Files
fullstack-fuware/src/components/user/ban-user-confirm-dialog.tsx
Sam 1d3e79c546 add function for user
- create house
- edit house
- delete house
- list all member for active house
2026-02-08 13:43:14 +07:00

149 lines
4.6 KiB
TypeScript

import usePreventAutoFocus from '@hooks/use-prevent-auto-focus';
import { m } from '@paraglide/messages';
import { ShieldWarningIcon } from '@phosphor-icons/react';
import { usersQueries } from '@service/queries';
import { banUser } from '@service/user.api';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Button } from '@ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@ui/dialog';
import { UserWithRole } from 'better-auth/plugins';
import { toast } from 'sonner';
import { Spinner } from '../ui/spinner';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '../ui/table';
import { useBanContext } from './ban-user-dialog';
type BanConfirmProps = {
data: UserWithRole;
};
const BanUserConfirm = ({ data }: BanConfirmProps) => {
const { openConfirm, setOpenConfirm, submitData } = useBanContext();
const queryClient = useQueryClient();
const prevent = usePreventAutoFocus();
const { mutate: banUserMutation, isPending } = useMutation({
mutationFn: banUser,
onSuccess: () => {
queryClient.refetchQueries({
queryKey: usersQueries.all,
});
setOpenConfirm(false);
toast.success(m.users_page_message_banned_success({ name: data.name }), {
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,
});
},
});
const onConfirm = () => {
banUserMutation({ data: submitData });
};
return (
<Dialog open={openConfirm} onOpenChange={setOpenConfirm}>
<DialogContent
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.users_page_ui_dialog_alert_ban_title()}
</DialogTitle>
<DialogDescription className="sr-only">
{m.users_page_ui_dialog_alert_ban_title()}
</DialogDescription>
</DialogHeader>
<div className="overflow-hidden rounded-md border">
<Table className="bg-white">
<TableHeader>
<TableRow className="bg-primary">
<TableHead className="px-2 h-7 text-white text-xs" colSpan={2}>
{m.users_page_ui_dialog_alert_description_title()}
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-bold">
{m.users_page_ui_table_header_name()}:
</TableCell>
<TableCell>{data.name}</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-bold">
{m.users_page_ui_table_header_email()}:
</TableCell>
<TableCell>{data.email}</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-bold">
{m.users_page_ui_form_ban_reason()}:
</TableCell>
<TableCell>{submitData.banReason}</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-bold">
{m.users_page_ui_form_ban_exp()}:
</TableCell>
<TableCell>
{m.exp_time({
time: submitData.banExp.toString() as Parameters<
typeof m.exp_time
>[0]['time'],
})}
</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 BanUserConfirm;