feat(time): add span-based attendance tracking under 2.0
This commit is contained in:
@@ -34,6 +34,8 @@ export type TenantProfile = {
|
||||
};
|
||||
|
||||
export type StaffTimeSpan = {
|
||||
paused?: boolean;
|
||||
model?: string;
|
||||
id: string | null;
|
||||
eventIds: string[];
|
||||
state: string;
|
||||
@@ -608,8 +610,22 @@ export async function fetchStaffTimeSpans(
|
||||
const query = targetUserId ? `?targetUserId=${encodeURIComponent(targetUserId)}` : '';
|
||||
const spans = await apiRequest<any[]>(`/api/staff/time/spans${query}`, { token });
|
||||
|
||||
return (spans || [])
|
||||
const seen = new Set<string>();
|
||||
return (spans || []).filter((span) => {
|
||||
if (span.model !== 'spans-v2') return true;
|
||||
if (seen.has(span.id)) return false;
|
||||
seen.add(span.id); return true;
|
||||
})
|
||||
.map((span) => {
|
||||
if (span.attendance) {
|
||||
const s = span.attendance;
|
||||
const end = s.ended_at ? Date.parse(s.ended_at) : Date.now();
|
||||
const pauseMs = s.breaks.reduce((n: number, p: any) => n + ((p.ended_at ? Date.parse(p.ended_at) : end) - Date.parse(p.started_at)), 0);
|
||||
return { id: s.id, eventIds: [s.id], state: s.status, started_at: s.started_at,
|
||||
stopped_at: s.ended_at, duration_minutes: Math.floor((end - Date.parse(s.started_at) - pauseMs) / 60000),
|
||||
user_id: s.user_id, type: s.type, description: s.description,
|
||||
paused: s.breaks.some((p: any) => !p.ended_at), model: 'spans-v2' } as StaffTimeSpan;
|
||||
}
|
||||
const started = span.startedAt ? new Date(span.startedAt) : null;
|
||||
const ended = span.endedAt ? new Date(span.endedAt) : new Date();
|
||||
const durationMinutes =
|
||||
|
||||
Reference in New Issue
Block a user