first commit
Deploy / lint (push) Failing after 7s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped

This commit is contained in:
Dennis Thiessen
2026-02-20 17:31:01 +01:00
commit 61ab24490d
160 changed files with 17034 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import * as adminApi from '../api/admin';
import { useToast } from '../components/ui/Toast';
// ── Users ──
export function useUsers() {
return useQuery({
queryKey: ['admin', 'users'],
queryFn: () => adminApi.listUsers(),
});
}
export function useCreateUser() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: (data: {
username: string;
password: string;
role: string;
has_access: boolean;
}) => adminApi.createUser(data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'users'] });
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to create user');
},
});
}
export function useUpdateAccess() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: ({ userId, hasAccess }: { userId: number; hasAccess: boolean }) =>
adminApi.updateAccess(userId, hasAccess),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'users'] });
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to update access');
},
});
}
export function useResetPassword() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: ({ userId, password }: { userId: number; password: string }) =>
adminApi.resetPassword(userId, password),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'users'] });
addToast('success', 'Password reset successfully');
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to reset password');
},
});
}
// ── Settings ──
export function useSettings() {
return useQuery({
queryKey: ['admin', 'settings'],
queryFn: () => adminApi.listSettings(),
});
}
export function useUpdateSetting() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: ({ key, value }: { key: string; value: string }) =>
adminApi.updateSetting(key, value),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'settings'] });
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to update setting');
},
});
}
// ── Jobs ──
export function useJobs() {
return useQuery({
queryKey: ['admin', 'jobs'],
queryFn: () => adminApi.listJobs(),
refetchInterval: 15_000,
});
}
export function useToggleJob() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: ({ jobName, enabled }: { jobName: string; enabled: boolean }) =>
adminApi.toggleJob(jobName, enabled),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'jobs'] });
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to toggle job');
},
});
}
export function useTriggerJob() {
const qc = useQueryClient();
const { addToast } = useToast();
return useMutation({
mutationFn: (jobName: string) => adminApi.triggerJob(jobName),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'jobs'] });
addToast('success', 'Job triggered successfully');
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to trigger job');
},
});
}
// ── Data Cleanup ──
export function useCleanupData() {
const { addToast } = useToast();
return useMutation({
mutationFn: (olderThanDays: number) => adminApi.cleanupData(olderThanDays),
onSuccess: (data) => {
addToast('success', (data as { message: string }).message || 'Cleanup completed');
},
onError: (error: Error) => {
addToast('error', error.message || 'Failed to cleanup data');
},
});
}