feat(admin): sessions management screen (list + filter + actions)

This commit is contained in:
Bas van Rossem
2026-06-17 22:38:28 +02:00
parent 53c66ee144
commit b5366413b6
6 changed files with 605 additions and 3 deletions

View File

@@ -1,5 +1,9 @@
import { useQuery } from '@tanstack/react-query';
import type { WorkSession } from '@solelog/shared';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import type {
AdminUpdateSessionInput,
CreateManualSessionInput,
WorkSession,
} from '@solelog/shared';
import { apiFetch } from '../lib/api';
// Active work sessions across all workers (admin cross-user view).
@@ -11,3 +15,69 @@ export function useActiveSessions() {
refetchInterval: 5000,
});
}
// Every session (newest first) for the Sessies management screen.
export function useAllSessions() {
return useQuery({
queryKey: ['admin', 'sessions', 'all'],
queryFn: () => apiFetch<WorkSession[]>('/api/admin/sessions'),
});
}
// Roster for the create-form worker picker.
export function useAdminUsers() {
return useQuery({
queryKey: ['admin', 'users'],
queryFn: () => apiFetch<{ id: string; name: string; email: string }[]>('/api/admin/users'),
});
}
export function useCreateManualSession() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (input: CreateManualSessionInput) =>
apiFetch<WorkSession>('/api/admin/sessions', {
method: 'POST',
body: JSON.stringify(input),
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'sessions'] });
},
});
}
export function useUpdateSession() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, input }: { id: number; input: AdminUpdateSessionInput }) =>
apiFetch<WorkSession>(`/api/admin/sessions/${id}`, {
method: 'PUT',
body: JSON.stringify(input),
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'sessions'] });
},
});
}
export function useAdminStopSession() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: number) =>
apiFetch<WorkSession>(`/api/admin/sessions/${id}/stop`, { method: 'POST' }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'sessions'] });
},
});
}
export function useAdminDiscardSession() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: number) =>
apiFetch<WorkSession>(`/api/admin/sessions/${id}/discard`, { method: 'POST' }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'sessions'] });
},
});
}