ldc-groupe/resources/ts/back/Components/ModelActions.tsx

186 lines
7.6 KiB
TypeScript

// * Packages
import { Link, useForm } from "@inertiajs/react";
import { route } from "ziggy-js";
import { FormEvent } from "react";
// * Components shadcn
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { DropdownMenuSeparator } from "@/components/ui/dropdown-menu";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
// * Other
import { useFormatedDate } from "@/hooks/use-formated-value";
import { useToast } from "@/hooks/use-toast";
import useTrans from "@/hooks/use-translations";
import str from "@/hooks/use-string";
import { Model, Views } from "@/back/types/global";
interface ModelActionsProps {
actions?: Views;
modelName: string;
model: Model;
modelUpdatedAt?: string;
inColumn?: boolean;
message?: string;
}
export default function ModelActions({
actions = [],
modelName,
model,
modelUpdatedAt = "",
inColumn = false,
message = "back.model_action_updated_at",
}: ModelActionsProps) {
const messageTrans = useTrans(message);
const { toast } = useToast();
const { delete: destroy } = useForm();
const deleteUser = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
destroy(route(`back.${modelName}.destroy`, model.id), {
preserveScroll: true,
onSuccess: () => {
toast({
title: "Suppression réussie !",
description:
"Vous venez de supprimer définitivement une entrée.",
});
},
onError: () => {
toast({
variant: "destructive",
title: "Suppression annulée !",
description:
"Un problème est survenu lors de la suppression de cette entrée.",
});
},
});
};
const GetTranslation = (label: string) => {
return useTrans(`crud.actions.${label}`);
};
const formattedDate = useFormatedDate(modelUpdatedAt);
const dialogSureTrans = useTrans("back.are_you_sure");
const dialogLostDataTrans = useTrans("back.lost_data");
const dialogCancelTrans = useTrans("back.no_cancel");
const dialogConfirmTrans = useTrans("back.yes_delete");
return (
<div
className={`flex justify-between items-center ${
!inColumn ? "flex-col xl:flex-row mb-4" : "flex-col"
}`}
>
{!inColumn && modelUpdatedAt.length > 0 && (
<div className="flex justify-start items-center">
<p className="text-center xl:text-left">{messageTrans}</p>
<Badge variant="secondary" className="ms-1 mt-1">
{formattedDate}
</Badge>
</div>
)}
<div
className={`flex justify-between items-center ${
!inColumn
? "flex-col sm:flex-row mt-4 xl:mt-0"
: "flex-col w-full"
}`}
>
{actions.map((action) => {
if (
!model.policies[
action.policy as keyof typeof model.policies
]
) {
return null;
}
return (
<div key={action.value} className="w-full">
{action.value === "destroy" ? (
<>
{inColumn && <DropdownMenuSeparator />}
<Dialog>
<DialogTrigger asChild>
<Button
variant="destructive"
className="w-full"
>
<action.icon />
{str(
GetTranslation(
action.label,
),
)
.ucFirst()
.value()}
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>
{dialogSureTrans}
</DialogTitle>
<DialogDescription>
{dialogLostDataTrans}
</DialogDescription>
</DialogHeader>
<DialogFooter className="items-center sm:justify-start">
<DialogClose asChild>
<Button variant="secondary">
{dialogCancelTrans}
</Button>
</DialogClose>
<form
onSubmit={deleteUser}
className="w-fit mb-2 sm:mb-0"
>
<Button
type="submit"
variant="destructive"
>
{dialogConfirmTrans}
</Button>
</form>
</DialogFooter>
</DialogContent>
</Dialog>
</>
) : (
<Button
asChild
variant="ghost"
className="w-full"
>
<Link
href={route(
`back.${modelName}.${action.value}`,
model.id,
)}
className="w-full"
>
<action.icon />
{str(GetTranslation(action.label))
.ucFirst()
.value()}
</Link>
</Button>
)}
</div>
);
})}
</div>
</div>
);
}