Add document storage (local filesystem) + fix dashboard outstanding KPI
- Local file storage via STORAGE_PATH env var (replaces DO Spaces) - POST/GET/DELETE /api/cases/:caseId/documents + GET /api/documents/:docId/download - useDocuments hook + upload/list/download/delete UI in CaseDetailPage - GET /api/invoices/summary — live SUM of sent+overdue invoices - Dashboard outstanding KPI wired to real DB value - api.upload() for FormData, formatBytes() utility Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
0700d54225
commit
ce2278f4be
@@ -0,0 +1,40 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { api, type ApiError } from '@/lib/api';
|
||||
|
||||
export interface Document {
|
||||
id: string;
|
||||
name: string;
|
||||
mimeType: string;
|
||||
sizeBytes: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
const KEY = (caseId: string) => ['documents', caseId] as const;
|
||||
|
||||
export function useDocuments(caseId: string | undefined) {
|
||||
return useQuery<Document[]>({
|
||||
queryKey: caseId ? KEY(caseId) : ['documents', 'noop'],
|
||||
queryFn: () => api.get(`/api/cases/${caseId}/documents`),
|
||||
enabled: !!caseId,
|
||||
});
|
||||
}
|
||||
|
||||
export function useUploadDocument(caseId: string) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<Document, ApiError, File>({
|
||||
mutationFn: (file) => {
|
||||
const form = new FormData();
|
||||
form.append('file', file);
|
||||
return api.upload(`/api/cases/${caseId}/documents`, form);
|
||||
},
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: KEY(caseId) }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteDocument(caseId: string) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<void, ApiError, string>({
|
||||
mutationFn: (docId) => api.delete(`/api/documents/${docId}`),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: KEY(caseId) }),
|
||||
});
|
||||
}
|
||||
@@ -90,6 +90,13 @@ function qs(p: ListParams): string {
|
||||
return s ? `?${s}` : '';
|
||||
}
|
||||
|
||||
export function useInvoiceSummary() {
|
||||
return useQuery<{ outstanding: string }>({
|
||||
queryKey: ['invoices', 'summary'],
|
||||
queryFn: () => api.get('/api/invoices/summary'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useInvoices(params: ListParams = {}) {
|
||||
return useQuery<ListResponse>({
|
||||
queryKey: KEY.list(params),
|
||||
|
||||
Reference in New Issue
Block a user