Merge pull request 'dev' (#40) from dev into main
Reviewed-on: #40
@@ -1,10 +1,13 @@
|
|||||||
import { drizzle } from "drizzle-orm/node-postgres"
|
import { drizzle } from "drizzle-orm/node-postgres"
|
||||||
import { Pool } from "pg"
|
import { Pool } from "pg"
|
||||||
import {secrets} from "../src/utils/secrets";
|
import {secrets} from "../src/utils/secrets";
|
||||||
|
import * as schema from "./schema"
|
||||||
|
|
||||||
const pool = new Pool({
|
|
||||||
|
|
||||||
|
export const pool = new Pool({
|
||||||
connectionString: secrets.DATABASE_URL,
|
connectionString: secrets.DATABASE_URL,
|
||||||
max: 10, // je nach Last
|
max: 10, // je nach Last
|
||||||
})
|
})
|
||||||
|
|
||||||
export const db = drizzle(pool)
|
export const db = drizzle(pool , {schema})
|
||||||
@@ -6,6 +6,6 @@ export default defineConfig({
|
|||||||
schema: "./db/schema",
|
schema: "./db/schema",
|
||||||
out: "./db/migrations",
|
out: "./db/migrations",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: secrets.DATABASE_URL || process.env.DATABASE_URL,
|
url: secrets.DATABASE_URL,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -146,6 +146,7 @@ async function main() {
|
|||||||
|
|
||||||
app.ready(async () => {
|
app.ready(async () => {
|
||||||
try {
|
try {
|
||||||
|
console.log("Testing DB Connection:")
|
||||||
const result = await app.db.execute("SELECT NOW()");
|
const result = await app.db.execute("SELECT NOW()");
|
||||||
console.log("✓ DB connection OK: " + JSON.stringify(result.rows[0]));
|
console.log("✓ DB connection OK: " + JSON.stringify(result.rows[0]));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default fp(async (server: FastifyInstance) => {
|
|||||||
"http://localhost:3001", // dein Nuxt-Frontend
|
"http://localhost:3001", // dein Nuxt-Frontend
|
||||||
"http://127.0.0.1:3000", // dein Nuxt-Frontend
|
"http://127.0.0.1:3000", // dein Nuxt-Frontend
|
||||||
"http://192.168.1.227:3001", // dein Nuxt-Frontend
|
"http://192.168.1.227:3001", // dein Nuxt-Frontend
|
||||||
"http://192.168.1.227:3000", // dein Nuxt-Frontend
|
"http://192.168.1.113:3000", // dein Nuxt-Frontend
|
||||||
"https://beta.fedeo.de", // dein Nuxt-Frontend
|
"https://beta.fedeo.de", // dein Nuxt-Frontend
|
||||||
"https://app.fedeo.de", // dein Nuxt-Frontend
|
"https://app.fedeo.de", // dein Nuxt-Frontend
|
||||||
"capacitor://localhost", // dein Nuxt-Frontend
|
"capacitor://localhost", // dein Nuxt-Frontend
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
import fp from "fastify-plugin"
|
import fp from "fastify-plugin"
|
||||||
import {drizzle, NodePgDatabase} from "drizzle-orm/node-postgres"
|
import {drizzle, NodePgDatabase} from "drizzle-orm/node-postgres"
|
||||||
import { Pool } from "pg"
|
|
||||||
import * as schema from "../../db/schema"
|
import * as schema from "../../db/schema"
|
||||||
|
import {secrets} from "../utils/secrets";
|
||||||
|
import { Pool } from "pg"
|
||||||
|
|
||||||
export default fp(async (server, opts) => {
|
export default fp(async (server, opts) => {
|
||||||
|
|
||||||
const pool = new Pool({
|
const pool = new Pool({
|
||||||
host: "100.102.185.225",
|
connectionString: secrets.DATABASE_URL,
|
||||||
port: Number(process.env.DB_PORT || 5432),
|
max: 10, // je nach Last
|
||||||
user: "postgres",
|
|
||||||
password: "wJw7aNpEBJdcxgoct6GXNpvY4Cn6ECqu",
|
|
||||||
database: "fedeo",
|
|
||||||
ssl: process.env.DB_DISABLE_SSL === "true" ? false : undefined,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Drizzle instance
|
const db = drizzle(pool , {schema})
|
||||||
const db = drizzle(pool, { schema })
|
|
||||||
|
|
||||||
// Dekorieren -> überall server.db
|
// Dekorieren -> überall server.db
|
||||||
server.decorate("db", db)
|
server.decorate("db", db)
|
||||||
@@ -24,7 +21,7 @@ export default fp(async (server, opts) => {
|
|||||||
await pool.end()
|
await pool.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
server.log.info("Drizzle database connected")
|
console.log("Drizzle database connected")
|
||||||
})
|
})
|
||||||
|
|
||||||
declare module "fastify" {
|
declare module "fastify" {
|
||||||
|
|||||||
@@ -62,17 +62,17 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
|||||||
// 🆕 POST /staff/time/edit (Bearbeiten durch Invalidieren + Neu erstellen)
|
// 🆕 POST /staff/time/edit (Bearbeiten durch Invalidieren + Neu erstellen)
|
||||||
server.post("/staff/time/edit", async (req, reply) => {
|
server.post("/staff/time/edit", async (req, reply) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.user_id;
|
// 1. Der "Actor" ist der, der gerade eingeloggt ist (z.B. Manager)
|
||||||
|
const actorId = req.user.user_id;
|
||||||
const tenantId = req.user.tenant_id;
|
const tenantId = req.user.tenant_id;
|
||||||
|
|
||||||
// Wir erwarten das komplette Paket für die Änderung
|
|
||||||
const {
|
const {
|
||||||
originalEventIds, // Array der IDs, die "gelöscht" werden sollen (Start ID, End ID)
|
originalEventIds,
|
||||||
newStart, // ISO String
|
newStart,
|
||||||
newEnd, // ISO String
|
newEnd,
|
||||||
newType, // z.B. 'work', 'vacation'
|
newType,
|
||||||
description,
|
description,
|
||||||
reason // Warum wurde geändert? (Audit)
|
reason
|
||||||
} = req.body as {
|
} = req.body as {
|
||||||
originalEventIds: string[],
|
originalEventIds: string[],
|
||||||
newStart: string,
|
newStart: string,
|
||||||
@@ -86,41 +86,66 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
|||||||
return reply.code(400).send({ error: "Keine Events zum Bearbeiten angegeben." });
|
return reply.code(400).send({ error: "Keine Events zum Bearbeiten angegeben." });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Transaction starten (damit alles oder nichts passiert)
|
// -----------------------------------------------------------
|
||||||
|
// SCHRITT A: Den eigentlichen Besitzer (Mitarbeiter) ermitteln
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
// Wir holen uns das erste Event aus der Liste, um zu sehen, wem es gehört.
|
||||||
|
const existingEvents = await server.db
|
||||||
|
.select({
|
||||||
|
user_id: stafftimeevents.user_id,
|
||||||
|
tenant_id: stafftimeevents.tenant_id
|
||||||
|
})
|
||||||
|
.from(stafftimeevents)
|
||||||
|
.where(and(
|
||||||
|
eq(stafftimeevents.id, originalEventIds[0]),
|
||||||
|
eq(stafftimeevents.tenant_id, tenantId) // Sicherheitscheck: Nur im eigenen Tenant
|
||||||
|
))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existingEvents.length === 0) {
|
||||||
|
return reply.code(404).send({ error: "Ursprüngliches Event nicht gefunden oder Zugriff verweigert." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Das ist der Mitarbeiter, dem die Zeit gehört
|
||||||
|
const targetUserId = existingEvents[0].user_id;
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
// SCHRITT B: Transaktion durchführen
|
||||||
|
// -----------------------------------------------------------
|
||||||
await server.db.transaction(async (tx) => {
|
await server.db.transaction(async (tx) => {
|
||||||
|
|
||||||
// A. INVALIDIEREN (Die alten Events "löschen")
|
// 1. INVALIDIEREN
|
||||||
// Wir erstellen für jedes alte Event ein 'invalidated' Event
|
// Wir nutzen 'targetUserId' als Besitzer des Events, aber 'actorId' als Auslöser
|
||||||
const invalidations = originalEventIds.map(id => ({
|
const invalidations = originalEventIds.map(id => ({
|
||||||
tenant_id: tenantId,
|
tenant_id: tenantId,
|
||||||
user_id: userId, // Gehört dem Mitarbeiter
|
user_id: targetUserId, // <--- WICHTIG: Gehört dem Mitarbeiter
|
||||||
actortype: "user",
|
actortype: "user",
|
||||||
actoruser_id: userId, // Wer hat geändert?
|
actoruser_id: actorId, // <--- WICHTIG: Geändert durch Manager/Self
|
||||||
eventtime: new Date(),
|
eventtime: new Date(),
|
||||||
eventtype: "invalidated", // <--- NEUER TYP: Muss in loadValidEvents gefiltert werden!
|
eventtype: "invalidated",
|
||||||
source: "WEB",
|
source: "WEB",
|
||||||
related_event_id: id, // Zeigt auf das alte Event
|
related_event_id: id,
|
||||||
metadata: {
|
metadata: {
|
||||||
reason: reason || "Bearbeitung",
|
reason: reason || "Bearbeitung",
|
||||||
replaced_by_edit: true
|
replaced_by_edit: true
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Batch Insert
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await tx.insert(stafftimeevents).values(invalidations);
|
await tx.insert(stafftimeevents).values(invalidations);
|
||||||
|
|
||||||
// B. NEU ERSTELLEN (Die korrigierten Events anlegen)
|
// 2. NEU ERSTELLEN
|
||||||
|
|
||||||
// Start Event
|
// Start Event
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await tx.insert(stafftimeevents).values({
|
await tx.insert(stafftimeevents).values({
|
||||||
tenant_id: tenantId,
|
tenant_id: tenantId,
|
||||||
user_id: userId,
|
user_id: targetUserId, // <--- Gehört dem Mitarbeiter
|
||||||
actortype: "user",
|
actortype: "user",
|
||||||
actoruser_id: userId,
|
actoruser_id: actorId, // <--- Erstellt durch Manager/Self
|
||||||
eventtime: new Date(newStart),
|
eventtime: new Date(newStart),
|
||||||
eventtype: `${newType}_start`, // z.B. work_start
|
eventtype: `${newType}_start`,
|
||||||
source: "WEB",
|
source: "WEB",
|
||||||
payload: { description: description || "" }
|
payload: { description: description || "" }
|
||||||
});
|
});
|
||||||
@@ -130,11 +155,11 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await tx.insert(stafftimeevents).values({
|
await tx.insert(stafftimeevents).values({
|
||||||
tenant_id: tenantId,
|
tenant_id: tenantId,
|
||||||
user_id: userId,
|
user_id: targetUserId, // <--- Gehört dem Mitarbeiter
|
||||||
actortype: "user",
|
actortype: "user",
|
||||||
actoruser_id: userId,
|
actoruser_id: actorId, // <--- Erstellt durch Manager/Self
|
||||||
eventtime: new Date(newEnd),
|
eventtime: new Date(newEnd),
|
||||||
eventtype: `${newType}_end`, // z.B. work_end
|
eventtype: `${newType}_end`,
|
||||||
source: "WEB"
|
source: "WEB"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,58 @@ services:
|
|||||||
web:
|
web:
|
||||||
image: reg.federspiel.software/fedeo/software:beta
|
image: reg.federspiel.software/fedeo/software:beta
|
||||||
restart: always
|
restart: always
|
||||||
|
environment:
|
||||||
|
- INFISICAL_CLIENT_ID=abc
|
||||||
|
- INFISICAL_CLIENT_SECRET=abc
|
||||||
backend:
|
backend:
|
||||||
image: reg.federspiel.software/fedeo/backend:main
|
image: reg.federspiel.software/fedeo/backend:main
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
- NUXT_PUBLIC_API_BASE=
|
||||||
|
- NUXT_PUBLIC_PDF_LICENSE=
|
||||||
|
db:
|
||||||
|
image: postgres
|
||||||
|
restart: always
|
||||||
|
shm_size: 128mb
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: abc
|
||||||
|
POSTGRES_USER: sandelcom
|
||||||
|
POSTGRES_DB: sensorfy
|
||||||
|
volumes:
|
||||||
|
- ./pg-data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
traefik:
|
||||||
|
image: traefik:v2.2
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: traefik
|
||||||
|
command:
|
||||||
|
- "--api.insecure=false"
|
||||||
|
- "--api.dashboard=true"
|
||||||
|
- "--api.debug=false"
|
||||||
|
- "--providers.docker=true"
|
||||||
|
- "--providers.docker.exposedbydefault=false"
|
||||||
|
- "--providers.docker.network=traefik"
|
||||||
|
- "--entrypoints.web.address=:80"
|
||||||
|
- "--entrypoints.web-secured.address=:443"
|
||||||
|
- "--accesslog=true"
|
||||||
|
- "--accesslog.filepath=/logs/access.log"
|
||||||
|
- "--accesslog.bufferingsize=5000"
|
||||||
|
- "--accesslog.fields.defaultMode=keep"
|
||||||
|
- "--accesslog.fields.headers.defaultMode=keep"
|
||||||
|
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true" # <== Enable TLS-ALPN-01 to generate and renew ACME certs
|
||||||
|
- "--certificatesresolvers.mytlschallenge.acme.email=info@sandelcom.de" # <== Setting email for certs
|
||||||
|
- "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" # <== Defining acme file to store cert information
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 8080:8080
|
||||||
|
- 443:443
|
||||||
|
volumes:
|
||||||
|
- "./traefik/letsencrypt:/letsencrypt" # <== Volume for certs (TLS)
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
- "./traefik/logs:/logs"
|
||||||
|
labels:
|
||||||
|
#### Labels define the behavior and rules of the traefik proxy for this container ####
|
||||||
|
- "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to view it
|
||||||
|
- "traefik.http.routers.api.rule=Host(`srv1.drinkingteam.de`)" # <== Setting the domain for the dashboard
|
||||||
|
- "traefik.http.routers.api.service=api@internal" # <== Enabling the api to be a service to access
|
||||||
|
|||||||
@@ -3,17 +3,7 @@ import * as Sentry from "@sentry/browser"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
|
|
||||||
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
|
|
||||||
})*/
|
|
||||||
|
|
||||||
const platform = ref('default')
|
|
||||||
|
|
||||||
const setup = async () => {
|
const setup = async () => {
|
||||||
if(await useCapacitor().getIsPhone()) {
|
|
||||||
platform.value = "mobile"
|
|
||||||
}
|
|
||||||
|
|
||||||
const dev = process.dev
|
const dev = process.dev
|
||||||
console.log(dev)
|
console.log(dev)
|
||||||
}
|
}
|
||||||
@@ -21,10 +11,10 @@ setup()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Sentry.init({
|
/*Sentry.init({
|
||||||
dsn: "https://62e62ff08e1a438591fe5eb4dd9de244@glitchtip.federspiel.software/3",
|
dsn: "https://62e62ff08e1a438591fe5eb4dd9de244@glitchtip.federspiel.software/3",
|
||||||
tracesSampleRate: 0.01,
|
tracesSampleRate: 0.01,
|
||||||
});
|
});*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -40,12 +30,12 @@ useHead({
|
|||||||
lang: 'de'
|
lang: 'de'
|
||||||
},
|
},
|
||||||
script: [
|
script: [
|
||||||
{
|
/*{
|
||||||
defer: true,
|
defer: true,
|
||||||
src: "/umami.js",
|
src: "/umami.js",
|
||||||
"data-website-id":"2a9782fa-2fdf-4434-981d-93592d39edef",
|
"data-website-id":"2a9782fa-2fdf-4434-981d-93592d39edef",
|
||||||
"data-host-url":"https://umami.federspiel.software"
|
"data-host-url":"https://umami.federspiel.software"
|
||||||
}
|
}*/
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -61,8 +51,7 @@ useSeoMeta({
|
|||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage/>
|
<NuxtPage/>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
<UNotifications/>
|
||||||
<UNotifications :class="platform === 'mobile' ? ['mb-14'] : []"/>
|
|
||||||
<USlideovers />
|
<USlideovers />
|
||||||
<UModals/>
|
<UModals/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import type { CapacitorConfig } from '@capacitor/cli';
|
|
||||||
|
|
||||||
const config: CapacitorConfig = {
|
|
||||||
appId: 'software.federspiel.fedeo',
|
|
||||||
appName: 'FEDEO',
|
|
||||||
webDir: 'dist',
|
|
||||||
ios: {
|
|
||||||
handleApplicationNotifications: false
|
|
||||||
},
|
|
||||||
/*server: {
|
|
||||||
url: "http://192.168.1.226:3000",
|
|
||||||
cleartext: true
|
|
||||||
}*/
|
|
||||||
};
|
|
||||||
|
|
||||||
export default config;
|
|
||||||
@@ -171,7 +171,7 @@ const moveFile = async () => {
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<div :class="useCapacitor().getIsNative() ? ['w-full'] : ['w-1/3']">
|
<div :class="false ? ['w-full'] : ['w-1/3']">
|
||||||
<PDFViewer
|
<PDFViewer
|
||||||
v-if="props.documentData.id && props.documentData.path.toLowerCase().includes('pdf')"
|
v-if="props.documentData.id && props.documentData.path.toLowerCase().includes('pdf')"
|
||||||
:file-id="props.documentData.id" />
|
:file-id="props.documentData.id" />
|
||||||
@@ -183,7 +183,7 @@ const moveFile = async () => {
|
|||||||
v-else
|
v-else
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-2/3 p-5" v-if="!useCapacitor().getIsNative()">
|
<div class="w-2/3 p-5" v-if="!false">
|
||||||
<UButtonGroup>
|
<UButtonGroup>
|
||||||
<ArchiveButton
|
<ArchiveButton
|
||||||
color="rose"
|
color="rose"
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ const platform = ref("default")
|
|||||||
|
|
||||||
const setup = async () => {
|
const setup = async () => {
|
||||||
|
|
||||||
if(await useCapacitor().getIsPhone()) platform.value = "mobile"
|
|
||||||
|
|
||||||
if(props.type && props.elementId){
|
if(props.type && props.elementId){
|
||||||
items.value = await useNuxtApp().$api(`/api/resource/${props.type}/${props.elementId}/history`)
|
items.value = await useNuxtApp().$api(`/api/resource/${props.type}/${props.elementId}/history`)
|
||||||
|
|||||||
@@ -15,14 +15,8 @@ const props = defineProps({
|
|||||||
*/
|
*/
|
||||||
async function openLink(link) {
|
async function openLink(link) {
|
||||||
if (link.external) {
|
if (link.external) {
|
||||||
if (useCapacitor().getIsNative()) {
|
window.open(link.to, "_blank")
|
||||||
await Browser.open({
|
|
||||||
url: link.to,
|
|
||||||
presentationStyle: "popover",
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
window.open(link.to, "_blank")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return navigateTo(link.to)
|
return navigateTo(link.to)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,9 @@ const platform = ref("default")
|
|||||||
const setupPage = async () => {
|
const setupPage = async () => {
|
||||||
runningTimeInfo.value = (await supabase.from("times").select().eq("profile", profileStore.activeProfile.id).is("endDate", null).single()).data || {}
|
runningTimeInfo.value = (await supabase.from("times").select().eq("profile", profileStore.activeProfile.id).is("endDate", null).single()).data || {}
|
||||||
|
|
||||||
projects.value = (await useSupabaseSelect("projects"))
|
//projects.value = (await useSupabaseSelect("projects"))
|
||||||
|
|
||||||
|
|
||||||
if(await useCapacitor().getIsPhone()) {
|
|
||||||
platform.value = "mobile"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
import {Capacitor} from "@capacitor/core";
|
|
||||||
import {Device} from "@capacitor/device";
|
|
||||||
import {Network} from "@capacitor/network";
|
|
||||||
|
|
||||||
const override = false
|
|
||||||
|
|
||||||
export const useCapacitor = () => {
|
|
||||||
const getPlatform = () => {
|
|
||||||
return Capacitor.getPlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
const getDeviceInfo = async () => {
|
|
||||||
return await Device.getInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
const getIsPhone = async () => {
|
|
||||||
let deviceInfo = await useCapacitor().getDeviceInfo()
|
|
||||||
|
|
||||||
return override || deviceInfo.model.toLowerCase().includes('iphone')
|
|
||||||
}
|
|
||||||
|
|
||||||
const getIsNative = () => {
|
|
||||||
return override || Capacitor.isNativePlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
const getNetworkStatus = async () => {
|
|
||||||
return await Network.getStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {getPlatform, getDeviceInfo, getNetworkStatus, getIsPhone, getIsNative}
|
|
||||||
}
|
|
||||||
13
frontend/ios/.gitignore
vendored
@@ -1,13 +0,0 @@
|
|||||||
App/build
|
|
||||||
App/Pods
|
|
||||||
App/output
|
|
||||||
App/App/public
|
|
||||||
DerivedData
|
|
||||||
xcuserdata
|
|
||||||
|
|
||||||
# Cordova plugins for Capacitor
|
|
||||||
capacitor-cordova-ios-plugins
|
|
||||||
|
|
||||||
# Generated Config files
|
|
||||||
App/App/capacitor.config.json
|
|
||||||
App/App/config.xml
|
|
||||||
@@ -1,641 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 77;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
|
|
||||||
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
|
|
||||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
|
|
||||||
504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
|
|
||||||
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
|
|
||||||
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
|
|
||||||
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
|
||||||
7E144E961F6CA2C63512098E /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF9D76ED77CB578563C2573 /* Pods_OneSignalNotificationServiceExtension.framework */; };
|
|
||||||
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
|
|
||||||
D5A301A42D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D5A3019D2D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
D5A301A22D970BAC002A22E9 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 504EC2FC1FED79650016851F /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = D5A3019C2D970BAC002A22E9;
|
|
||||||
remoteInfo = OneSignalNotificationServiceExtension;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
|
||||||
D5A301A92D970BAC002A22E9 /* Embed Foundation Extensions */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 13;
|
|
||||||
files = (
|
|
||||||
D5A301A42D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */,
|
|
||||||
);
|
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
|
||||||
37F7155EDCE8C061367E30A9 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
4DF9D76ED77CB578563C2573 /* Pods_OneSignalNotificationServiceExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OneSignalNotificationServiceExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
|
||||||
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
|
||||||
504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
|
||||||
504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
|
||||||
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
|
||||||
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
|
|
||||||
6CB294319AEF8406BACB8AC1 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
D5A301982D970B67002A22E9 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = "<group>"; };
|
|
||||||
D5A3019D2D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OneSignalNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
|
||||||
D5A301A52D970BAC002A22E9 /* Exceptions for "OneSignalNotificationServiceExtension" folder in "OneSignalNotificationServiceExtension" target */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
|
||||||
membershipExceptions = (
|
|
||||||
Info.plist,
|
|
||||||
);
|
|
||||||
target = D5A3019C2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */;
|
|
||||||
};
|
|
||||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
|
||||||
D5A3019E2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
|
||||||
exceptions = (
|
|
||||||
D5A301A52D970BAC002A22E9 /* Exceptions for "OneSignalNotificationServiceExtension" folder in "OneSignalNotificationServiceExtension" target */,
|
|
||||||
);
|
|
||||||
path = OneSignalNotificationServiceExtension;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
504EC3011FED79650016851F /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
D5A3019A2D970BAC002A22E9 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
7E144E961F6CA2C63512098E /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */,
|
|
||||||
4DF9D76ED77CB578563C2573 /* Pods_OneSignalNotificationServiceExtension.framework */,
|
|
||||||
);
|
|
||||||
name = Frameworks;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
504EC2FB1FED79650016851F = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
504EC3061FED79650016851F /* App */,
|
|
||||||
D5A3019E2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */,
|
|
||||||
504EC3051FED79650016851F /* Products */,
|
|
||||||
7F8756D8B27F46E3366F6CEA /* Pods */,
|
|
||||||
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
504EC3051FED79650016851F /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
504EC3041FED79650016851F /* App.app */,
|
|
||||||
D5A3019D2D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
504EC3061FED79650016851F /* App */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
D5A301982D970B67002A22E9 /* App.entitlements */,
|
|
||||||
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
|
||||||
504EC3071FED79650016851F /* AppDelegate.swift */,
|
|
||||||
504EC30B1FED79650016851F /* Main.storyboard */,
|
|
||||||
504EC30E1FED79650016851F /* Assets.xcassets */,
|
|
||||||
504EC3101FED79650016851F /* LaunchScreen.storyboard */,
|
|
||||||
504EC3131FED79650016851F /* Info.plist */,
|
|
||||||
2FAD9762203C412B000D30F8 /* config.xml */,
|
|
||||||
50B271D01FEDC1A000F3C39B /* public */,
|
|
||||||
);
|
|
||||||
path = App;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
7F8756D8B27F46E3366F6CEA /* Pods */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
|
|
||||||
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
|
|
||||||
37F7155EDCE8C061367E30A9 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */,
|
|
||||||
6CB294319AEF8406BACB8AC1 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */,
|
|
||||||
);
|
|
||||||
name = Pods;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
504EC3031FED79650016851F /* App */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */;
|
|
||||||
buildPhases = (
|
|
||||||
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
|
|
||||||
504EC3001FED79650016851F /* Sources */,
|
|
||||||
504EC3011FED79650016851F /* Frameworks */,
|
|
||||||
504EC3021FED79650016851F /* Resources */,
|
|
||||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
|
||||||
D5A301A92D970BAC002A22E9 /* Embed Foundation Extensions */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
D5A301A32D970BAC002A22E9 /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = App;
|
|
||||||
productName = App;
|
|
||||||
productReference = 504EC3041FED79650016851F /* App.app */;
|
|
||||||
productType = "com.apple.product-type.application";
|
|
||||||
};
|
|
||||||
D5A3019C2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = D5A301A62D970BAC002A22E9 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */;
|
|
||||||
buildPhases = (
|
|
||||||
D76E39AEACB5B9B2BDC681BF /* [CP] Check Pods Manifest.lock */,
|
|
||||||
D5A301992D970BAC002A22E9 /* Sources */,
|
|
||||||
D5A3019A2D970BAC002A22E9 /* Frameworks */,
|
|
||||||
D5A3019B2D970BAC002A22E9 /* Resources */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
fileSystemSynchronizedGroups = (
|
|
||||||
D5A3019E2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */,
|
|
||||||
);
|
|
||||||
name = OneSignalNotificationServiceExtension;
|
|
||||||
productName = OneSignalNotificationServiceExtension;
|
|
||||||
productReference = D5A3019D2D970BAC002A22E9 /* OneSignalNotificationServiceExtension.appex */;
|
|
||||||
productType = "com.apple.product-type.app-extension";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
504EC2FC1FED79650016851F /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 1620;
|
|
||||||
LastUpgradeCheck = 0920;
|
|
||||||
TargetAttributes = {
|
|
||||||
504EC3031FED79650016851F = {
|
|
||||||
CreatedOnToolsVersion = 9.2;
|
|
||||||
LastSwiftMigration = 1100;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
D5A3019C2D970BAC002A22E9 = {
|
|
||||||
CreatedOnToolsVersion = 16.2;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
|
|
||||||
developmentRegion = en;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
Base,
|
|
||||||
);
|
|
||||||
mainGroup = 504EC2FB1FED79650016851F;
|
|
||||||
preferredProjectObjectVersion = 77;
|
|
||||||
productRefGroup = 504EC3051FED79650016851F /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
504EC3031FED79650016851F /* App */,
|
|
||||||
D5A3019C2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
|
||||||
504EC3021FED79650016851F /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
|
|
||||||
50B271D11FEDC1A000F3C39B /* public in Resources */,
|
|
||||||
504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
|
|
||||||
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
|
|
||||||
504EC30D1FED79650016851F /* Main.storyboard in Resources */,
|
|
||||||
2FAD9763203C412B000D30F8 /* config.xml in Resources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
D5A3019B2D970BAC002A22E9 /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXResourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
|
||||||
"${PODS_ROOT}/Manifest.lock",
|
|
||||||
);
|
|
||||||
name = "[CP] Check Pods Manifest.lock";
|
|
||||||
outputPaths = (
|
|
||||||
"$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Embed Pods Frameworks";
|
|
||||||
outputFileListPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
D76E39AEACB5B9B2BDC681BF /* [CP] Check Pods Manifest.lock */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
|
||||||
"${PODS_ROOT}/Manifest.lock",
|
|
||||||
);
|
|
||||||
name = "[CP] Check Pods Manifest.lock";
|
|
||||||
outputFileListPaths = (
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
"$(DERIVED_FILE_DIR)/Pods-OneSignalNotificationServiceExtension-checkManifestLockResult.txt",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
504EC3001FED79650016851F /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
D5A301992D970BAC002A22E9 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
D5A301A32D970BAC002A22E9 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = D5A3019C2D970BAC002A22E9 /* OneSignalNotificationServiceExtension */;
|
|
||||||
targetProxy = D5A301A22D970BAC002A22E9 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
504EC30B1FED79650016851F /* Main.storyboard */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
504EC30C1FED79650016851F /* Base */,
|
|
||||||
);
|
|
||||||
name = Main.storyboard;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
504EC3111FED79650016851F /* Base */,
|
|
||||||
);
|
|
||||||
name = LaunchScreen.storyboard;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
504EC3141FED79650016851F /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
|
||||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_COMMA = YES;
|
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
ENABLE_TESTABILITY = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
||||||
"DEBUG=1",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
504EC3151FED79650016851F /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
|
||||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_COMMA = YES;
|
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
504EC3171FED79650016851F /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = GMCGQ8KK2P;
|
|
||||||
INFOPLIST_FILE = App/Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
);
|
|
||||||
MARKETING_VERSION = 2.0;
|
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
504EC3181FED79650016851F /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = GMCGQ8KK2P;
|
|
||||||
INFOPLIST_FILE = App/Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
);
|
|
||||||
MARKETING_VERSION = 2.0;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
D5A301A72D970BAC002A22E9 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 37F7155EDCE8C061367E30A9 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = GMCGQ8KK2P;
|
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
|
||||||
INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist;
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
"@executable_path/../../Frameworks",
|
|
||||||
);
|
|
||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
|
||||||
MARKETING_VERSION = 1.0;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
|
||||||
MTL_FAST_MATH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo.OneSignalNotificationServiceExtension;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SKIP_INSTALL = YES;
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
D5A301A82D970BAC002A22E9 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 6CB294319AEF8406BACB8AC1 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = GMCGQ8KK2P;
|
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
|
||||||
INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist;
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
"@executable_path/../../Frameworks",
|
|
||||||
);
|
|
||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
|
||||||
MARKETING_VERSION = 1.0;
|
|
||||||
MTL_FAST_MATH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = software.federspiel.fedeo.OneSignalNotificationServiceExtension;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SKIP_INSTALL = YES;
|
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
504EC3141FED79650016851F /* Debug */,
|
|
||||||
504EC3151FED79650016851F /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
504EC3171FED79650016851F /* Debug */,
|
|
||||||
504EC3181FED79650016851F /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
D5A301A62D970BAC002A22E9 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
D5A301A72D970BAC002A22E9 /* Debug */,
|
|
||||||
D5A301A82D970BAC002A22E9 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 504EC2FC1FED79650016851F /* Project object */;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "group:App.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
<FileRef
|
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>IDEDidComputeMac32BitWarning</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>aps-environment</key>
|
|
||||||
<string>development</string>
|
|
||||||
<key>com.apple.security.application-groups</key>
|
|
||||||
<array>
|
|
||||||
<string>group.software.federspiel.fedeo.onesignal</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import UIKit
|
|
||||||
import Capacitor
|
|
||||||
|
|
||||||
@UIApplicationMain
|
|
||||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
||||||
|
|
||||||
var window: UIWindow?
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
||||||
// Override point for customization after application launch.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationWillResignActive(_ application: UIApplication) {
|
|
||||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
|
||||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
|
||||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
|
||||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
|
||||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
|
||||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationWillTerminate(_ application: UIApplication) {
|
|
||||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
|
||||||
}
|
|
||||||
|
|
||||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
|
||||||
// Called when the app was launched with a url. Feel free to add additional processing here,
|
|
||||||
// but if you want the App API to support tracking app url opens, make sure to keep this call
|
|
||||||
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
|
||||||
// Called when the app was launched with an activity, including Universal Links.
|
|
||||||
// Feel free to add additional processing here, but if you want the App API to support
|
|
||||||
// tracking app url opens, make sure to keep this call
|
|
||||||
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"idiom": "universal",
|
|
||||||
"size": "1024x1024",
|
|
||||||
"filename": "AppIcon-512@2x.png",
|
|
||||||
"platform": "ios"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info": {
|
|
||||||
"author": "xcode",
|
|
||||||
"version": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
{
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"idiom": "universal",
|
|
||||||
"filename": "Default@1x~universal~anyany.png",
|
|
||||||
"scale": "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom": "universal",
|
|
||||||
"filename": "Default@2x~universal~anyany.png",
|
|
||||||
"scale": "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom": "universal",
|
|
||||||
"filename": "Default@3x~universal~anyany.png",
|
|
||||||
"scale": "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances": [
|
|
||||||
{
|
|
||||||
"appearance": "luminosity",
|
|
||||||
"value": "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"idiom": "universal",
|
|
||||||
"scale": "1x",
|
|
||||||
"filename": "Default@1x~universal~anyany-dark.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances": [
|
|
||||||
{
|
|
||||||
"appearance": "luminosity",
|
|
||||||
"value": "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"idiom": "universal",
|
|
||||||
"scale": "2x",
|
|
||||||
"filename": "Default@2x~universal~anyany-dark.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances": [
|
|
||||||
{
|
|
||||||
"appearance": "luminosity",
|
|
||||||
"value": "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"idiom": "universal",
|
|
||||||
"scale": "3x",
|
|
||||||
"filename": "Default@3x~universal~anyany-dark.png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info": {
|
|
||||||
"version": 1,
|
|
||||||
"author": "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
@@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17132" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
|
||||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17105"/>
|
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--View Controller-->
|
|
||||||
<scene sceneID="EHf-IW-A2E">
|
|
||||||
<objects>
|
|
||||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
|
||||||
<imageView key="view" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" id="snD-IY-ifK">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
||||||
</imageView>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="53" y="375"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
<resources>
|
|
||||||
<image name="Splash" width="1366" height="1366"/>
|
|
||||||
<systemColor name="systemBackgroundColor">
|
|
||||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</systemColor>
|
|
||||||
</resources>
|
|
||||||
</document>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14111" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
|
||||||
<device id="retina4_7" orientation="portrait">
|
|
||||||
<adaptation id="fullscreen"/>
|
|
||||||
</device>
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--Bridge View Controller-->
|
|
||||||
<scene sceneID="tne-QT-ifu">
|
|
||||||
<objects>
|
|
||||||
<viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
</document>
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>de</string>
|
|
||||||
<key>CFBundleDisplayName</key>
|
|
||||||
<string>FEDEO</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>$(MARKETING_VERSION)</string>
|
|
||||||
<key>CFBundleURLTypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleURLSchemes</key>
|
|
||||||
<array>
|
|
||||||
<string>fedeo</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>LSRequiresIPhoneOS</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSLocationAlwaysUsageDescription</key>
|
|
||||||
<string>One Signal Notifications</string>
|
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string>One Signal Notifications</string>
|
|
||||||
<key>NSSupportsLiveActivities</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSSupportsLiveActivitiesFrequentUpdates</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIBackgroundModes</key>
|
|
||||||
<array>
|
|
||||||
<string>remote-notification</string>
|
|
||||||
</array>
|
|
||||||
<key>UILaunchStoryboardName</key>
|
|
||||||
<string>LaunchScreen</string>
|
|
||||||
<key>UIMainStoryboardFile</key>
|
|
||||||
<string>Main</string>
|
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
</array>
|
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
|
||||||
</array>
|
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>NSExtension</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSExtensionPointIdentifier</key>
|
|
||||||
<string>com.apple.usernotifications.service</string>
|
|
||||||
<key>NSExtensionPrincipalClass</key>
|
|
||||||
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import UserNotifications
|
|
||||||
|
|
||||||
import OneSignalExtension
|
|
||||||
|
|
||||||
class NotificationService: UNNotificationServiceExtension {
|
|
||||||
|
|
||||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
|
||||||
var receivedRequest: UNNotificationRequest!
|
|
||||||
var bestAttemptContent: UNMutableNotificationContent?
|
|
||||||
|
|
||||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
|
||||||
self.receivedRequest = request
|
|
||||||
self.contentHandler = contentHandler
|
|
||||||
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
|
||||||
|
|
||||||
if let bestAttemptContent = bestAttemptContent {
|
|
||||||
/* DEBUGGING: Uncomment the 2 lines below to check this extension is executing
|
|
||||||
Note, this extension only runs when mutable-content is set
|
|
||||||
Setting an attachment or action buttons automatically adds this */
|
|
||||||
// print("Running NotificationServiceExtension")
|
|
||||||
// bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
|
|
||||||
|
|
||||||
OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func serviceExtensionTimeWillExpire() {
|
|
||||||
// Called just before the extension will be terminated by the system.
|
|
||||||
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
|
|
||||||
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
|
||||||
OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
|
|
||||||
contentHandler(bestAttemptContent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>com.apple.security.application-groups</key>
|
|
||||||
<array>
|
|
||||||
<string>group.software.federspiel.fedeo.onesignal</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
|
|
||||||
|
|
||||||
platform :ios, '14.0'
|
|
||||||
use_frameworks!
|
|
||||||
|
|
||||||
# workaround to avoid Xcode caching of Pods that requires
|
|
||||||
# Product -> Clean Build Folder after new Cordova plugins installed
|
|
||||||
# Requires CocoaPods 1.6 or newer
|
|
||||||
install! 'cocoapods', :disable_input_output_paths => true
|
|
||||||
|
|
||||||
def capacitor_pods
|
|
||||||
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
|
||||||
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
|
||||||
pod 'CapacitorBrowser', :path => '../../node_modules/@capacitor/browser'
|
|
||||||
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
|
|
||||||
|
|
||||||
target 'App' do
|
|
||||||
capacitor_pods
|
|
||||||
# Add your Pods here
|
|
||||||
end
|
|
||||||
|
|
||||||
post_install do |installer|
|
|
||||||
installer.pods_project.targets.each do |target|
|
|
||||||
target.build_configurations.each do |config|
|
|
||||||
# iOS Deployment Target erzwingen
|
|
||||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
|
|
||||||
|
|
||||||
# Alle Warnungen auf inherited setzen, falls Pods Dinge überschreiben
|
|
||||||
config.build_settings['CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER'] = '$(inherited)'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
target 'OneSignalNotificationServiceExtension' do
|
|
||||||
pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
|
|
||||||
end
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import MainNav from "~/components/MainNav.vue";
|
import MainNav from "~/components/MainNav.vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {useCapacitor} from "../composables/useCapacitor.js";
|
|
||||||
import GlobalMessages from "~/components/GlobalMessages.vue";
|
import GlobalMessages from "~/components/GlobalMessages.vue";
|
||||||
import TenantDropdown from "~/components/TenantDropdown.vue";
|
import TenantDropdown from "~/components/TenantDropdown.vue";
|
||||||
import LabelPrinterButton from "~/components/LabelPrinterButton.vue";
|
import LabelPrinterButton from "~/components/LabelPrinterButton.vue";
|
||||||
@@ -228,13 +227,6 @@ const footerLinks = [
|
|||||||
</UDashboardNavbar>
|
</UDashboardNavbar>
|
||||||
|
|
||||||
<UDashboardSidebar id="sidebar">
|
<UDashboardSidebar id="sidebar">
|
||||||
<!-- <template #header>
|
|
||||||
<UDashboardSearchButton label="Suche..."/>
|
|
||||||
</template>-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<GlobalMessages/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<MainNav/>
|
<MainNav/>
|
||||||
|
|
||||||
@@ -266,11 +258,6 @@ const footerLinks = [
|
|||||||
|
|
||||||
<HelpSlideover/>
|
<HelpSlideover/>
|
||||||
|
|
||||||
<!--<NotificationsSlideover />
|
|
||||||
|
|
||||||
<ClientOnly>
|
|
||||||
<LazyUDashboardSearch :groups="groups" hide-color-mode/>
|
|
||||||
</ClientOnly>-->
|
|
||||||
</UDashboardLayout>
|
</UDashboardLayout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,275 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { ref, onMounted, onBeforeUnmount } from "vue"
|
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import {useAuthStore} from "~/stores/auth.js";
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
const auth = useAuthStore()
|
|
||||||
|
|
||||||
const month = dayjs().format("MM")
|
|
||||||
|
|
||||||
|
|
||||||
const hideNav = ref(false)
|
|
||||||
let lastScrollY = 0
|
|
||||||
let scrollElement = null
|
|
||||||
let returnTimer = null
|
|
||||||
|
|
||||||
const SHOW_DELAY = 1000 // 1 Sekunden
|
|
||||||
|
|
||||||
function showNavAfterDelay() {
|
|
||||||
clearTimeout(returnTimer)
|
|
||||||
returnTimer = setTimeout(() => {
|
|
||||||
hideNav.value = false
|
|
||||||
}, SHOW_DELAY)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleScroll = () => {
|
|
||||||
const current = scrollElement.scrollTop
|
|
||||||
|
|
||||||
// Runter scrollen -> verstecken
|
|
||||||
if (current > lastScrollY + 10) {
|
|
||||||
hideNav.value = true
|
|
||||||
showNavAfterDelay()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hoch scrollen -> sofort zeigen
|
|
||||||
if (current < lastScrollY - 10) {
|
|
||||||
hideNav.value = false
|
|
||||||
clearTimeout(returnTimer)
|
|
||||||
}
|
|
||||||
|
|
||||||
lastScrollY = current
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
scrollElement = document.querySelector('.mobile-scroll-area')
|
|
||||||
if (scrollElement) {
|
|
||||||
scrollElement.addEventListener('scroll', handleScroll)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
if (scrollElement) scrollElement.removeEventListener('scroll', handleScroll)
|
|
||||||
clearTimeout(returnTimer)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div v-if="!auth.loading">
|
|
||||||
<div v-if="auth.activeTenantData?.locked === 'maintenance_tenant'">
|
|
||||||
<UContainer class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
|
|
||||||
<UCard class="max-w-lg text-center p-10">
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo_Hell_Weihnachten.png"
|
|
||||||
dark="/Logo_Dunkel_Weihnachten.png"
|
|
||||||
class=" mx-auto my-10"
|
|
||||||
v-if="month === '12'"
|
|
||||||
/>
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo.png"
|
|
||||||
dark="/Logo_Dark.png"
|
|
||||||
class="mx-auto my-10"
|
|
||||||
v-else
|
|
||||||
/>
|
|
||||||
<div class="flex justify-center mb-6">
|
|
||||||
<UIcon name="i-heroicons-exclamation-triangle-solid" class="w-16 h-16 text-yellow-500" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
|
|
||||||
Wartungsarbeiten
|
|
||||||
</h1>
|
|
||||||
<p class="text-gray-600 dark:text-gray-300 mb-8">
|
|
||||||
Dieser FEDEO Mandant wird derzeit gewartet. Bitte versuche es in einigen Minuten erneut oder verwende einen anderen Mandanten.
|
|
||||||
</p>
|
|
||||||
<div class="mx-auto text-left flex flex-row justify-between my-3" v-for="tenant in auth.tenants">
|
|
||||||
{{tenant.name}}
|
|
||||||
<UButton
|
|
||||||
:disabled="tenant.locked"
|
|
||||||
@click="auth.switchTenant(tenant.id)"
|
|
||||||
>Wählen</UButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
</UContainer>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="auth.activeTenantData?.locked === 'maintenance'">
|
|
||||||
<UContainer class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
|
|
||||||
<UCard class="max-w-lg text-center p-10">
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo_Hell_Weihnachten.png"
|
|
||||||
dark="/Logo_Dunkel_Weihnachten.png"
|
|
||||||
class=" mx-auto my-10"
|
|
||||||
v-if="month === '12'"
|
|
||||||
/>
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo.png"
|
|
||||||
dark="/Logo_Dark.png"
|
|
||||||
class="mx-auto my-10"
|
|
||||||
v-else
|
|
||||||
/>
|
|
||||||
<div class="flex justify-center mb-6">
|
|
||||||
<UIcon name="i-heroicons-exclamation-triangle-solid" class="w-16 h-16 text-yellow-500" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
|
|
||||||
Wartungsarbeiten
|
|
||||||
</h1>
|
|
||||||
<p class="text-gray-600 dark:text-gray-300 mb-8">
|
|
||||||
FEDEO wird derzeit gewartet. Bitte versuche es in einigen Minuten erneut.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
</UContainer>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="auth.activeTenantData?.locked === 'no_subscription'">
|
|
||||||
<UContainer class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
|
|
||||||
<UCard class="max-w-lg text-center p-10">
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo_Hell_Weihnachten.png"
|
|
||||||
dark="/Logo_Dunkel_Weihnachten.png"
|
|
||||||
class=" mx-auto my-10"
|
|
||||||
v-if="month === '12'"
|
|
||||||
/>
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo.png"
|
|
||||||
dark="/Logo_Dark.png"
|
|
||||||
class="mx-auto my-10"
|
|
||||||
v-else
|
|
||||||
/>
|
|
||||||
<div class="flex justify-center mb-6">
|
|
||||||
<UIcon name="i-heroicons-credit-card" class="w-16 h-16 text-red-600" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
|
|
||||||
Kein Aktives Abonnement für diesen Mandant.
|
|
||||||
</h1>
|
|
||||||
<p class="text-gray-600 dark:text-gray-300 mb-8">
|
|
||||||
Bitte wenden Sie sich an den FEDEO Support um ein Abonnement zu erhalten oder verwenden Sie einen anderen Mandanten.
|
|
||||||
</p>
|
|
||||||
<div class="mx-auto text-left flex flex-row justify-between my-3" v-for="tenant in auth.tenants">
|
|
||||||
{{tenant.name}}
|
|
||||||
<UButton
|
|
||||||
:disabled="tenant.locked"
|
|
||||||
@click="auth.switchTenant(tenant.id)"
|
|
||||||
>Wählen</UButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
</UContainer>
|
|
||||||
</div>
|
|
||||||
<UDashboardLayout class="safearea" v-else>
|
|
||||||
|
|
||||||
<UDashboardPage style="height: 90vh">
|
|
||||||
<UDashboardPanel grow>
|
|
||||||
<slot />
|
|
||||||
</UDashboardPanel>
|
|
||||||
</UDashboardPage>
|
|
||||||
|
|
||||||
<!-- Modernisierte Mobile Navigation -->
|
|
||||||
<nav
|
|
||||||
:class="[
|
|
||||||
'fixed bottom-0 left-0 right-0 z-50', // ← bottom-0 hinzugefügt!
|
|
||||||
'h-[70px] bg-white/80 dark:bg-gray-950/80 backdrop-blur-xl',
|
|
||||||
'border-t border-gray-200 dark:border-gray-800',
|
|
||||||
'flex justify-around items-center pt-2 pb-[max(env(safe-area-inset-bottom),0.5rem)]',
|
|
||||||
'transition-transform duration-300 ease-in-out',
|
|
||||||
hideNav ? 'translate-y-full' : 'translate-y-0'
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<UButton
|
|
||||||
icon="i-heroicons-home"
|
|
||||||
to="/mobile/"
|
|
||||||
variant="ghost"
|
|
||||||
:color="route.fullPath === '/mobile' ? 'primary' : 'gray'"
|
|
||||||
class="nav-btn"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UButton
|
|
||||||
icon="i-heroicons-clipboard-document-check"
|
|
||||||
to="/standardEntity/tasks"
|
|
||||||
variant="ghost"
|
|
||||||
:color="route.fullPath === '/standardEntity/tasks' ? 'primary' : 'gray'"
|
|
||||||
class="nav-btn"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UButton
|
|
||||||
icon="i-heroicons-rectangle-stack"
|
|
||||||
to="/standardEntity/projects"
|
|
||||||
variant="ghost"
|
|
||||||
:color="route.fullPath === '/standardEntity/projects' ? 'primary' : 'gray'"
|
|
||||||
class="nav-btn"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UButton
|
|
||||||
icon="i-heroicons-bars-4"
|
|
||||||
to="/mobile/menu"
|
|
||||||
variant="ghost"
|
|
||||||
:color="route.fullPath === '/mobile/menu' ? 'primary' : 'gray'"
|
|
||||||
class="nav-btn"
|
|
||||||
/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
|
||||||
</UDashboardLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="flex flex-col"
|
|
||||||
>
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo_Hell_Weihnachten.png"
|
|
||||||
dark="/Logo_Dunkel_Weihnachten.png"
|
|
||||||
class="w-1/3 mx-auto my-10"
|
|
||||||
v-if="month === '12'"
|
|
||||||
/>
|
|
||||||
<UColorModeImage
|
|
||||||
light="/Logo.png"
|
|
||||||
dark="/Logo_Dark.png"
|
|
||||||
class="w-1/3 mx-auto my-10"
|
|
||||||
v-else
|
|
||||||
/>
|
|
||||||
<div v-if="!auth.activeTenant && auth.tenants?.length > 0 " class="w-full mx-auto text-center">
|
|
||||||
<!-- Tenant Selection -->
|
|
||||||
<h3 class="text-center font-bold text-2xl mb-5">Kein Aktiver Mandant. <br>Bitte wählen Sie ein Mandant.</h3>
|
|
||||||
<div class="mx-auto w-5/6 flex flex-row justify-between my-3" v-for="tenant in auth.tenants">
|
|
||||||
<span class="text-left">{{tenant.name}}</span>
|
|
||||||
<UButton
|
|
||||||
@click="auth.switchTenant(tenant.id)"
|
|
||||||
>Wählen</UButton>
|
|
||||||
</div>
|
|
||||||
<UButton
|
|
||||||
variant="outline"
|
|
||||||
color="rose"
|
|
||||||
@click="auth.logout()"
|
|
||||||
>Abmelden</UButton>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<UProgress animation="carousel" class="w-3/4 mx-auto mt-10" />Test
|
|
||||||
{{auth.tenants}}
|
|
||||||
|
|
||||||
<UButton
|
|
||||||
variant="outline"
|
|
||||||
color="rose"
|
|
||||||
@click="auth.logout()"
|
|
||||||
>Abmelden</UButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.nav-btn {
|
|
||||||
@apply w-12 h-12 flex justify-center items-center rounded-xl active:scale-95 transition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,20 +1,42 @@
|
|||||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
|
|
||||||
console.log(auth)
|
// DEBUG: Was sieht die Middleware wirklich?
|
||||||
|
console.log("🔒 Middleware Check auf:", to.path)
|
||||||
|
console.log("👤 User Status:", auth.user ? "Eingeloggt" : "Gast")
|
||||||
|
|
||||||
if (auth.loading) return
|
// 1. Ausnahme für Workflows
|
||||||
|
// WICHTIG: Prüfen ob to.path wirklich mit /workflows beginnt
|
||||||
|
if (to.path.startsWith('/workflows')) {
|
||||||
|
console.log("✅ Zugriff erlaubt (Public Route)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth.loading) {
|
||||||
|
console.log("⏳ Auth lädt noch...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Wenn nicht eingeloggt → auf /login (außer er will schon dahin)
|
// 2. Wenn nicht eingeloggt
|
||||||
if (!auth.user && !["/login", "/password-reset"].includes(to.path)) {
|
if (!auth.user) {
|
||||||
|
// Erlaube Zugriff auf Login/Reset Seiten
|
||||||
|
if (["/login", "/password-reset"].includes(to.path)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("⛔ Blocked: Not logged in - Redirect to /login")
|
||||||
return navigateTo("/login")
|
return navigateTo("/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn eingeloggt → von /login auf /dashboard umleiten
|
// 3. Wenn eingeloggt
|
||||||
if (auth.user && !auth.user?.must_change_password && to.path === "/login") {
|
if (to.path === "/login") {
|
||||||
|
if (auth.user.must_change_password) {
|
||||||
|
return navigateTo("/password-change")
|
||||||
|
}
|
||||||
return navigateTo("/")
|
return navigateTo("/")
|
||||||
} else if(auth.user && auth.user.must_change_password && to.path !== "/password-change") {
|
}
|
||||||
|
|
||||||
|
if (auth.user.must_change_password && to.path !== "/password-change") {
|
||||||
return navigateTo("/password-change")
|
return navigateTo("/password-change")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export default defineNuxtRouteMiddleware(async (to, _from) => {
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
console.log(useCapacitor().getIsNative())
|
|
||||||
|
|
||||||
if(useCapacitor().getIsNative() && _from.path !== '/mobile') {
|
|
||||||
return router.push('/mobile')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -117,6 +117,8 @@ const totalCalculated = computed(() => {
|
|||||||
|
|
||||||
if(account.taxType === "19" && account.amountTax) {
|
if(account.taxType === "19" && account.amountTax) {
|
||||||
totalAmount19Tax += account.amountTax
|
totalAmount19Tax += account.amountTax
|
||||||
|
} else if(account.taxType === "7" && account.amountTax) {
|
||||||
|
totalAmount7Tax += account.amountTax
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -125,6 +127,7 @@ const totalCalculated = computed(() => {
|
|||||||
return {
|
return {
|
||||||
totalNet,
|
totalNet,
|
||||||
totalAmount19Tax,
|
totalAmount19Tax,
|
||||||
|
totalAmount7Tax,
|
||||||
totalGross
|
totalGross
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,6 +395,10 @@ const findIncomingInvoiceErrors = computed(() => {
|
|||||||
<td>Gesamt exkl. Steuer: </td>
|
<td>Gesamt exkl. Steuer: </td>
|
||||||
<td class="text-right">{{totalCalculated.totalNet.toFixed(2).replace(".",",")}} €</td>
|
<td class="text-right">{{totalCalculated.totalNet.toFixed(2).replace(".",",")}} €</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>7% Steuer: </td>
|
||||||
|
<td class="text-right">{{totalCalculated.totalAmount7Tax.toFixed(2).replace(".",",")}} €</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>19% Steuer: </td>
|
<td>19% Steuer: </td>
|
||||||
<td class="text-right">{{totalCalculated.totalAmount19Tax.toFixed(2).replace(".",",")}} €</td>
|
<td class="text-right">{{totalCalculated.totalAmount19Tax.toFixed(2).replace(".",",")}} €</td>
|
||||||
@@ -441,7 +448,7 @@ const findIncomingInvoiceErrors = computed(() => {
|
|||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
searchable
|
searchable
|
||||||
:disabled="mode === 'show'"
|
:disabled="mode === 'show'"
|
||||||
:search-attributes="['label']"
|
:search-attributes="['label','name','description','number']"
|
||||||
searchable-placeholder="Suche..."
|
searchable-placeholder="Suche..."
|
||||||
v-model="item.costCentre"
|
v-model="item.costCentre"
|
||||||
class="flex-auto"
|
class="flex-auto"
|
||||||
@@ -450,10 +457,10 @@ const findIncomingInvoiceErrors = computed(() => {
|
|||||||
{{costcentres.find(i => i.id === item.costCentre) ? costcentres.find(i => i.id === item.costCentre).name : "Keine Kostenstelle ausgewählt" }}
|
{{costcentres.find(i => i.id === item.costCentre) ? costcentres.find(i => i.id === item.costCentre).name : "Keine Kostenstelle ausgewählt" }}
|
||||||
</template>
|
</template>
|
||||||
<template #option="{option}">
|
<template #option="{option}">
|
||||||
<span v-if="option.vehicle">Fahrzeug - {{option.name}}</span>
|
<span v-if="option.vehicle">{{option.number}} - Fahrzeug - {{option.name}}</span>
|
||||||
<span v-else-if="option.project">Projekt - {{option.name}}</span>
|
<span v-else-if="option.project">{{option.number}} - Projekt - {{option.name}}</span>
|
||||||
<span v-else-if="option.inventoryitem">Inventarartikel - {{option.name}}</span>
|
<span v-else-if="option.inventoryitem">{{option.number}} - Inventarartikel - {{option.name}}</span>
|
||||||
<span v-else>{{option.name}}</span>
|
<span v-else>{{option.number}} - {{option.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
|
|||||||
@@ -80,9 +80,6 @@
|
|||||||
import Nimbot from "~/components/nimbot.vue";
|
import Nimbot from "~/components/nimbot.vue";
|
||||||
import LabelPrintModal from "~/components/LabelPrintModal.vue";
|
import LabelPrintModal from "~/components/LabelPrintModal.vue";
|
||||||
|
|
||||||
definePageMeta({
|
|
||||||
middleware: 'redirect-to-mobile-index'
|
|
||||||
})
|
|
||||||
|
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
|
|||||||
@@ -7,19 +7,14 @@ const auth = useAuthStore()
|
|||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const platformIsNative = useCapacitor().getIsNative()
|
|
||||||
|
|
||||||
|
|
||||||
const doLogin = async (data:any) => {
|
const doLogin = async (data:any) => {
|
||||||
try {
|
try {
|
||||||
await auth.login(data.email, data.password)
|
await auth.login(data.email, data.password)
|
||||||
// Weiterleiten nach erfolgreichem Login
|
// Weiterleiten nach erfolgreichem Login
|
||||||
toast.add({title:"Einloggen erfolgreich"})
|
toast.add({title:"Einloggen erfolgreich"})
|
||||||
if(platformIsNative) {
|
|
||||||
await router.push("/mobile")
|
await router.push("/")
|
||||||
} else {
|
|
||||||
await router.push("/")
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
toast.add({title:"Zugangsdaten falsch. Bitte überprüfen Sie Ihre Eingaben",color:"rose"})
|
toast.add({title:"Zugangsdaten falsch. Bitte überprüfen Sie Ihre Eingaben",color:"rose"})
|
||||||
}
|
}
|
||||||
@@ -27,22 +22,13 @@ const doLogin = async (data:any) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard class="max-w-sm w-full mx-auto mt-5" v-if="!platformIsNative">
|
<UCard class="max-w-sm w-full mx-auto mt-5">
|
||||||
|
|
||||||
<UColorModeImage
|
<UColorModeImage
|
||||||
light="/Logo.png"
|
light="/Logo.png"
|
||||||
dark="/Logo_Dark.png"
|
dark="/Logo_Dark.png"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UAlert
|
|
||||||
title="Achtung"
|
|
||||||
description="Es wurden alle Benutzerkonten zurückgesetzt. Bitte fordert über Passwort vergessen ein neues Passwort an."
|
|
||||||
color="rose"
|
|
||||||
variant="outline"
|
|
||||||
class="my-5"
|
|
||||||
>
|
|
||||||
</UAlert>
|
|
||||||
|
|
||||||
<UAuthForm
|
<UAuthForm
|
||||||
title="Login"
|
title="Login"
|
||||||
description="Geben Sie Ihre Anmeldedaten ein um Zugriff auf Ihren Account zu erhalten."
|
description="Geben Sie Ihre Anmeldedaten ein um Zugriff auf Ihren Account zu erhalten."
|
||||||
@@ -68,7 +54,7 @@ const doLogin = async (data:any) => {
|
|||||||
</template>
|
</template>
|
||||||
</UAuthForm>
|
</UAuthForm>
|
||||||
</UCard>
|
</UCard>
|
||||||
<div v-else class="mt-20 m-2 p-2">
|
<!-- <div v-else class="mt-20 m-2 p-2">
|
||||||
<UColorModeImage
|
<UColorModeImage
|
||||||
light="/Logo.png"
|
light="/Logo.png"
|
||||||
dark="/Logo_Dark.png"
|
dark="/Logo_Dark.png"
|
||||||
@@ -98,5 +84,5 @@ const doLogin = async (data:any) => {
|
|||||||
<NuxtLink to="/password-reset" class="text-primary font-medium">Passwort vergessen?</NuxtLink>
|
<NuxtLink to="/password-reset" class="text-primary font-medium">Passwort vergessen?</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
</UAuthForm>
|
</UAuthForm>
|
||||||
</div>
|
</div>-->
|
||||||
</template>
|
</template>
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
|
|
||||||
|
|
||||||
definePageMeta({
|
|
||||||
layout: 'mobile'
|
|
||||||
})
|
|
||||||
|
|
||||||
const auth = useAuthStore()
|
|
||||||
|
|
||||||
const pinnedLinks = computed(() => {
|
|
||||||
return (auth.profile?.pinned_on_navigation || [])
|
|
||||||
.map((pin) => {
|
|
||||||
if (pin.type === "external") {
|
|
||||||
return {
|
|
||||||
label: pin.label,
|
|
||||||
to: pin.link,
|
|
||||||
icon: pin.icon,
|
|
||||||
external: true,
|
|
||||||
}
|
|
||||||
} else if (pin.type === "standardEntity") {
|
|
||||||
return {
|
|
||||||
label: pin.label,
|
|
||||||
to: `/standardEntity/${pin.datatype}/show/${pin.id}`,
|
|
||||||
icon: pin.icon,
|
|
||||||
external: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<UDashboardPanelContent>
|
|
||||||
<UPageGrid>
|
|
||||||
<UDashboardCard>
|
|
||||||
<display-welcome/>
|
|
||||||
</UDashboardCard>
|
|
||||||
<UDashboardCard
|
|
||||||
title="Aufgaben"
|
|
||||||
>
|
|
||||||
<display-open-tasks/>
|
|
||||||
</UDashboardCard>
|
|
||||||
<!--<UDashboardCard
|
|
||||||
title="Anwesenheit"
|
|
||||||
>
|
|
||||||
<display-running-working-time/>
|
|
||||||
</UDashboardCard>
|
|
||||||
<UDashboardCard
|
|
||||||
title="Zeit"
|
|
||||||
>
|
|
||||||
<display-running-time/>
|
|
||||||
</UDashboardCard>
|
|
||||||
<UDashboardCard
|
|
||||||
title="Buchhaltung"
|
|
||||||
v-if="profileStore.ownTenant.features.accounting"
|
|
||||||
>
|
|
||||||
<display-open-balances/>
|
|
||||||
</UDashboardCard>-->
|
|
||||||
<UDashboardCard
|
|
||||||
title="Projekte"
|
|
||||||
>
|
|
||||||
<display-projects-in-phases/>
|
|
||||||
</UDashboardCard>
|
|
||||||
<display-pinnend-links :links="pinnedLinks"/>
|
|
||||||
|
|
||||||
</UPageGrid>
|
|
||||||
</UDashboardPanelContent>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
|
|
||||||
definePageMeta({
|
|
||||||
layout: 'mobile',
|
|
||||||
})
|
|
||||||
|
|
||||||
const auth = useAuthStore()
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<UDashboardPanelContent>
|
|
||||||
<UDivider class="mb-3">Weiteres</UDivider>
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/staff/time"
|
|
||||||
icon="i-heroicons-clock"
|
|
||||||
>
|
|
||||||
Zeiten
|
|
||||||
</UButton>
|
|
||||||
<!-- <UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/standardEntity/absencerequests"
|
|
||||||
icon="i-heroicons-document-text"
|
|
||||||
>
|
|
||||||
Abwesenheiten
|
|
||||||
</UButton>-->
|
|
||||||
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/standardEntity/customers"
|
|
||||||
icon="i-heroicons-user-group"
|
|
||||||
>
|
|
||||||
Kunden
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/standardEntity/vendors"
|
|
||||||
icon="i-heroicons-truck"
|
|
||||||
>
|
|
||||||
Lieferanten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/standardEntity/contacts"
|
|
||||||
icon="i-heroicons-user-group"
|
|
||||||
>
|
|
||||||
Ansprechpartner
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
to="/standardEntity/plants"
|
|
||||||
icon="i-heroicons-clipboard-document"
|
|
||||||
>
|
|
||||||
Objekte
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
class="w-full my-1"
|
|
||||||
@click="auth.logout()"
|
|
||||||
color="rose"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
Abmelden
|
|
||||||
</UButton>
|
|
||||||
|
|
||||||
<UDivider class="my-5">Unternehmen wechseln</UDivider>
|
|
||||||
|
|
||||||
<div class="w-full flex flex-row justify-between my-3" v-for="tenant in auth.tenants">
|
|
||||||
<span class="text-left">{{tenant.name}}</span>
|
|
||||||
<UButton
|
|
||||||
@click="auth.switchTenant(tenant.id)"
|
|
||||||
>Wechseln</UButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</UDashboardPanelContent>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -24,7 +24,7 @@ const workingTimeInfo = ref<{
|
|||||||
} | null; // Neue Struktur für die Zusammenfassung
|
} | null; // Neue Struktur für die Zusammenfassung
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
|
|
||||||
const platformIsNative = ref(useCapacitor().getIsNative())
|
const platformIsNative = ref(false)
|
||||||
|
|
||||||
const selectedPresetRange = ref("Dieser Monat bis heute")
|
const selectedPresetRange = ref("Dieser Monat bis heute")
|
||||||
const selectedStartDay = ref("")
|
const selectedStartDay = ref("")
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const toast = useToast()
|
|||||||
const { $dayjs } = useNuxtApp()
|
const { $dayjs } = useNuxtApp()
|
||||||
|
|
||||||
// MOBILE DETECTION
|
// MOBILE DETECTION
|
||||||
const platformIsNative = useCapacitor().getIsNative()
|
const platformIsNative = false
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {setPageLayout} from "#app";
|
import {setPageLayout} from "#app";
|
||||||
import {useCapacitor} from "~/composables/useCapacitor.js";
|
|
||||||
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
@@ -9,7 +7,7 @@ const api = useNuxtApp().$api
|
|||||||
|
|
||||||
|
|
||||||
const type = route.params.type
|
const type = route.params.type
|
||||||
const platform = await useCapacitor().getIsNative() ? "mobile" : "default"
|
const platform = "default"
|
||||||
|
|
||||||
|
|
||||||
const dataType = dataStore.dataTypes[route.params.type]
|
const dataType = dataStore.dataTypes[route.params.type]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {setPageLayout} from "#app";
|
|||||||
|
|
||||||
const { has } = usePermission()
|
const { has } = usePermission()
|
||||||
|
|
||||||
const platformIsNative = useCapacitor().getIsNative()
|
const platformIsNative = false
|
||||||
|
|
||||||
defineShortcuts({
|
defineShortcuts({
|
||||||
'/': () => {
|
'/': () => {
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ const setup = async () => {
|
|||||||
times.value = await useSupabaseSelect("times","*, profile(*), project(id, name)")
|
times.value = await useSupabaseSelect("times","*, profile(*), project(id, name)")
|
||||||
projects.value = await useSupabaseSelect("projects","*")
|
projects.value = await useSupabaseSelect("projects","*")
|
||||||
|
|
||||||
if(await useCapacitor().getIsPhone()) {
|
|
||||||
platform.value = "mobile"
|
|
||||||
setPageLayout("mobile")
|
|
||||||
}
|
|
||||||
|
|
||||||
runningTimeInfo.value = (await supabase
|
runningTimeInfo.value = (await supabase
|
||||||
.from("times")
|
.from("times")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ definePageMeta({
|
|||||||
middleware: [], // Keine Auth-Checks durch Nuxt
|
middleware: [], // Keine Auth-Checks durch Nuxt
|
||||||
auth: false // Falls du das nuxt-auth Modul nutzt
|
auth: false // Falls du das nuxt-auth Modul nutzt
|
||||||
})
|
})
|
||||||
|
const config = useRuntimeConfig()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const token = route.params.token
|
const token = route.params.token
|
||||||
const { $api } = useNuxtApp() // Dein Fetch-Wrapper
|
const { $api } = useNuxtApp() // Dein Fetch-Wrapper
|
||||||
@@ -27,7 +27,7 @@ const loadContext = async () => {
|
|||||||
|
|
||||||
// Abruf an dein Fastify Backend
|
// Abruf an dein Fastify Backend
|
||||||
// Pfad evtl. anpassen, wenn du Proxy nutzt
|
// Pfad evtl. anpassen, wenn du Proxy nutzt
|
||||||
const res = await $fetch(`http://localhost:3100/workflows/context/${token}`, { headers })
|
const res = await $fetch(`${config.public.apiBase}/workflows/context/${token}`, { headers })
|
||||||
|
|
||||||
context.value = res
|
context.value = res
|
||||||
status.value = 'ready'
|
status.value = 'ready'
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import {Preferences} from "@capacitor/preferences";
|
|
||||||
|
|
||||||
export default defineNuxtPlugin(() => {
|
export default defineNuxtPlugin(() => {
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
@@ -9,12 +8,9 @@ export default defineNuxtPlugin(() => {
|
|||||||
async onRequest({options}) {
|
async onRequest({options}) {
|
||||||
// Token aus Cookie holen
|
// Token aus Cookie holen
|
||||||
let token: string | null | undefined = ""
|
let token: string | null | undefined = ""
|
||||||
if (useCapacitor().getIsNative()) {
|
|
||||||
const {value} = await Preferences.get({key: 'token'});
|
token = useCookie("token").value
|
||||||
token = value
|
|
||||||
} else {
|
|
||||||
token = useCookie("token").value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Falls im Request explizit ein anderer JWT übergeben wird → diesen verwenden
|
// Falls im Request explizit ein anderer JWT übergeben wird → diesen verwenden
|
||||||
|
|||||||
@@ -16,32 +16,36 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
async persist(token) {
|
async persist(token) {
|
||||||
if(useCapacitor().getIsNative()) {
|
|
||||||
console.log("On Native")
|
|
||||||
await Preferences.set({
|
|
||||||
key:"token",
|
|
||||||
value: token,
|
|
||||||
})
|
|
||||||
useCookie("token").value = token // persistieren
|
|
||||||
|
|
||||||
} else {
|
console.log("On Web")
|
||||||
console.log("On Web")
|
useCookie("token").value = token // persistieren
|
||||||
useCookie("token").value = token // persistieren
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async initStore() {
|
async initStore() {
|
||||||
console.log("Auth initStore")
|
console.log("Auth initStore")
|
||||||
await this.fetchMe()
|
|
||||||
|
|
||||||
|
// 1. Check: Haben wir überhaupt ein Token?
|
||||||
|
const token = useCookie("token").value
|
||||||
|
|
||||||
|
/*if (!token) {
|
||||||
|
// Kein Token -> Wir sind fertig, User ist Gast.
|
||||||
|
this.user = null
|
||||||
|
this.loading = false
|
||||||
|
return
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// 2. Token existiert -> Versuche User zu laden
|
||||||
|
await this.fetchMe(token)
|
||||||
|
|
||||||
|
// Wenn fetchMe fertig ist (egal ob Erfolg oder Fehler), ladebalken weg
|
||||||
|
|
||||||
|
|
||||||
|
// Optional: Wenn eingeloggt, leite zur Home, falls gewünscht
|
||||||
if(this.activeTenant > 0) {
|
if(this.activeTenant > 0) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if(useCapacitor().getIsNative()) {
|
// Hier vorsichtig sein: Nicht navigieren, wenn der User auf eine Deep-Link URL will!
|
||||||
navigateTo("/mobile")
|
// navigateTo("/") <-- Das würde ich hier evtl. sogar weglassen und der Middleware überlassen
|
||||||
} else {
|
|
||||||
navigateTo("/")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -51,14 +55,11 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
|
|
||||||
const tempStore = useTempStore()
|
const tempStore = useTempStore()
|
||||||
|
|
||||||
if(this.profile.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config)
|
if(this.profile?.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config)
|
||||||
if(this.activeTenant > 0) {
|
if(this.activeTenant > 0) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if(useCapacitor().getIsNative()) {
|
|
||||||
navigateTo("/mobile")
|
navigateTo("/")
|
||||||
} else {
|
|
||||||
navigateTo("/")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -69,12 +70,34 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
body: { email, password }
|
body: { email, password }
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log("Token: " + token)
|
console.log("Token: " + token)
|
||||||
|
|
||||||
|
// 1. WICHTIG: Token sofort ins Cookie schreiben, damit es persistiert wird
|
||||||
|
const tokenCookie = useCookie("token")
|
||||||
|
tokenCookie.value = token
|
||||||
|
|
||||||
|
// 2. User Daten laden
|
||||||
await this.fetchMe(token)
|
await this.fetchMe(token)
|
||||||
|
|
||||||
|
console.log(this.user)
|
||||||
|
|
||||||
|
// 3. WICHTIG: Jetzt explizit weiterleiten!
|
||||||
|
// Prüfen, ob der User geladen wurde
|
||||||
|
if (this.user) {
|
||||||
|
// Falls Passwort-Änderung erzwungen wird (passend zu deiner Middleware)
|
||||||
|
if (this.user.must_change_password) {
|
||||||
|
return navigateTo("/password-change")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normaler Login -> Dashboard
|
||||||
|
return navigateTo("/")
|
||||||
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("login error:" + e)
|
console.log("login error:" + e)
|
||||||
|
// Hier könnte man noch eine Fehlermeldung im UI anzeigen
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async logout() {
|
async logout() {
|
||||||
@@ -82,34 +105,44 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
try {
|
try {
|
||||||
await useNuxtApp().$api("/auth/logout", { method: "POST" })
|
await useNuxtApp().$api("/auth/logout", { method: "POST" })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Logout fehlgeschlagen:", e)
|
console.error("Logout API fehlgeschlagen (egal):", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// State resetten
|
||||||
|
this.resetState()
|
||||||
|
|
||||||
|
// Token löschen
|
||||||
|
useCookie("token").value = null
|
||||||
|
|
||||||
|
// Nur beim expliziten Logout navigieren wir
|
||||||
|
navigateTo("/login")
|
||||||
|
},
|
||||||
|
|
||||||
|
resetState() {
|
||||||
this.user = null
|
this.user = null
|
||||||
this.permissions = []
|
this.permissions = []
|
||||||
this.profile = null
|
this.profile = null
|
||||||
this.activeTenant = null
|
this.activeTenant = null
|
||||||
this.tenants = []
|
this.tenants = []
|
||||||
if(useCapacitor().getIsNative()) {
|
this.activeTenantData = null
|
||||||
await Preferences.remove({ key: 'token' });
|
|
||||||
useCookie("token").value = null
|
|
||||||
} else {
|
|
||||||
useCookie("token").value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateTo("/login")
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchMe(jwt= null) {
|
async fetchMe(jwt= null) {
|
||||||
console.log("Auth fetchMe")
|
console.log("Auth fetchMe")
|
||||||
const tempStore = useTempStore()
|
const tempStore = useTempStore()
|
||||||
|
|
||||||
|
// Token aus Argument oder Cookie holen
|
||||||
|
const tokenToUse = jwt || useCookie("token").value
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const me = await useNuxtApp().$api("/api/me", {
|
const me = await useNuxtApp().$api("/api/me", {
|
||||||
headers: { Authorization: `Bearer ${jwt}`,
|
headers: {
|
||||||
context: {
|
Authorization: `Bearer ${tokenToUse}`,
|
||||||
jwt
|
context: { jwt: tokenToUse }
|
||||||
}}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ... (Deine Logik für tenants, sorting etc. bleibt gleich) ...
|
||||||
console.log(me)
|
console.log(me)
|
||||||
this.user = me.user
|
this.user = me.user
|
||||||
this.permissions = me.permissions
|
this.permissions = me.permissions
|
||||||
@@ -122,19 +155,24 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
|
|
||||||
this.profile = me.profile
|
this.profile = me.profile
|
||||||
|
|
||||||
if(this.profile.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config)
|
if(this.profile?.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config)
|
||||||
|
|
||||||
if(me.activeTenant > 0) {
|
if(me.activeTenant > 0) {
|
||||||
this.activeTenant = me.activeTenant
|
this.activeTenant = me.activeTenant
|
||||||
this.activeTenantData = me.tenants.find(i => i.id === me.activeTenant)
|
this.activeTenantData = me.tenants.find(i => i.id === me.activeTenant)
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(this)
|
||||||
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err?.response?.status === 401) this.logout()
|
// WICHTIG: Hier NICHT this.logout() aufrufen, weil das navigiert!
|
||||||
|
console.log("fetchMe failed (Invalid Token or Network)", err)
|
||||||
|
|
||||||
|
// Stattdessen nur den State sauber machen und Token löschen
|
||||||
|
this.resetState()
|
||||||
|
useCookie("token").value = null
|
||||||
|
|
||||||
|
// Wir werfen den Fehler nicht weiter, damit initStore normal durchläuft
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -149,15 +187,10 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
|
|
||||||
const {token} = res
|
const {token} = res
|
||||||
|
|
||||||
if(useCapacitor().getIsNative()) {
|
|
||||||
await Preferences.set({
|
|
||||||
key:"token",
|
|
||||||
value: token,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
useCookie("token").value = token // persistieren
|
|
||||||
|
|
||||||
}
|
useCookie("token").value = token // persistieren
|
||||||
|
|
||||||
|
|
||||||
await this.init(token)
|
await this.init(token)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const useProfileStore = defineStore('profile', () => {
|
|||||||
let profiles = (await supabase.from("profiles").select("*, role(*)")).data
|
let profiles = (await supabase.from("profiles").select("*, role(*)")).data
|
||||||
let activeProfileConnection = profileconnections.find(i => i.active)
|
let activeProfileConnection = profileconnections.find(i => i.active)
|
||||||
if(activeProfileConnection) {
|
if(activeProfileConnection) {
|
||||||
if(!await useCapacitor().getIsPhone()) {
|
if(!false) {
|
||||||
toast.add({title: 'Aktives Profil ausgewählt'})
|
toast.add({title: 'Aktives Profil ausgewählt'})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||