import type { ColumnDef, Table } from "@tanstack/react-table"; import { add, format, formatDuration, intervalToDuration } from "date-fns"; import { it } from "date-fns/locale"; import { CircleCheck, CircleCheckBig, CircleEllipsis, ClockFading, ExternalLink, SearchX, } from "lucide-react"; import Link from "next/link"; import { useRef } from "react"; import toast from "react-hot-toast"; import { NotePopover } from "~/components/notePopover"; import { AnnuncioCardRichieste } from "~/components/servizio/annuncio_card"; import { Badge } from "~/components/ui/badge"; import { Button } from "~/components/ui/button"; import { DataTable } from "~/components/ui/data-table"; import { DataTableColumnHeader } from "~/components/ui/dataTable-header"; import type { PinnedFiltro, SearchFiltro, } from "~/components/ui/dataTable-toolbar"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from "~/components/ui/sheet"; import { Tooltip, TooltipContent, TooltipTrigger, } from "~/components/ui/tooltip"; import { UserAvatar } from "~/components/user_avatar"; import { MutationPageRestore } from "~/lib/tableUtils"; import { cn } from "~/lib/utils"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import type { RichiesteData } from "~/server/controllers/servizio.controller"; import { api } from "~/utils/api"; type RichiesteTableProps = { data: RichiesteData[]; }; export const RichiesteTable = ({ data }: RichiesteTableProps) => { const tabledata = data; const columns_titles = { id: "ID Ordine", username: "Utente", note: "Note", decorrenza: "Decorrenza", status: "Status", tipologia: "Tipo", annunci: "Annunci", interruzione_expires_at: "Scad. interr.", actions: "Azioni", }; const statusOptions = [ { label: "Attesa di attivazione", value: "attesa_attivazione" }, { label: "Acconto pagato", value: "acconto_pagato" }, { label: "Saldo pagato", value: "saldo_pagato" }, { label: "Conferma in corso", value: "conferma" }, ]; const type_options = [ { label: "Transitorio", value: TipologiaPosizioneEnum.Transitorio }, { label: "Stabile", value: TipologiaPosizioneEnum.Stabile }, ]; type Column = (typeof tabledata)[number]; const tableRef = useRef | null>(null); const utils = api.useUtils(); const { onMutate, onSettled } = MutationPageRestore(tableRef); const { mutate, isPending } = api.users.editUser.useMutation({ onMutate, onSettled, onSuccess: async () => { toast.success("Note aggiornate con successo"); await utils.users.invalidate(); await utils.servizio.invalidate(); }, onError: (error) => { toast.error(error.message); }, }); const columns: ColumnDef[] = [ { accessorKey: "id", cell: () => null, enableHiding: false, header: () => null, }, { accessorKey: "username", cell: ({ row }) => { return ( {row.original.username} ); }, enableHiding: false, header: ({ column }) => ( ), }, { accessorKey: "note", cell: ({ row }) => { const note = row.original.note; return ( ); }, header: ({ column }) => ( ), enableSorting: false, }, { accessorKey: "decorrenza", cell: ({ row }) => { let decorrenzaColor = ""; let decorrenzaTooltip = ""; if (!row.original.isOkAcconto || !row.original.decorrenza) { decorrenzaColor = "text-muted-foreground"; decorrenzaTooltip = "Attesa di attivazione"; } else if (row.original.isInterrotto) { decorrenzaColor = "text-destructive"; decorrenzaTooltip = "Servizio interrotto"; } else if (row.original.isOkAcconto && !row.original.isOkSaldo) { decorrenzaColor = "text-warning"; decorrenzaTooltip = "Attesa di saldo"; } return ( {row.original.decorrenza ? format(row.original.decorrenza, "dd/MM") : "---"}

{decorrenzaTooltip}

); }, enableHiding: false, header: ({ column }) => ( ), sortingFn: "datetime", }, { accessorKey: "tipologia", cell: ({ row }) => { const { tipologia } = row.original; return ( {tipologia.toString()} ); }, filterFn: (row, id, value) => { return value.includes(row.getValue(id)); }, header: ({ column }) => ( ), }, { accessorKey: "status", cell: ({ row }) => { let badgeClass = ""; let contents: React.ReactNode; const annunci = row.original.annunci_servizio; const awaitingConferma = annunci.some( (a) => a.user_confirmed_at !== null && !a.hasConfermaAdmin, ); const hasConfermaAdmin = annunci.some((a) => a.hasConfermaAdmin); if (row.original.isInterrotto) { badgeClass = "border-destructive bg-destructive/10 text-destructive"; contents = ( <> Interrotto ); } else if (!row.original.onboardOk) { badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600"; contents = ( <> Attesa attivazione ); } else if (awaitingConferma) { badgeClass = "border-sky-500 bg-sky-500/10 text-sky-500"; contents = ( <> In Conferma ); } else if (row.original.isOkSaldo && hasConfermaAdmin) { badgeClass = "border-blue-500 bg-blue-500/10 text-blue-500"; contents = ( <> Saldo pagato ); } else if (row.original.isOkAcconto) { badgeClass = "border-green-500 bg-green-500/10 text-green-500"; contents = ( <> Attivo ); } return ( svg]:size-4", badgeClass, )} variant="outline" > {contents} ); }, filterFn: (row, id, value) => { return value.includes(row.getValue(id)); }, header: ({ column }) => ( ), }, { accessorKey: "interruzione_expires_at", cell: ({ row }) => { if (row.original.isInterrotto) return "---"; if (!row.original.decorrenza) return "---"; const expiresAt = add(row.original.decorrenza, { days: row.original.interruzioneDays, }); const timeLeft = intervalToDuration({ start: new Date(), end: expiresAt, }); const daysLeft = timeLeft.days || 0; let badgeColor = ""; if (daysLeft > 5) { badgeColor = "border-green-500 bg-green-500/10 text-green-500"; } else if (daysLeft > 0) { badgeColor = "border-yellow-500 bg-yellow-500/10 text-yellow-500"; } else { badgeColor = "border-red-500 bg-red-500/10 text-red-500"; } return ( {format(expiresAt, "dd/MM")} {daysLeft > 0 ? (

{formatDuration(timeLeft, { locale: it, format: ["days"] })}{" "} rimanenti

) : (

Interruzione scaduta

)}
); }, header: ({ column }) => ( ), }, { accessorKey: "annunci_servizio", cell: ({ row }) => { const annunci = row.original.annunci_servizio; return ( // // // // // // // Annunci Inseriti // // Desc // // //
// {annunci.map((a) => ( // // ))} //
//
//
Annunci Inseriti Desc
{annunci.map((a) => ( ))}
); }, header: ({ column }) => ( ), enableSorting: false, }, { cell: ({ row }) => { return ( ); }, enableHiding: false, id: "actions", }, ]; const searchFiltro: SearchFiltro = { columnName: "id", placeholder: "Cerca ordine...", }; const pinnedFiltri: PinnedFiltro[] = [ { columnName: "status", options: statusOptions, title: "Stato Ordine", }, { columnName: "tipologia", options: type_options, title: "Tipo Ordine", }, ]; return (
(tableRef.current = t)} pinnedFiltri={pinnedFiltri} searchColumn={searchFiltro} />
); };