Files
fullstack-fuware/src/components/house/delete-user-house-dialog.tsx
2026-02-23 21:40:32 +07:00

169 lines
5.3 KiB
TypeScript

import useHasPermission from '@hooks/use-has-permission';
import usePreventAutoFocus from '@hooks/use-prevent-auto-focus';
import { authClient } from '@lib/auth-client';
import { m } from '@paraglide/messages';
import { ShieldWarningIcon, TrashIcon } from '@phosphor-icons/react';
import { deleteUserHouse } from '@service/house.api';
import { housesQueries } from '@service/queries';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Button } from '@ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@ui/dialog';
import { Label } from '@ui/label';
import { Spinner } from '@ui/spinner';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@ui/table';
import { Tooltip, TooltipContent, TooltipTrigger } from '@ui/tooltip';
import parse from 'html-react-parser';
import { useState } from 'react';
import { toast } from 'sonner';
import RoleBadge from '../avatar/role-badge';
import { Skeleton } from '../ui/skeleton';
type DeleteUserHouseProps = {
activeHouse: ReturnType<typeof authClient.useActiveOrganization>['data'];
};
const DeleteUserHouseAction = ({ activeHouse }: DeleteUserHouseProps) => {
const [_open, _setOpen] = useState(false);
const prevent = usePreventAutoFocus();
const { hasPermission, isLoading } = useHasPermission(
'house',
'delete',
true,
);
const queryClient = useQueryClient();
const { mutate: deleteHouseMutation, isPending } = useMutation({
mutationFn: deleteUserHouse,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [...housesQueries.all, 'currentUser'],
});
_setOpen(false);
toast.success(m.houses_page_message_delete_house_success(), {
richColors: true,
});
},
onError: (error: ReturnError) => {
console.error(error);
const code = error.code as Parameters<
typeof m.backend_message
>[0]['code'];
toast.error(m.backend_message({ code }), {
richColors: true,
});
},
});
if (isLoading || !activeHouse) {
return <Skeleton className="h-8 w-8 rounded-full" />;
}
const onConfirm = async () => {
deleteHouseMutation({ data: { id: activeHouse.id } });
};
if (!hasPermission) return null;
return (
<Dialog open={_open} onOpenChange={_setOpen}>
<Tooltip>
<TooltipTrigger asChild>
<DialogTrigger asChild>
<Button
type="button"
size="icon-lg"
className="rounded-full cursor-pointer bg-red-500 text-white hover:bg-red-100 hover:text-red-600"
>
<TrashIcon size={16} />
<span className="sr-only">{m.ui_delete_btn()}</span>
</Button>
</DialogTrigger>
</TooltipTrigger>
<TooltipContent className="bg-red-500 [&_svg]:bg-red-500 [&_svg]:fill-red-500 text-white">
<Label>{m.ui_delete_btn()}</Label>
</TooltipContent>
</Tooltip>
<DialogContent
className="max-w-100 xl:max-w-xl"
showCloseButton={false}
{...prevent}
onPointerDownOutside={(e) => e.preventDefault()}
onEscapeKeyDown={(e) => e.preventDefault()}
>
<DialogHeader>
<DialogTitle className="flex items-center gap-3 text-lg font-bold text-red-500">
<div className="rounded-full bg-red-100 p-3">
<ShieldWarningIcon size={30} />
</div>
{m.houses_page_ui_dialog_alert_delete_title({
name: activeHouse.name,
})}
</DialogTitle>
<DialogDescription className="text-red-500">
{parse(m.houses_page_ui_dialog_alert_delete_description())}
</DialogDescription>
</DialogHeader>
<div className="overflow-hidden rounded-md border">
<Table className="bg-white">
<TableHeader>
<TableRow>
<TableHead className="px-2 h-7 bg-primary text-white text-xs w-1/2">
{m.houses_page_ui_view_table_header_email()}
</TableHead>
<TableHead className="px-2 h-7 bg-primary text-white text-xs w-1/2">
{m.houses_page_ui_view_table_header_role()}
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{activeHouse.members.map((member) => (
<TableRow key={member.user.email}>
<TableCell>{member.user.email}</TableCell>
<TableCell>
<RoleBadge type={member.role} />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<DialogFooter className="bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4">
<DialogClose asChild>
<Button variant="outline" type="button">
{m.ui_cancel_btn()}
</Button>
</DialogClose>
<Button
variant="destructive"
type="button"
onClick={onConfirm}
disabled={isPending}
>
{isPending && <Spinner data-icon="inline-start" />}
{m.ui_confirm_btn()}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
export default DeleteUserHouseAction;