diff --git a/app.vue b/app.vue
index b987c6b..f2f0d80 100644
--- a/app.vue
+++ b/app.vue
@@ -1,12 +1,7 @@
+
+
+
+ Archivieren
+
+
+
+
+ Archivieren bestätigen
+
+ Möchten Sie diese/-s/-n {{dataType.labelSingle}} wirklich archivieren?
+
+
+
+
+
+ Abbrechen
+
+
+ Archivieren
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/ButtonWithConfirm.vue b/components/ButtonWithConfirm.vue
index fe10c44..24da92c 100644
--- a/components/ButtonWithConfirm.vue
+++ b/components/ButtonWithConfirm.vue
@@ -41,7 +41,6 @@ const emitConfirm = () => {
@@ -50,8 +49,9 @@ const emitConfirm = () => {
- Bestätigen
+ Archivieren
diff --git a/components/DocumentDisplay.vue b/components/DocumentDisplay.vue
index 7e4715b..6db5d5a 100644
--- a/components/DocumentDisplay.vue
+++ b/components/DocumentDisplay.vue
@@ -3,7 +3,6 @@
import DocumentDisplayModal from "~/components/DocumentDisplayModal.vue";
const toast = useToast()
-const supabase = useSupabaseClient()
const dataStore = useDataStore()
const modal = useModal()
const profileStore = useProfileStore()
@@ -66,18 +65,18 @@ const showFile = (file) => {
diff --git a/components/ProfileDropdown.vue b/components/ProfileDropdown.vue
deleted file mode 100644
index a5c7281..0000000
--- a/components/ProfileDropdown.vue
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
- {{profileStore.tenants.find(i => profileStore.profiles.find(i => i.id === selectedProfile).tenant === i.id).name}}
-
-
-
- {{profileStore.tenants.find(i => i.id === option.tenant).name}}
-
-
-
\ No newline at end of file
diff --git a/components/StandardEntityModal.vue b/components/StandardEntityModal.vue
index f405e2f..98850ac 100644
--- a/components/StandardEntityModal.vue
+++ b/components/StandardEntityModal.vue
@@ -35,10 +35,10 @@ const item = ref({})
const setupPage = async () => {
if(props.mode === "show") {
//Load Data for Show
- item.value = await useSupabaseSelectSingle(props.type, props.id, dataType.supabaseSelectWithInformation || "*")
+ item.value = await useEntities(props.type).selectSingle(props.id, dataType.supabaseSelectWithInformation || "*")
} else if(props.mode === "edit") {
//Load Data for Edit
- const data = JSON.stringify((await supabase.from(props.type).select().eq("id", props.id).single()).data)
+ const data = JSON.stringify(await useEntities(props.type).selectSingle(props.id)/*(await supabase.from(props.type).select().eq("id", props.id).single()).data*/)
//await useSupabaseSelectSingle(type, route.params.id)
item.value = data
@@ -48,7 +48,7 @@ const setupPage = async () => {
} else if(props.mode === "list") {
//Load Data for List
- items.value = await useSupabaseSelect(props.type, dataType.supabaseSelectWithInformation || "*", dataType.supabaseSortColumn,dataType.supabaseSortAscending || false)
+ items.value = await useEntities(props.type).select(dataType.supabaseSelectWithInformation || "*", dataType.supabaseSortColumn,dataType.supabaseSortAscending || false)
}
loaded.value = true
diff --git a/components/TenantDropdown.vue b/components/TenantDropdown.vue
new file mode 100644
index 0000000..fa5eb6f
--- /dev/null
+++ b/components/TenantDropdown.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ {{auth.tenants.find(i => auth.activeTenant === i.id).name}}
+
+
+
+ {{option.name}}
+
+
+
\ No newline at end of file
diff --git a/components/UserDropdown.vue b/components/UserDropdown.vue
index b0b57f0..7d15569 100644
--- a/components/UserDropdown.vue
+++ b/components/UserDropdown.vue
@@ -1,4 +1,5 @@
- {{props.row.driver ? profileStore.getProfileById(props.row.driver).fullName : props.row.driver}}
+ {{props.row.driver ? "" : props.row.driver}}
diff --git a/components/costcentreDisplay.vue b/components/costcentreDisplay.vue
index 5d5215b..8b3a97b 100644
--- a/components/costcentreDisplay.vue
+++ b/components/costcentreDisplay.vue
@@ -13,7 +13,7 @@ const props = defineProps({
const incomingInvoices = ref({})
const setupPage = async () => {
- incomingInvoices.value = (await supabase.from("incominginvoices").select().eq("tenant", profileStore.currentTenant)).data.filter(i => i.accounts.find(x => x.costCentre === props.item.id))
+ incomingInvoices.value = (await useEntities("incominginvoices").select()).filter(i => i.accounts.find(x => x.costCentre === props.item.id))
}
setupPage()
diff --git a/components/displayBankaccounts.vue b/components/displayBankaccounts.vue
index 147bd71..cb4ac08 100644
--- a/components/displayBankaccounts.vue
+++ b/components/displayBankaccounts.vue
@@ -1,15 +1,14 @@
-
Willkommen zurück {{profileStore.activeProfile.fullName}}
- bei {{tenant.name}}
+ Willkommen zurück {{auth.profile.full_name}}
+ bei {{auth.activeTenantData.name}}
diff --git a/composables/useCapacitor.js b/composables/useCapacitor.js
index 26e7288..64ec2be 100644
--- a/composables/useCapacitor.js
+++ b/composables/useCapacitor.js
@@ -17,10 +17,14 @@ export const useCapacitor = () => {
return deviceInfo.model.toLowerCase().includes('iphone')
}
+ const getIsNative = () => {
+ return Capacitor.isNativePlatform()
+ }
+
const getNetworkStatus = async () => {
return await Network.getStatus()
}
- return {getPlatform, getDeviceInfo, getNetworkStatus, getIsPhone}
+ return {getPlatform, getDeviceInfo, getNetworkStatus, getIsPhone, getIsNative}
}
\ No newline at end of file
diff --git a/composables/useEntities.ts b/composables/useEntities.ts
new file mode 100644
index 0000000..9975b02
--- /dev/null
+++ b/composables/useEntities.ts
@@ -0,0 +1,143 @@
+
+import { useDataStore } from "~/stores/data"
+
+export const useEntities = (
+ relation: string,
+) => {
+
+ const dataStore = useDataStore()
+ const toast = useToast()
+ const router = useRouter()
+
+ const dataType = dataStore.dataTypes[relation]
+
+ const select = async (
+ select: string = "*",
+ sortColumn: string | null = null,
+ ascending: boolean = false,
+ noArchivedFiltering: boolean = false
+ ) => {
+
+ const res = await useNuxtApp().$api(`/api/resource/${relation}`, {
+ method: "GET",
+ params: {
+ select,
+ sort: sortColumn || undefined,
+ asc: ascending
+ }
+ })
+
+ let data = res || []
+
+ if (dataType && dataType.isArchivable && !noArchivedFiltering) {
+ data = data.filter((i: any) => !i.archived)
+ }
+
+ return data
+ }
+
+ const selectSpecial = async (
+ select: string = "*",
+ sortColumn: string | null = null,
+ ascending: boolean = false,
+ ) => {
+
+ const res = await useNuxtApp().$api(`/api/resource-special/${relation}`, {
+ method: "GET",
+ params: {
+ select,
+ sort: sortColumn || undefined,
+ asc: ascending
+ }
+ })
+
+ return res || []
+ }
+
+ const selectSingle = async (
+ idToEq: string | number,
+ select: string = "*",
+ withInformation: boolean = false
+ ) => {
+ if (!idToEq) return null
+
+ const res = await useNuxtApp().$api(withInformation ? `/api/resource/${relation}/${idToEq}/${withInformation}` : `/api/resource/${relation}/${idToEq}`, {
+ method: "GET",
+ params: { select }
+ })
+
+ return res
+ }
+
+ const create = async (
+ payload: Record
,
+ noRedirect: boolean = false
+ ) => {
+
+
+ const res = await useNuxtApp().$api(`/api/resource/${relation}`, {
+ method: "POST",
+ body: payload
+ })
+
+ toast.add({title: `${dataType.labelSingle} hinzugefügt`})
+ if(dataType.redirect && !noRedirect) {
+ if(dataType.isStandardEntity) {
+ await router.push(dataType.redirectToList ? `/standardEntity/${relation}` : `/standardEntity/${relation}/show/${res.id}`)
+ } else {
+ await router.push(dataType.redirectToList ? `/${relation}` : `/${relation}/show/${res.id}`)
+ }
+ }
+ //modal.close() TODO: Modal Close wenn in Modal
+
+
+ return res
+ }
+
+ const update = async (
+ id: string | number,
+ payload: Record,
+ noRedirect: boolean = false
+ ) => {
+ const res = await useNuxtApp().$api(`/api/resource/${relation}/${id}`, {
+ method: "PUT",
+ body: payload
+ })
+
+ toast.add({title: `${dataType.labelSingle} geändert`})
+ if(dataType.redirect && !noRedirect) {
+ if(dataType.isStandardEntity) {
+ await router.push(dataType.redirectToList ? `/standardEntity/${relation}` : `/standardEntity/${relation}/show/${res.id}`)
+ } else {
+ await router.push(dataType.redirectToList ? `/${relation}` : `/${relation}/show/${res.id}`)
+ }
+ }
+ //modal.close() TODO: Modal Close wenn in Modal
+
+
+ return res
+ }
+
+ /**
+ * Soft Delete = archived = true
+ */
+ const archive = async (
+ id: string | number
+ ) => {
+ const res = await useNuxtApp().$api(`/api/resource/${relation}/${id}`, {
+ method: "PUT",
+ body: { archived: true }
+ })
+ navigateTo(dataType.isStandardEntity ? `/standardEntity/${relation}` : `/${relation}`)
+
+ return res
+
+ }
+
+ return {select, create, update, archive, selectSingle, selectSpecial}
+}
+
+
+
+
+
diff --git a/composables/useError.js b/composables/useErrorLogging.js
similarity index 92%
rename from composables/useError.js
rename to composables/useErrorLogging.js
index 1c2e742..298ccd0 100644
--- a/composables/useError.js
+++ b/composables/useErrorLogging.js
@@ -1,5 +1,5 @@
-export const useError = (resourceType) => {
+export const useErrorLogging = (resourceType) => {
const supabase = useSupabaseClient()
const toast = useToast()
const profileStore = useProfileStore()
diff --git a/composables/useFiles.js b/composables/useFiles.js
deleted file mode 100644
index 52c4875..0000000
--- a/composables/useFiles.js
+++ /dev/null
@@ -1,211 +0,0 @@
-
-export const useFiles = () => {
- const supabase = useSupabaseClient()
- const toast = useToast()
-
- let bucket = "filesdev"
-
- const profileStore = useProfileStore()
-
- const uploadFiles = async (formData, files,tags, upsert) => {
- const uploadSingleFile = async (file) => {
- //Create File Entry to Get ID for Folder
- const {data:createdFileData,error:createdFileError} = await supabase
- .from("files")
- .insert({
- tenant: profileStore.currentTenant,
- })
- .select()
- .single()
-
- if(createdFileError){
- console.log(createdFileError)
- toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
- } else if(createdFileData) {
- //Upload File to ID Folder
- const {data:uploadData, error: uploadError} = await supabase
- .storage
- .from(bucket)
- .upload(`${profileStore.currentTenant}/filesbyid/${createdFileData.id}/${file.name}`, file, {upsert: upsert})
-
- if(uploadError) {
- console.log(uploadError)
- console.log(uploadError.statusCode)
-
- if(uploadError.statusCode === '400') {
- console.log("is 400")
- toast.add({title: "Hochladen fehlgeschlagen", description: "Die Datei enthält ungültige Zeichen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
- } else if(uploadError.statusCode === '409') {
- console.log("is 409")
- toast.add({title: "Hochladen fehlgeschlagen", description: "Es existiert bereits eine Datei mit diesem Namen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
- } else {
- toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
-
- }
- } else if(uploadData) {
- //Update File with Corresponding Path
- const {data:updateFileData, error:updateFileError} = await supabase
- .from("files")
- .update({
- ...formData,
- path: uploadData.path,
- })
- .eq("id", createdFileData.id)
-
- if(updateFileError) {
- console.log(updateFileError)
- toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
- } else {
- const {data:tagData, error:tagError} = await supabase
- .from("filetagmembers")
- .insert(tags.map(tag => {
- return {
- file_id: createdFileData.id,
- tag_id: tag
- }
- }))
-
-
-
- toast.add({title: "Hochladen erfolgreich"})
-
- }
- }
- }
- }
-
- if(files.length === 1) {
- await uploadSingleFile(files[0])
- } else if( files.length > 1) {
-
- for(let i = 0; i < files.length; i++){
- await uploadSingleFile(files[i])
- }
-
- }
- }
-
- const selectDocuments = async (sortColumn = null, folder = null) => {
- let data = []
-
- if(sortColumn !== null ) {
- data = (await supabase
- .from("files")
- .select('*, incominginvoice(*), project(*), vendor(*), customer(*), contract(*), plant(*), createddocument(*), vehicle(*), product(*), profile(*), check(*), inventoryitem(*)')
- .eq("tenant", profileStore.currentTenant)
- .not("path","is",null)
- .not("archived","is",true)
- .order(sortColumn, {ascending: true})).data
- } else {
- data = (await supabase
- .from("files")
- .select('*, incominginvoice(*), project(*), vendor(*), customer(*), contract(*), plant(*), createddocument(*), vehicle(*), product(*), profile(*), check(*), inventoryitem(*)')
- .eq("tenant", profileStore.currentTenant)
- .not("path","is",null)
- .not("archived","is",true)).data
-
- }
-
- if(data.length > 0){
- let paths = []
- data.forEach(doc => {
- paths.push(doc.path)
- })
-
- const {data: supabaseData,error} = await supabase.storage.from(bucket).createSignedUrls(paths,3600)
-
- data = data.map((doc,index) => {
-
- return {
- ...doc,
- url: supabaseData[index].signedUrl
- }
- })
- }
-
- return data
- }
-
- const selectSomeDocuments = async (documentIds, sortColumn = null, folder = null) => {
- let data = null
-
- if(sortColumn !== null ) {
- data = (await supabase
- .from("files")
- .select('*, incominginvoice(*), project(*), vendor(*), customer(*), contract(*), plant(*), createddocument(*), vehicle(*), product(*), profile(*), check(*), inventoryitem(*)')
- .in("id",documentIds)
- .eq("tenant", profileStore.currentTenant)
- .not("path","is",null)
- .not("archived","is",true)
- .order(sortColumn, {ascending: true})).data
- } else {
- data = (await supabase
- .from("files")
- .select('*, incominginvoice(*), project(*), vendor(*), customer(*), contract(*), plant(*), createddocument(*, customer(*), contact(*)), vehicle(*), product(*), profile(*), check(*), inventoryitem(*)')
- .in("id",documentIds)
- .not("path","is",null)
- .not("archived","is",true)
- .eq("tenant", profileStore.currentTenant)).data
-
- }
-
- if(data.length > 0){
- let paths = []
- data.forEach(doc => {
- paths.push(doc.path)
- })
-
- const {data: supabaseData,error} = await supabase.storage.from(bucket).createSignedUrls(paths,3600)
-
- data = data.map((doc,index) => {
-
- return {
- ...doc,
- url: supabaseData[index].signedUrl
- }
- })
- }
-
- //console.log(data)
-
- return data
- }
-
- const selectDocument = async (id) => {
- const {data,error} = await supabase
- .from("files")
- .select('*')
- .eq("id",id)
- .single()
-
- const {data: supabaseData,error:supabaseError} = await supabase.storage.from(bucket).createSignedUrl(data.path,3600)
-
- return {
- ...data,
- url: supabaseData.signedUrl
- }
-/*
- if(data.length > 0){
- let paths = []
- data.forEach(doc => {
- paths.push(doc.path)
- })
-
- const {data: supabaseData,error} = await supabase.storage.from(bucket).createSignedUrls(paths,3600)
-
- data = data.map((doc,index) => {
-
- return {
- ...doc,
- url: supabaseData[index].signedUrl
- }
- })
- }
-
- //console.log(data)
-
- return data[0]*/
- }
-
- return {uploadFiles, selectDocuments, selectSomeDocuments, selectDocument}
-}
\ No newline at end of file
diff --git a/composables/useFiles.ts b/composables/useFiles.ts
new file mode 100644
index 0000000..657824d
--- /dev/null
+++ b/composables/useFiles.ts
@@ -0,0 +1,129 @@
+
+export const useFiles = () => {
+ const supabase = useSupabaseClient()
+ const toast = useToast()
+
+ const auth = useAuthStore()
+
+ let bucket = "filesdev"
+
+ const uploadFiles = async (fileData, files,tags, upsert) => {
+ const uploadSingleFile = async (file) => {
+ //Create File Entry to Get ID for Folder
+
+ const formData = new FormData()
+
+ formData.append("file", file)
+ formData.append("meta", JSON.stringify(fileData))
+
+ const {fileReturn} = await useNuxtApp().$api("/api/files/upload",{
+ method: "POST",
+ body: formData
+ })
+ }
+
+ if(files.length === 1) {
+ await uploadSingleFile(files[0])
+ } else if( files.length > 1) {
+
+ for(let i = 0; i < files.length; i++){
+ await uploadSingleFile(files[i])
+ }
+
+ }
+ }
+
+ const selectDocuments = async (sortColumn = null, folder = null) => {
+ let data = []
+ data = await useEntities("files").select("*, incominginvoice(*), project(*), vendor(*), customer(*), contract(*), plant(*), createddocument(*), vehicle(*), product(*), profile(*), check(*), inventoryitem(*)")
+
+
+
+ const res = await useNuxtApp().$api("/api/files/presigned",{
+ method: "POST",
+ body: {
+ ids: data.map(i => i.id)
+ }
+ })
+
+ console.log(res)
+
+ return res.files
+ }
+
+ const selectSomeDocuments = async (documentIds, sortColumn = null, folder = null) => {
+
+ if(documentIds.length === 0) return []
+ const res = await useNuxtApp().$api("/api/files/presigned",{
+ method: "POST",
+ body: {
+ ids: documentIds
+ }
+ })
+
+ console.log(res)
+
+ return res.files
+
+
+ }
+
+ const selectDocument = async (id) => {
+ let documentIds = [id]
+ if(documentIds.length === 0) return []
+ const res = await useNuxtApp().$api("/api/files/presigned",{
+ method: "POST",
+ body: {
+ ids: documentIds
+ }
+ })
+
+ console.log(res)
+
+ return res.files[0]
+ }
+
+ const downloadFile = async (id?: string, ids?: string[], returnAsBlob: Boolean = false) => {
+ const url = id ? `/api/files/download/${id}` : `/api/files/download`
+ const body = ids ? { ids } : undefined
+
+ const res:any = await useNuxtApp().$api.raw(url, {
+ method: "POST",
+ body,
+ responseType: "blob", // wichtig!
+ })
+
+ // Dateiname bestimmen
+ let filename = "download"
+
+ if (id) {
+ // Einzeldatei → nimm den letzten Teil des Pfads aus Content-Disposition
+ const contentDisposition = res.headers?.get("content-disposition")
+ if (contentDisposition) {
+ const match = contentDisposition.match(/filename="?([^"]+)"?/)
+ if (match) filename = match[1]
+ }
+ } else {
+ filename = "dateien.zip"
+ }
+
+ // Direkt speichern
+ const blob = res._data as Blob
+
+ if(returnAsBlob) {
+ return blob
+ } else {
+ const link = document.createElement("a")
+ link.href = URL.createObjectURL(blob)
+ link.download = filename
+ link.click()
+ URL.revokeObjectURL(link.href)
+ }
+
+
+
+ }
+
+
+ return {uploadFiles, selectDocuments, selectSomeDocuments, selectDocument, downloadFile}
+}
\ No newline at end of file
diff --git a/composables/useFunctions.js b/composables/useFunctions.js
index 44d27ee..42e7506 100644
--- a/composables/useFunctions.js
+++ b/composables/useFunctions.js
@@ -24,7 +24,7 @@ export const useFunctions = () => {
}
const useNextNumber = async (numberRange) => {
- const {data:{session:{access_token}}} = await supabase.auth.getSession()
+ /*const {data:{session:{access_token}}} = await supabase.auth.getSession()
return (await axios({
method: "POST",
@@ -35,7 +35,11 @@ export const useFunctions = () => {
headers: {
Authorization: `Bearer ${access_token}`
}
- })).data.usedNumber
+ })).data.usedNumber*/
+
+ return (await useNuxtApp().$api(`/api/functions/usenextnumber/${numberRange}`,)).usedNumber
+
+
}
const useCreateTicket = async (subject,message,url,source) => {
@@ -80,9 +84,17 @@ export const useFunctions = () => {
}
const useCreatePDF = async (invoiceData,path) => {
- const {data:{session:{access_token}}} = await supabase.auth.getSession()
+ //const {data:{session:{access_token}}} = await supabase.auth.getSession()
- const {data} = await axios({
+ const data = await useNuxtApp().$api(`/api/functions/createinvoicepdf`, {
+ method: "POST",
+ body: {
+ invoiceData: invoiceData,
+ backgroundPath: path,
+ }
+ })
+
+ /*const {data} = await axios({
method: "POST",
url: `${baseURL}/functions/createpdf`,
data: {
@@ -93,7 +105,7 @@ export const useFunctions = () => {
headers: {
Authorization: `Bearer ${access_token}`
}
- })
+ })*/
console.log(data)
diff --git a/composables/usePermission.ts b/composables/usePermission.ts
new file mode 100644
index 0000000..54376e7
--- /dev/null
+++ b/composables/usePermission.ts
@@ -0,0 +1,9 @@
+export function usePermission() {
+ const auth = useAuthStore()
+
+ const has = (key: string) => {
+ return auth.hasPermission(key)
+ }
+
+ return { has }
+}
diff --git a/composables/useSum.js b/composables/useSum.js
index 752a9d4..4c11915 100644
--- a/composables/useSum.js
+++ b/composables/useSum.js
@@ -6,7 +6,6 @@ export const useSum = () => {
const getIncomingInvoiceSum = (invoice) => {
let sum = 0
invoice.accounts.forEach(account => {
- console.log(account)
sum += account.amountTax
@@ -23,21 +22,9 @@ export const useSum = () => {
let total19 = 0
let total7 = 0
- /*let usedadvanceinvoices = []
- if(createddocument.usedAdvanceInvoices.length > 0) {
- console.log(createddocument)
- console.log(createddocument.usedAdvanceInvoices)
- console.log((await supabase.from("createddocuments").select().in("id", createddocument.usedAdvanceInvoices)))
-
- usedadvanceinvoices = (await supabase.from("createddocuments").select().in("id", createddocument.usedAdvanceInvoices)).data
- console.log(usedadvanceinvoices)
-
- }*/
-
-
createddocument.rows.forEach(row => {
if(!['pagebreak','title','text'].includes(row.mode)){
let rowPrice = Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(3)
diff --git a/composables/useSupabase.js b/composables/useSupabase.js
deleted file mode 100644
index 4618aa1..0000000
--- a/composables/useSupabase.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import {useDataStore} from "~/stores/data.js";
-
-
-export const useSupabaseSelect = async (relation,select = '*', sortColumn = null, ascending = true,noArchivedFiltering = false) => {
- const supabase = useSupabaseClient()
- const profileStore = useProfileStore()
- let data = null
- const dataStore = useDataStore()
-
- const dataType = dataStore.dataTypes[relation]
-
- if(sortColumn !== null ) {
- data = (await supabase
- .from(relation)
- .select(select)
- .eq("tenant", profileStore.currentTenant)
- .order(sortColumn, {ascending: ascending})).data
- } else {
- data = (await supabase
- .from(relation)
- .select(select)
- .eq("tenant", profileStore.currentTenant)).data
- }
-
- if(dataType && dataType.isArchivable && !noArchivedFiltering) {
- data = data.filter(i => !i.archived)
- }
-
- return data
-}
-
-export const useSupabaseSelectSingle = async (relation,idToEq,select = '*' ) => {
- const supabase = useSupabaseClient()
- const profileStore = useProfileStore()
- let data = null
-
-
- if(idToEq !== null) {
- data = (await supabase
- .from(relation)
- .select(select)
- .eq("tenant", profileStore.currentTenant)
- .eq("id",idToEq)
- .single()).data
- } else {
- data = (await supabase
- .from(relation)
- .select(select)
- .eq("tenant", profileStore.currentTenant)
- .single()).data
- }
-
- return data
-}
\ No newline at end of file
diff --git a/composables/useUsers.ts b/composables/useUsers.ts
new file mode 100644
index 0000000..ba68874
--- /dev/null
+++ b/composables/useUsers.ts
@@ -0,0 +1,28 @@
+
+import { useDataStore } from "~/stores/data"
+
+export const useUsers = (
+ id: string | number,
+) => {
+
+ const dataStore = useDataStore()
+ const toast = useToast()
+ const router = useRouter()
+
+ const getProfile = async () => {
+
+
+ const res = await useNuxtApp().$api(`/api/profiles/${id}`, {
+ method: "GET"
+ })
+
+ return res
+ }
+
+ return {getProfile}
+}
+
+
+
+
+
diff --git a/docker-compose.yml b/docker-compose.yml
index 00ef6c5..55aab3b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,9 +7,8 @@ services:
# networks:
# - traefik
environment:
- SUPABASE_URL: "https://uwppvcxflrcsibuzsbil.supabase.co"
- SUPABASE_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo"
-# labels:
+ NUXT_PUBLIC_API_BASE: "https://backend.fedeo.io"
+ # labels:
# - "traefik.enable=true"
# - "traefik.docker.network=traefik"
# - "traefik.port=3000"
diff --git a/error.vue b/error.vue
index fbeac53..814280f 100644
--- a/error.vue
+++ b/error.vue
@@ -7,11 +7,29 @@ const props = defineProps({
-
-
-
Da ist etwas schief gelaufen
- Zurück
-
+
+
+
+ Es gab ein Problem - {{error.statusCode}}
+
+
+
+
-
+
+ Zurück zur Startseite
+
+
\ No newline at end of file
diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj
index 529ce3c..31a573e 100644
--- a/ios/App/App.xcodeproj/project.pbxproj
+++ b/ios/App/App.xcodeproj/project.pbxproj
@@ -485,7 +485,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 2;
+ CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GMCGQ8KK2P;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
@@ -493,7 +493,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.8;
+ MARKETING_VERSION = 2.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -510,7 +510,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 2;
+ CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GMCGQ8KK2P;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
@@ -518,7 +518,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.8;
+ MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
diff --git a/ios/App/Podfile b/ios/App/Podfile
index 05c9cc3..6006b02 100644
--- a/ios/App/Podfile
+++ b/ios/App/Podfile
@@ -13,6 +13,7 @@ def capacitor_pods
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device'
pod 'CapacitorNetwork', :path => '../../node_modules/@capacitor/network'
+ pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
pod 'CapacitorPluginSafeArea', :path => '../../node_modules/capacitor-plugin-safe-area'
pod 'CordovaPluginsStatic', :path => '../capacitor-cordova-ios-plugins'
end
diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock
index 5510ba5..3d267bf 100644
--- a/ios/App/Podfile.lock
+++ b/ios/App/Podfile.lock
@@ -8,6 +8,8 @@ PODS:
- Capacitor
- CapacitorPluginSafeArea (4.0.0):
- Capacitor
+ - CapacitorPreferences (6.0.3):
+ - Capacitor
- CordovaPluginsStatic (7.1.0):
- CapacitorCordova
- OneSignalXCFramework (= 5.2.10)
@@ -64,6 +66,7 @@ DEPENDENCIES:
- "CapacitorDevice (from `../../node_modules/@capacitor/device`)"
- "CapacitorNetwork (from `../../node_modules/@capacitor/network`)"
- CapacitorPluginSafeArea (from `../../node_modules/capacitor-plugin-safe-area`)
+ - "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)"
- CordovaPluginsStatic (from `../capacitor-cordova-ios-plugins`)
- OneSignalXCFramework (< 6.0, >= 5.0)
@@ -82,6 +85,8 @@ EXTERNAL SOURCES:
:path: "../../node_modules/@capacitor/network"
CapacitorPluginSafeArea:
:path: "../../node_modules/capacitor-plugin-safe-area"
+ CapacitorPreferences:
+ :path: "../../node_modules/@capacitor/preferences"
CordovaPluginsStatic:
:path: "../capacitor-cordova-ios-plugins"
@@ -91,9 +96,10 @@ SPEC CHECKSUMS:
CapacitorDevice: 069faf433b3a99c3d5f0e500fbe634f60a8c6a84
CapacitorNetwork: 30c2e78a0ed32530656cb426c8ee6c2caec10dbf
CapacitorPluginSafeArea: 22031c3436269ca80fac90ec2c94bc7c1e59a81d
+ CapacitorPreferences: f3eadae2369ac3ab8e21743a2959145b0d1286a3
CordovaPluginsStatic: f722d4ff434f50099581e690d579b7c108f490e6
OneSignalXCFramework: 1a3b28dfbff23aabce585796d23c1bef37772774
-PODFILE CHECKSUM: ccfbce7f13cfefd953204fe26b280d6431731aa5
+PODFILE CHECKSUM: d76fcd3d35c3f8c3708303de70ef45a76cc6e2b5
COCOAPODS: 1.16.2
diff --git a/layouts/default.vue b/layouts/default.vue
index ecbbae7..e994ab7 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -3,19 +3,18 @@
import MainNav from "~/components/MainNav.vue";
import dayjs from "dayjs";
-import {useProfileStore} from "~/stores/profile.js";
import {useCapacitor} from "../composables/useCapacitor.js";
import GlobalMessages from "~/components/GlobalMessages.vue";
+import TenantDropdown from "~/components/TenantDropdown.vue";
const dataStore = useDataStore()
-const profileStore = useProfileStore()
const colorMode = useColorMode()
const { isHelpSlideoverOpen } = useDashboard()
-const supabase = useSupabaseClient()
const router = useRouter()
const route = useRoute()
-profileStore.initializeData((await supabase.auth.getUser()).data.user.id)
+const auth = useAuthStore()
+
const month = dayjs().format("MM")
@@ -65,8 +64,8 @@ const actions = [
]
-const groups = computed(() =>
- [{
+const groups = computed(() => [
+ {
key: 'actions',
commands: actions
},{
@@ -99,7 +98,8 @@ const groups = computed(() =>
commands: dataStore.projects.map(item => { return {id: item.id, label: item.name, to: `/projects/show/${item.id}`}})
}
].filter(Boolean))
-const footerLinks = [/*{
+const footerLinks = [
+ /*{
label: 'Invite people',
icon: 'i-heroicons-plus',
to: '/settings/members'
@@ -112,56 +112,163 @@ const footerLinks = [/*{
-
-
-
-
-
-
-
-
-
-