186 lines
7.6 KiB
TypeScript
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>
|
|
);
|
|
}
|