217 lines
5.8 KiB
TypeScript
217 lines
5.8 KiB
TypeScript
import { CircleCheck, CircleSlash, ReceiptText, Trash2 } from "lucide-react";
|
|
import Link from "next/link";
|
|
import toast from "react-hot-toast";
|
|
import { Confirm } from "~/components/confirm";
|
|
import {
|
|
Credenza,
|
|
CredenzaBody,
|
|
CredenzaClose,
|
|
CredenzaContent,
|
|
CredenzaDescription,
|
|
CredenzaFooter,
|
|
CredenzaHeader,
|
|
CredenzaTitle,
|
|
} from "~/components/custom_ui/credenza";
|
|
import { PaymentsTable } from "~/components/tables/payments-table";
|
|
import { Button } from "~/components/ui/button";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuLabel,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from "~/components/ui/dropdown-menu";
|
|
import { cn } from "~/lib/utils";
|
|
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
|
|
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
|
|
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
|
|
import type { UsersId } from "~/schemas/public/Users";
|
|
import { api } from "~/utils/api";
|
|
|
|
export const OrdiniModal = ({
|
|
isAdmin,
|
|
open,
|
|
setModalOpen,
|
|
ordineId,
|
|
userId,
|
|
}: {
|
|
isAdmin: boolean;
|
|
open: boolean;
|
|
setModalOpen: (open: boolean) => void;
|
|
ordineId: OrdiniOrdineId;
|
|
userId: UsersId | undefined;
|
|
}) => {
|
|
const utils = api.useUtils();
|
|
const { mutate: remove } = api.servizio.removeOrder.useMutation({
|
|
onError: (error) => {
|
|
toast.error(`Errore durante la rimozione ordine: ${error.message}`);
|
|
},
|
|
onSuccess: async () => {
|
|
toast.success("Ordine rimosso con successo!");
|
|
await utils.servizio.getOrdini.invalidate({
|
|
userId,
|
|
});
|
|
setModalOpen(false);
|
|
},
|
|
});
|
|
const { mutate: update } = api.servizio.updateOrder.useMutation({
|
|
onError: (error) => {
|
|
toast.error(`Errore durante la modifica: ${error.message}`);
|
|
},
|
|
onSuccess: async (data) => {
|
|
if (data.type === OrderTypeEnum.Acconto && data.isActive) {
|
|
updateServizio({
|
|
data: {
|
|
decorrenza: new Date(),
|
|
isOkAcconto: true,
|
|
},
|
|
servizioId: data.servizio_id,
|
|
});
|
|
}
|
|
toast.success("Ordine aggiornato con successo!");
|
|
await utils.servizio.getOrdini.invalidate({
|
|
userId,
|
|
});
|
|
await utils.servizio.getOrdineById.invalidate({
|
|
ordineId,
|
|
});
|
|
},
|
|
});
|
|
|
|
const { mutate: updateServizio } = api.servizio.updateServizio.useMutation({
|
|
onError: (error) => {
|
|
toast.error(error.message);
|
|
},
|
|
onSuccess: async (data) => {
|
|
toast.success("Servizio modificato con successo");
|
|
await utils.servizio.getUserServizi.invalidate();
|
|
await utils.servizio.getPacksSolution.invalidate({
|
|
servizioId: data.servizio_id,
|
|
});
|
|
},
|
|
});
|
|
|
|
const { data } = api.servizio.getOrdineById.useQuery({
|
|
ordineId,
|
|
});
|
|
if (!data) return null;
|
|
|
|
return (
|
|
<Credenza
|
|
onOpenChange={(b) => {
|
|
setModalOpen(b);
|
|
}}
|
|
open={open}
|
|
>
|
|
<CredenzaContent className="max-h-[90vh] max-w-2xl sm:max-w-4xl">
|
|
<CredenzaHeader>
|
|
<CredenzaTitle>Dettagli Ordine</CredenzaTitle>
|
|
<CredenzaDescription>
|
|
Visualizza i dettagli e i pagamenti associati.
|
|
</CredenzaDescription>
|
|
</CredenzaHeader>
|
|
<CredenzaBody className="max-h-[80vh] space-y-2 overflow-auto pb-5">
|
|
<p>Id Ordine: {data.ordine_id}</p>
|
|
<p>
|
|
Data Ordine:
|
|
{new Date(data.created_at).toLocaleDateString("it-IT", {
|
|
day: "2-digit",
|
|
month: "2-digit",
|
|
year: "numeric",
|
|
})}
|
|
</p>
|
|
<p>Tipologia: {data.type.toString()}</p>
|
|
<p>Pack ID: {data.packid}</p>
|
|
<p className="flex items-center gap-2">
|
|
Stato:{" "}
|
|
{data.isActive ? (
|
|
<span className="inline-flex items-center gap-1 text-green-500">
|
|
<CircleCheck className="size-5" />
|
|
Attivo
|
|
</span>
|
|
) : (
|
|
<span className="inline-flex items-center gap-1">
|
|
<CircleSlash className="size-5" />
|
|
Non Attivo
|
|
</span>
|
|
)}
|
|
</p>
|
|
|
|
{data.isActive &&
|
|
data.pagamenti.find(
|
|
(p) => p.paymentstatus === PaymentStatusEnum.success,
|
|
) && (
|
|
<div>
|
|
<Link
|
|
href={`/area-riservata/payment-recap/${data.ordine_id}`}
|
|
target="_blank"
|
|
>
|
|
<Button variant="outline">
|
|
Ricevuta di cortesia <ReceiptText />
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
)}
|
|
|
|
<PaymentsTable data={data.pagamenti} isAdmin={isAdmin} isUserView />
|
|
</CredenzaBody>
|
|
<CredenzaFooter
|
|
className={cn(
|
|
"flex w-full",
|
|
isAdmin ? "sm:justify-between" : "sm:justify-end",
|
|
)}
|
|
>
|
|
{isAdmin && (
|
|
<div className="flex items-center gap-4">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button aria-label="Modifica Status" variant="outline">
|
|
Modifica Status
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuLabel>Status</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuRadioGroup
|
|
onValueChange={(v) => {
|
|
update({
|
|
data: { isActive: v === "true" },
|
|
ordineId,
|
|
});
|
|
}}
|
|
value={data.isActive ? "true" : "false"}
|
|
>
|
|
<DropdownMenuRadioItem value="true">
|
|
Attivo
|
|
</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="false">
|
|
Non Attivo
|
|
</DropdownMenuRadioItem>
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
|
|
<Confirm
|
|
description="Sei sicuro di voler eliminare l'ordine?"
|
|
onConfirm={() => {
|
|
remove({ ordineId });
|
|
}}
|
|
title="Elimina ordine"
|
|
>
|
|
<Button aria-label="Elimina Ordine" variant="destructive">
|
|
<Trash2 className="size-6" />
|
|
Elimina Ordine
|
|
</Button>
|
|
</Confirm>
|
|
</div>
|
|
)}
|
|
<CredenzaClose asChild>
|
|
<Button variant="ghost">Chiudi</Button>
|
|
</CredenzaClose>
|
|
</CredenzaFooter>
|
|
</CredenzaContent>
|
|
</Credenza>
|
|
);
|
|
};
|