mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 21:53:41 +00:00
refactor: migrate ReportsPage to TanStack Query
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
29b54e58a2
commit
150be9183c
2 changed files with 54 additions and 43 deletions
38
frontend/src/hooks/useReports.ts
Normal file
38
frontend/src/hooks/useReports.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import api from '@/services/api'
|
||||
import type { ReportMeta } from '@/types'
|
||||
|
||||
interface ReportsListResponse {
|
||||
items: ReportMeta[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export function useReports() {
|
||||
return useQuery({
|
||||
queryKey: ['reports'],
|
||||
queryFn: () =>
|
||||
api.get<ReportsListResponse>('/reports/list').then(r => r.data),
|
||||
})
|
||||
}
|
||||
|
||||
export function useGenerateReport() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (params: { jahr: number; kw: number }) =>
|
||||
api.post<ReportMeta>('/reports/generate', null, { params }).then(r => r.data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reports'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDeleteReports() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (ids: number[]) =>
|
||||
api.delete('/reports/delete', { data: ids }),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['reports'] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { Download, FileSpreadsheet, Loader2, Plus, Trash2 } from 'lucide-react'
|
||||
import api from '@/services/api'
|
||||
import type { ReportMeta } from '@/types'
|
||||
import { useAuth } from '@/context/AuthContext'
|
||||
import { useReports, useGenerateReport, useDeleteReports } from '@/hooks/useReports'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
|
|
@ -19,54 +19,31 @@ export function ReportsPage() {
|
|||
const currentYear = new Date().getFullYear()
|
||||
const currentKw = getISOWeek(new Date())
|
||||
|
||||
const [reports, setReports] = useState<ReportMeta[]>([])
|
||||
const [totalReports, setTotalReports] = useState(0)
|
||||
const [loading, setLoading] = useState(true)
|
||||
// TanStack Query hooks
|
||||
const { data, isLoading: loading } = useReports()
|
||||
const reports = data?.items ?? []
|
||||
const totalReports = data?.total ?? 0
|
||||
|
||||
const generateMutation = useGenerateReport()
|
||||
const deleteMutation = useDeleteReports()
|
||||
|
||||
// Report generation state
|
||||
const [genJahr, setGenJahr] = useState(currentYear)
|
||||
const [genKw, setGenKw] = useState(currentKw)
|
||||
const [generating, setGenerating] = useState(false)
|
||||
const [genError, setGenError] = useState('')
|
||||
const [genSuccess, setGenSuccess] = useState('')
|
||||
|
||||
// Selection state for deletion
|
||||
const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set())
|
||||
const [deleting, setDeleting] = useState(false)
|
||||
|
||||
// Fetch reports list
|
||||
const fetchReports = () => {
|
||||
setLoading(true)
|
||||
api.get<{ items: ReportMeta[]; total: number }>('/reports/list')
|
||||
.then((res) => {
|
||||
setReports(res.data.items)
|
||||
setTotalReports(res.data.total)
|
||||
})
|
||||
.catch(() => {
|
||||
setReports([])
|
||||
setTotalReports(0)
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchReports()
|
||||
}, [])
|
||||
|
||||
const generateReport = async () => {
|
||||
setGenerating(true)
|
||||
setGenError('')
|
||||
setGenSuccess('')
|
||||
try {
|
||||
const res = await api.post<ReportMeta>('/reports/generate', null, {
|
||||
params: { jahr: genJahr, kw: genKw },
|
||||
})
|
||||
setGenSuccess(`Bericht für KW ${res.data.kw}/${res.data.jahr} wurde generiert.`)
|
||||
fetchReports()
|
||||
const result = await generateMutation.mutateAsync({ jahr: genJahr, kw: genKw })
|
||||
setGenSuccess(`Bericht für KW ${result.kw}/${result.jahr} wurde generiert.`)
|
||||
} catch {
|
||||
setGenError('Fehler beim Generieren des Berichts.')
|
||||
} finally {
|
||||
setGenerating(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,15 +99,11 @@ export function ReportsPage() {
|
|||
|
||||
const deleteSelected = async () => {
|
||||
if (selectedIds.size === 0) return
|
||||
setDeleting(true)
|
||||
try {
|
||||
await api.delete('/reports/delete', { data: Array.from(selectedIds) })
|
||||
await deleteMutation.mutateAsync(Array.from(selectedIds))
|
||||
setSelectedIds(new Set())
|
||||
fetchReports()
|
||||
} catch {
|
||||
setGenError('Fehler beim Löschen der Berichte.')
|
||||
} finally {
|
||||
setDeleting(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,8 +146,8 @@ export function ReportsPage() {
|
|||
max={53}
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={generateReport} disabled={generating}>
|
||||
{generating ? (
|
||||
<Button onClick={generateReport} disabled={generateMutation.isPending}>
|
||||
{generateMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Wird generiert...
|
||||
|
|
@ -213,9 +186,9 @@ export function ReportsPage() {
|
|||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={deleteSelected}
|
||||
disabled={deleting}
|
||||
disabled={deleteMutation.isPending}
|
||||
>
|
||||
{deleting ? (
|
||||
{deleteMutation.isPending ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue