import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useMutation, useQuery } from "@tanstack/react-query"; import { Box, Card, CardContent, Typography, Button, Chip, Grid, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Alert, CircularProgress, Tooltip, LinearProgress, Divider, Switch, FormControlLabel, } from "@mui/material"; import { Refresh as RefreshIcon, Info as InfoIcon, Warning as WarningIcon, Schedule as ScheduleIcon, Autorenew as RenewIcon, } from "@mui/icons-material"; import * as Icons from "@mui/icons-material"; import { useModules } from "../contexts/ModuleContext"; import { moduleService } from "../services/moduleService"; import type { ModuleDto } from "../types/module"; import { formatPrice, formatDate, getDaysRemainingText, getSubscriptionStatusColor, getSubscriptionStatusText, } from "../types/module"; export default function ModulesAdminPage() { const navigate = useNavigate(); const { modules, isLoading, refreshModules } = useModules(); const [selectedModule, setSelectedModule] = useState(null); const [confirmDisable, setConfirmDisable] = useState(null); // Query per moduli in scadenza const { data: expiringModules = [] } = useQuery({ queryKey: ["modules", "expiring"], queryFn: () => moduleService.getExpiring(30), }); // Mutation per disattivare modulo const disableMutation = useMutation({ mutationFn: (code: string) => moduleService.disable(code), onSuccess: () => { refreshModules(); setConfirmDisable(null); }, }); // Mutation per rinnovare subscription const renewMutation = useMutation({ mutationFn: (code: string) => moduleService.renewSubscription(code), onSuccess: () => { refreshModules(); }, }); // Mutation per controllare scadenze const checkExpiredMutation = useMutation({ mutationFn: () => moduleService.checkExpired(), onSuccess: () => { refreshModules(); }, }); // Helper per ottenere icona modulo const getModuleIcon = (iconName?: string) => { if (!iconName) return ; const IconComponent = (Icons as Record)[ iconName.replace(/\s+/g, "") ]; return IconComponent ? : ; }; if (isLoading) { return ( ); } return ( {/* Header */} Gestione Moduli Configura i moduli attivi e gestisci le subscription {/* Alert moduli in scadenza */} {expiringModules.length > 0 && ( }> {expiringModules.length} modulo/i in scadenza nei prossimi 30 giorni: {expiringModules.map((m) => ( ))} )} {/* Griglia moduli */} {modules.map((module) => ( { if (module.isEnabled && !module.isCore) { setConfirmDisable(module.code); } else if (!module.isEnabled) { navigate(`/modules/purchase/${module.code}`); } }} onInfo={() => setSelectedModule(module)} onRenew={() => renewMutation.mutate(module.code)} isRenewing={renewMutation.isPending} getIcon={getModuleIcon} /> ))} {/* Dialog dettagli modulo */} setSelectedModule(null)} maxWidth="sm" fullWidth > {selectedModule && ( <> {getModuleIcon(selectedModule.icon)} {selectedModule.name} {selectedModule.description} Prezzo annuale {formatPrice(selectedModule.basePrice)} Prezzo mensile {formatPrice(selectedModule.monthlyPrice)} {selectedModule.dependencies.length > 0 && ( Dipendenze {selectedModule.dependencies.map((dep) => ( ))} )} {selectedModule.subscription && ( <> Dettagli Subscription Tipo {selectedModule.subscription.subscriptionTypeName} Stato Data inizio {formatDate(selectedModule.subscription.startDate)} Data scadenza {formatDate(selectedModule.subscription.endDate)} Giorni rimanenti {getDaysRemainingText( selectedModule.subscription.daysRemaining, )} Rinnovo automatico {selectedModule.subscription.autoRenew ? "Sì" : "No"} )} )} {/* Dialog conferma disattivazione */} setConfirmDisable(null)} maxWidth="xs" fullWidth > Conferma disattivazione Sei sicuro di voler disattivare il modulo{" "} {modules.find((m) => m.code === confirmDisable)?.name} ? I dati inseriti rimarranno nel sistema ma non saranno più accessibili fino alla riattivazione. {disableMutation.isError && ( {(disableMutation.error as Error)?.message || "Errore durante la disattivazione"} )} ); } // Componente Card singolo modulo interface ModuleCardProps { module: ModuleDto; onToggle: () => void; onInfo: () => void; onRenew: () => void; isRenewing: boolean; getIcon: (iconName?: string) => React.ReactNode; } function ModuleCard({ module, onToggle, onInfo, onRenew, isRenewing, getIcon, }: ModuleCardProps) { const statusColor = getSubscriptionStatusColor(module.subscription); const statusText = getSubscriptionStatusText(module.subscription); return ( {/* Header */} {getIcon(module.icon)} {module.name} {module.isCore ? ( ) : ( )} {/* Descrizione */} {module.description} {/* Info subscription */} {module.subscription && module.isEnabled && ( Scadenza: {formatDate(module.subscription.endDate)} {module.subscription.daysRemaining !== undefined && module.subscription.daysRemaining <= 30 && ( )} )} {/* Prezzo */} {formatPrice(module.basePrice)} /anno {/* Actions */} {module.isEnabled && !module.isCore && module.subscription?.isExpiringSoon && ( {isRenewing ? : } )} {!module.isCore && ( } label={module.isEnabled ? "Attivo" : "Disattivo"} labelPlacement="start" /> )} ); }