import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Box, Button, Card, CardContent, CardMedia, CardActions, Grid, Typography, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, FormControl, InputLabel, Select, MenuItem, Chip, Tooltip, CircularProgress, useMediaQuery, useTheme, Stack, Fab, Zoom, } from "@mui/material"; import { Add as AddIcon, Edit as EditIcon, Delete as DeleteIcon, ContentCopy as CopyIcon, Download as DownloadIcon, Upload as UploadIcon, Description as DescriptionIcon, } from "@mui/icons-material"; import { reportTemplateService, downloadBlob } from "../services/reportService"; import type { ReportTemplateDto } from "../types/report"; export default function ReportTemplatesPage() { const navigate = useNavigate(); const queryClient = useQueryClient(); const theme = useTheme(); // Breakpoints const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [filterCategoria, setFilterCategoria] = useState(""); const [deleteDialog, setDeleteDialog] = useState<{ open: boolean; template: ReportTemplateDto | null; }>({ open: false, template: null, }); const [importDialog, setImportDialog] = useState(false); const [importFile, setImportFile] = useState(null); const { data: templates = [], isLoading } = useQuery({ queryKey: ["report-templates", filterCategoria], queryFn: () => reportTemplateService.getAll(filterCategoria || undefined), }); const { data: categories = [] } = useQuery({ queryKey: ["report-template-categories"], queryFn: () => reportTemplateService.getCategories(), }); const deleteMutation = useMutation({ mutationFn: (id: number) => reportTemplateService.delete(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["report-templates"] }); setDeleteDialog({ open: false, template: null }); }, }); const cloneMutation = useMutation({ mutationFn: (id: number) => reportTemplateService.clone(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["report-templates"] }); }, }); const importMutation = useMutation({ mutationFn: (file: File) => reportTemplateService.import(file), onSuccess: (newTemplate) => { queryClient.invalidateQueries({ queryKey: ["report-templates"] }); setImportDialog(false); setImportFile(null); navigate(`/report-editor/${newTemplate.id}`); }, }); const handleExport = async (template: ReportTemplateDto) => { const blob = await reportTemplateService.export(template.id); downloadBlob(blob, `${template.nome.replace(/\s+/g, "_")}.aprt`); }; const handleImport = () => { if (importFile) { importMutation.mutate(importFile); } }; const getCategoriaColor = ( categoria: string, ): | "default" | "primary" | "secondary" | "success" | "warning" | "error" | "info" => { const colors: Record< string, | "default" | "primary" | "secondary" | "success" | "warning" | "error" | "info" > = { Evento: "primary", Cliente: "secondary", Articoli: "success", Generale: "default", Importato: "warning", }; return colors[categoria] || "default"; }; if (isLoading) { return ( ); } return ( {/* Header */} Template Report {/* Desktop/Tablet buttons */} {!isMobile && ( )} {/* Filter */} Filtra per categoria {/* Mobile import button inline with filter */} {isMobile && ( )} {/* Empty State */} {templates.length === 0 ? ( Nessun template trovato Crea il tuo primo template di report o importane uno esistente ) : ( /* Template Grid */ {templates.map((template) => ( {/* Thumbnail */} {template.thumbnailBase64 ? ( ) : ( )} {/* Content */} {template.nome} {template.descrizione && ( {template.descrizione} )} {template.pageSize} -{" "} {template.orientation === "portrait" ? "Verticale" : "Orizzontale"} {/* Actions */} navigate(`/report-editor/${template.id}`) } > cloneMutation.mutate(template.id)} > handleExport(template)} > setDeleteDialog({ open: true, template })} > ))} )} {/* Mobile FAB */} {isMobile && ( navigate("/report-editor")} sx={{ position: "fixed", bottom: 16, right: 16, zIndex: 1000, }} > )} {/* Delete Dialog */} setDeleteDialog({ open: false, template: null })} fullWidth maxWidth="xs" fullScreen={isMobile} > Conferma Eliminazione Sei sicuro di voler eliminare il template " {deleteDialog.template?.nome}"? Questa azione non può essere annullata. {/* Import Dialog */} { setImportDialog(false); setImportFile(null); }} fullWidth maxWidth="xs" fullScreen={isMobile} > Importa Template Seleziona un file .aprt da importare ); }