import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" import { apiClient } from "@/lib/api-client" // --- Constants --- const CLUB_ID = "00000000-0000-0000-0000-000000000001" // --- Types --- export type DocumentCategory = | "SATZUNG" | "PROTOKOLL" | "VERTRAG" | "VERSICHERUNG" | "GENEHMIGUNG" | "SONSTIGES" export type DocumentAccessLevel = "ALL_MEMBERS" | "BOARD_ONLY" export interface ClubDocument { id: string title: string category: DocumentCategory filename: string contentType: string fileSize: number accessLevel: DocumentAccessLevel description: string | null uploadedBy: string createdAt: string updatedAt: string | null } export interface StorageUsage { bytesUsed: number } export interface UploadDocumentRequest { title: string category: DocumentCategory accessLevel: DocumentAccessLevel description: string | null file: File } // --- Raw API functions --- export async function uploadDocument( clubId: string, title: string, category: DocumentCategory, accessLevel: DocumentAccessLevel, description: string | null, file: File ): Promise { const formData = new FormData() formData.append("file", file) const params = new URLSearchParams({ clubId, title, category, accessLevel, }) if (description) params.append("description", description) // Multipart upload — use raw fetch since apiClient assumes JSON const res = await fetch( `/api/backend/documents/upload?${params.toString()}`, { method: "POST", body: formData, } ) if (!res.ok) { if (res.status === 402) { const problem = await res.json() const error = new Error("Storage quota exceeded") as Error & { status: number problemDetail: unknown } error.status = 402 error.problemDetail = problem throw error } throw new Error("Upload failed") } return res.json() } export function listDocuments( clubId: string, category?: DocumentCategory, accessLevel?: DocumentAccessLevel ): Promise { const params = new URLSearchParams({ clubId }) if (category) params.append("category", category) if (accessLevel) params.append("accessLevel", accessLevel) return apiClient(`/documents?${params.toString()}`) } export async function downloadDocument(id: string): Promise { const res = await fetch(`/api/backend/documents/${id}/download`) if (!res.ok) throw new Error("Download failed") return res.blob() } export function deleteDocument(id: string, clubId: string): Promise { return apiClient(`/documents/${id}?clubId=${clubId}`, { method: "DELETE", }) } export function getStorageUsage(clubId: string): Promise { return apiClient(`/documents/usage?clubId=${clubId}`) } export function getPortalDocuments(clubId: string): Promise { return apiClient(`/portal/documents?clubId=${clubId}`) } // --- React Query Hooks --- export function useDocumentsQuery(category?: DocumentCategory) { return useQuery({ queryKey: ["documents", CLUB_ID, category], queryFn: () => listDocuments(CLUB_ID, category), }) } export function useUploadDocumentMutation() { const queryClient = useQueryClient() return useMutation({ mutationFn: (data: UploadDocumentRequest) => uploadDocument( CLUB_ID, data.title, data.category, data.accessLevel, data.description, data.file ), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["documents"] }) }, }) } export function useDeleteDocumentMutation() { const queryClient = useQueryClient() return useMutation({ mutationFn: (id: string) => deleteDocument(id, CLUB_ID), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["documents"] }) }, }) } // --- Helper: format file size --- export function formatFileSize(bytes: number): string { if (bytes < 1024) return `${bytes} B` if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB` return `${(bytes / (1024 * 1024)).toFixed(1)} MB` } // --- Category labels --- export const categoryLabels: Record = { SATZUNG: "Satzung", PROTOKOLL: "Protokoll", VERTRAG: "Vertrag", VERSICHERUNG: "Versicherung", GENEHMIGUNG: "Genehmigung", SONSTIGES: "Sonstiges", }