Fixed Times
This commit is contained in:
@@ -7,7 +7,20 @@ export const useFunctions = () => {
|
||||
const supabase = useSupabaseClient()
|
||||
|
||||
const getWorkingTimesEvaluationData = async (user_id, startDate, endDate) => {
|
||||
return (await useNuxtApp().$api(`/api/functions/timeevaluation/${user_id}?start_date=${startDate}&end_date=${endDate}`))
|
||||
// Der neue Endpunkt ist /staff/time/evaluation und erwartet die Benutzer-ID als targetUserId Query-Parameter.
|
||||
|
||||
// Wir bauen den Query-String zusammen.
|
||||
const queryParams = new URLSearchParams({
|
||||
from: startDate,
|
||||
to: endDate,
|
||||
targetUserId: user_id, // Die ID wird als targetUserId übergeben
|
||||
});
|
||||
|
||||
// Der neue API-Pfad verwendet nur noch den Basis-Endpunkt.
|
||||
const url = `/api/staff/time/evaluation?${queryParams.toString()}`;
|
||||
|
||||
// Annahme: useNuxtApp().$api führt den GET-Request aus und liefert die Daten zurück.
|
||||
return (await useNuxtApp().$api(url));
|
||||
}
|
||||
|
||||
const useNextNumber = async (numberRange) => {
|
||||
|
||||
@@ -1,77 +1,160 @@
|
||||
interface StaffTimeEntry {
|
||||
id: string
|
||||
started_at: string
|
||||
stopped_at?: string | null
|
||||
duration_minutes?: number | null
|
||||
type: string
|
||||
description?: string | null
|
||||
created_at?: string
|
||||
}
|
||||
import { defineStore } from 'pinia'
|
||||
import { useAuthStore } from '~/stores/auth'
|
||||
|
||||
export function useStaffTime() {
|
||||
const { $api } = useNuxtApp()
|
||||
export const useStaffTime = () => {
|
||||
const { $api, $dayjs } = useNuxtApp()
|
||||
const auth = useAuthStore()
|
||||
|
||||
/**
|
||||
* Lädt die Zeitspannen (Spans) für die Liste.
|
||||
* Nutzt jetzt GET /api/staff/time/spans
|
||||
*/
|
||||
const list = async (filter?: { user_id?: string, from?: string, to?: string }) => {
|
||||
// Standard: Aktueller Monat
|
||||
const from = filter?.from || $dayjs().startOf('month').format('YYYY-MM-DD')
|
||||
const to = filter?.to || $dayjs().endOf('month').format('YYYY-MM-DD')
|
||||
|
||||
// Ziel-User: Entweder aus Filter (Admin-Ansicht) oder eigener User
|
||||
const targetUserId = filter?.user_id || auth.user.id
|
||||
|
||||
async function list(params?: { user_id?: string }) {
|
||||
const query = new URLSearchParams()
|
||||
if (params?.user_id) query.append("user_id", params.user_id)
|
||||
|
||||
return await $api(`/api/staff/time${query.toString() ? `?${query}` : ''}`, { method: 'GET' })
|
||||
}
|
||||
|
||||
async function start(description?: string) {
|
||||
return await $api<StaffTimeEntry>('/api/staff/time', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
started_at: new Date().toISOString(),
|
||||
type: 'work',
|
||||
description,
|
||||
},
|
||||
const params = new URLSearchParams({
|
||||
from,
|
||||
to,
|
||||
// Der Endpoint erwartet targetUserId, wenn man Daten eines anderen Users will
|
||||
targetUserId
|
||||
})
|
||||
|
||||
try {
|
||||
// 💡 UPDATE: Prefix /api hinzugefügt
|
||||
const spans = await $api(`/api/staff/time/spans?${params.toString()}`)
|
||||
|
||||
return (spans || []).map((span: any) => {
|
||||
const start = $dayjs(span.startedAt)
|
||||
// Wenn endedAt null ist, läuft die Zeit noch -> Dauer bis "jetzt" berechnen für Anzeige
|
||||
const end = span.endedAt ? $dayjs(span.endedAt) : $dayjs()
|
||||
const duration = end.diff(start, 'minute')
|
||||
|
||||
return {
|
||||
// ID: Wir nehmen die erste Event-ID (Start-Event) als Referenz für Aktionen
|
||||
id: span.sourceEventIds && span.sourceEventIds.length > 0 ? span.sourceEventIds[0] : null,
|
||||
|
||||
// Mapping Backend-Status -> Frontend-State
|
||||
state: span.status,
|
||||
|
||||
// Zeitstempel
|
||||
started_at: span.startedAt,
|
||||
stopped_at: span.endedAt,
|
||||
|
||||
duration_minutes: duration,
|
||||
|
||||
// Da der Endpoint nur die Spans zurückgibt, setzen wir die UserID
|
||||
// auf den User, den wir angefragt haben.
|
||||
user_id: targetUserId,
|
||||
|
||||
type: span.type,
|
||||
|
||||
// Payload/Description falls vorhanden
|
||||
description: span.payload?.description || ''
|
||||
}
|
||||
}).sort((a: any, b: any) => $dayjs(b.started_at).valueOf() - $dayjs(a.started_at).valueOf()) // Sortierung: Neueste oben
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Laden der Zeiten:", error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
async function stop(id: string) {
|
||||
return await $api<StaffTimeEntry>(`/api/staff/time/${id}/stop`, {
|
||||
method: 'PUT',
|
||||
body: { stopped_at: new Date().toISOString() },
|
||||
})
|
||||
/**
|
||||
* Startet einen neuen Zeiteintrag.
|
||||
* POST /api/staff/time/event
|
||||
*/
|
||||
const start = async (description = "Arbeitszeit") => {
|
||||
try {
|
||||
// 💡 UPDATE: Prefix /api hinzugefügt
|
||||
await $api('/api/staff/time/event', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
eventtype: 'work_start',
|
||||
eventtime: new Date().toISOString(),
|
||||
payload: { description }
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Starten:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function submit(id: string) {
|
||||
return await $api<StaffTimeEntry>(`/api/staff/time/${id}`, {
|
||||
method: 'PUT',
|
||||
body: { state: 'submitted' },
|
||||
})
|
||||
/**
|
||||
* Stoppt die aktuelle Zeit.
|
||||
* POST /api/staff/time/event
|
||||
*/
|
||||
const stop = async (entryId?: string) => {
|
||||
try {
|
||||
// 💡 UPDATE: Prefix /api hinzugefügt
|
||||
await $api('/api/staff/time/event', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
eventtype: 'work_end',
|
||||
eventtime: new Date().toISOString()
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Stoppen:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function approve(id: string) {
|
||||
const auth = useAuthStore()
|
||||
const now = useNuxtApp().$dayjs().toISOString()
|
||||
|
||||
return await $api(`/api/staff/time/${id}`, {
|
||||
method: 'PUT',
|
||||
body: {
|
||||
state: 'approved',
|
||||
//@ts-ignore
|
||||
approved_by: auth.user.id,
|
||||
approved_at: now,
|
||||
},
|
||||
})
|
||||
/**
|
||||
* Reicht einen Eintrag ein.
|
||||
* POST /api/staff/time/submit
|
||||
*/
|
||||
const submit = async (entryId: string) => {
|
||||
if (!entryId) return
|
||||
try {
|
||||
// 💡 UPDATE: Prefix /api hinzugefügt
|
||||
await $api('/api/staff/time/submit', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
eventIds: [entryId]
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Einreichen:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function get(id: string) {
|
||||
return await $api<StaffTimeEntry>(`/api/staff/time/${id}`, { method: 'GET' })
|
||||
/**
|
||||
* Genehmigt einen Eintrag.
|
||||
* POST /api/staff/time/approve
|
||||
*/
|
||||
const approve = async (entry: any) => {
|
||||
if (!entry || !entry.id || !entry.user_id) {
|
||||
console.error("Ungültiger Eintrag für Genehmigung (ID oder UserID fehlt)", entry)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 💡 UPDATE: Prefix /api hinzugefügt
|
||||
await $api('/api/staff/time/approve', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
eventIds: [entry.id],
|
||||
employeeUserId: entry.user_id
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Genehmigen:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function create(data: Record<string, any>) {
|
||||
return await $api('/api/staff/time', { method: 'POST', body: data })
|
||||
return {
|
||||
list,
|
||||
start,
|
||||
stop,
|
||||
submit,
|
||||
approve
|
||||
}
|
||||
|
||||
async function update(id: string, data: Record<string, any>) {
|
||||
return await $api(`/api/staff/time/${id}`, { method: 'PUT', body: data })
|
||||
}
|
||||
|
||||
return { list, start, stop,submit,approve, get, create, update }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user