infoalloggi-monorepo/apps/infoalloggi/src/components/tables/orders-table.tsx

244 lines
5.8 KiB
TypeScript
Raw Normal View History

2025-08-28 18:27:07 +02:00
import type { ColumnDef } from "@tanstack/react-table";
import { CircleCheck, ExternalLink } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { OrdiniModal } from "~/components/area-riservata/ordini";
2025-08-04 17:45:44 +02:00
import { DataTable } from "~/components/custom_ui/data-table";
2025-08-28 18:27:07 +02:00
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
2025-08-04 17:45:44 +02:00
import type {
2025-08-28 18:27:07 +02:00
PinnedFiltro,
SearchFiltro,
2025-08-04 17:45:44 +02:00
} from "~/components/custom_ui/dataTable-toolbar";
import { Button } from "~/components/ui/button";
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
2025-08-28 18:27:07 +02:00
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import type { UsersId } from "~/schemas/public/Users";
import type { OrdiniWPagamenti } from "~/server/controllers/ordini.controller";
2025-08-04 17:45:44 +02:00
type PaymentsTableProps = {
2025-08-28 18:27:07 +02:00
data: OrdiniWPagamenti[];
isAdmin: boolean;
userId?: UsersId;
2025-08-04 17:45:44 +02:00
};
export const OrdiniTable = ({ data, isAdmin, userId }: PaymentsTableProps) => {
2025-08-28 18:27:07 +02:00
const tabledata = data.map((row) => {
return {
2025-08-29 16:18:32 +02:00
actions: "Azioni",
created_at: row.created_at,
2025-08-28 18:27:07 +02:00
id: row.ordine_id,
isActive: row.isActive,
isPaid: row.pagamenti.some(
(p) => p.paymentstatus === PaymentStatusEnum.success,
),
2025-08-29 16:18:32 +02:00
packid: row.packid,
tipo: row.type,
userId: row.userid,
username: row.username,
2025-08-28 18:27:07 +02:00
};
});
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const columns_titles = {
2025-08-29 16:18:32 +02:00
actions: "Azioni",
2025-08-28 18:27:07 +02:00
created_at: "Creato il",
isPaid: "Pagato",
2025-08-29 16:18:32 +02:00
packid: "ID Pacchetto",
tipo: "Tipo",
username: "Utente",
2025-08-28 18:27:07 +02:00
};
const isPaidOptions = [
2025-08-29 16:18:32 +02:00
{ label: "Pagato", value: "true" },
{ label: "Non pagato", value: "false" },
2025-08-28 18:27:07 +02:00
];
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const type_options = [
2025-08-29 16:18:32 +02:00
{ label: "Acconto", value: OrderTypeEnum.Acconto },
{ label: "Saldo", value: OrderTypeEnum.Saldo },
{ label: "Consulenza", value: OrderTypeEnum.Consulenza },
{ label: "Altro", value: OrderTypeEnum.Altro },
2025-08-28 18:27:07 +02:00
];
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const [modalOpen, setModalOpen] = useState(false);
const [selectedOrdine, setSelectedOrdine] = useState<OrdiniOrdineId | null>(
null,
);
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
type Column = (typeof tabledata)[number];
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const columns: ColumnDef<Column>[] = [
{
accessorKey: "username",
cell: ({ row }) => {
if (isAdmin) {
return (
<Link
aria-label="Visualizza Utente"
href={`/area-riservata/admin/user-view/ricerca/${row.original.userId}`}
>
<Button size="sm">{row.original.username}</Button>
</Link>
);
}
return <span>{row.original.username}</span>;
},
2025-08-29 16:18:32 +02:00
enableHiding: false,
2025-08-28 18:27:07 +02:00
header: ({ column }) => (
<DataTableColumnHeader
column={column}
2025-08-29 16:18:32 +02:00
title={columns_titles.username}
2025-08-28 18:27:07 +02:00
/>
),
2025-08-29 16:18:32 +02:00
},
{
2025-08-28 18:27:07 +02:00
accessorKey: "created_at",
cell: ({ row }) => {
const date = row.getValue("created_at");
return new Date(date as Date).toLocaleDateString();
},
enableHiding: false,
header: ({ column }) => (
2025-08-29 16:18:32 +02:00
<DataTableColumnHeader
column={column}
title={columns_titles.created_at}
/>
2025-08-28 18:27:07 +02:00
),
2025-08-29 16:18:32 +02:00
sortingFn: "datetime",
},
{
2025-08-28 18:27:07 +02:00
accessorKey: "tipo",
cell: ({ row }) => {
return row.original.tipo.toString();
},
filterFn: (row, id, value) => {
return value.includes(row.getValue(id));
},
2025-08-29 16:18:32 +02:00
header: ({ column }) => (
<DataTableColumnHeader column={column} title={columns_titles.tipo} />
),
2025-08-28 18:27:07 +02:00
},
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
{
2025-08-29 16:18:32 +02:00
accessorKey: "packid",
2025-08-28 18:27:07 +02:00
header: ({ column }) => (
<DataTableColumnHeader column={column} title={columns_titles.packid} />
),
},
{
accessorKey: "isPaid",
cell: ({ row }) => {
const isPaid = row.original.isPaid;
const isActive = row.original.isActive;
if (isActive) {
return (
<span className="inline-flex items-center gap-1 text-green-500">
<CircleCheck className="size-5" />
{isPaid ? "Pagato" : "Attivato da Admin"}
</span>
);
}
if (isPaid) {
return (
<span className="inline-flex items-center gap-1 text-green-500">
<CircleCheck className="size-5" />
Pagato
</span>
);
} else {
return (
<span className="inline-flex items-center gap-1 text-red-500">
<CircleCheck className="size-5" />
Non pagato
</span>
);
}
},
2025-08-29 16:18:32 +02:00
filterFn: (row, id, value) => {
return value.includes(row.getValue(id));
},
header: ({ column }) => (
<DataTableColumnHeader column={column} title={columns_titles.isPaid} />
),
2025-08-28 18:27:07 +02:00
},
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
{
cell: ({ row }) => {
return (
<Button
aria-label="Apri Dettagli Ordine"
2025-08-29 16:18:32 +02:00
className="flex items-center gap-2"
2025-08-28 18:27:07 +02:00
onClick={() => {
setSelectedOrdine(row.original.id);
setModalOpen(true);
}}
2025-08-29 16:18:32 +02:00
size="sm"
variant="outline"
2025-08-28 18:27:07 +02:00
>
<ExternalLink className="size-6" />
Apri Dettagli
</Button>
);
},
2025-08-29 16:18:32 +02:00
enableHiding: false,
id: "actions",
2025-08-28 18:27:07 +02:00
},
];
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const searchFiltro: SearchFiltro =
isAdmin && !userId
? {
columnName: "username",
placeholder: "Cerca utente...",
}
: {
columnName: "packid",
placeholder: "Cerca pagamento...",
};
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const pinnedFiltri: PinnedFiltro[] = [
{
columnName: "isPaid",
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
options: isPaidOptions,
2025-08-29 16:18:32 +02:00
title: "Stato Pagamento",
2025-08-28 18:27:07 +02:00
},
{
columnName: "tipo",
options: type_options,
2025-08-29 16:18:32 +02:00
title: "Tipo Ordine",
2025-08-28 18:27:07 +02:00
},
];
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
return (
<div className="mx-auto w-full py-10">
<DataTable
columns={columns}
columns_titles={columns_titles}
2025-08-29 16:18:32 +02:00
data={tabledata}
2025-08-28 18:27:07 +02:00
defaultColumnVisibility={{
2025-08-29 16:18:32 +02:00
actions: true,
2025-08-28 18:27:07 +02:00
amount: true,
2025-08-29 16:18:32 +02:00
packid: true,
2025-08-28 18:27:07 +02:00
paid_at: true,
2025-08-29 16:18:32 +02:00
status: true,
tipo: true,
username: isAdmin && !userId,
2025-08-28 18:27:07 +02:00
}}
2025-08-29 16:18:32 +02:00
defaultSort={[{ desc: true, id: "created_at" }]}
pinnedFiltri={pinnedFiltri}
searchColumn={searchFiltro}
2025-08-28 18:27:07 +02:00
/>
{selectedOrdine && (
<OrdiniModal
isAdmin={isAdmin}
open={modalOpen}
2025-08-29 16:18:32 +02:00
ordineId={selectedOrdine}
setModalOpen={setModalOpen}
2025-08-28 18:27:07 +02:00
userId={userId}
/>
)}
</div>
);
2025-08-04 17:45:44 +02:00
};