import { zodResolver } from '@hookform/resolvers/zod' import dayjs from 'dayjs' import { useForm } from 'react-hook-form' import * as z from 'zod' import { toast } from 'sonner' import { useEffect } from 'react' import { Button, cn, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_, Modal, Select_Shadcn_, SelectContent_Shadcn_, SelectItem_Shadcn_, SelectTrigger_Shadcn_, Separator, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { useUserUpdateMutation } from 'data/auth/user-update-mutation' import { User } from 'data/auth/users-query' import { useProjectApiQuery } from 'data/config/project-api-query' import { useParams } from 'common' interface BanUserModalProps { visible: boolean user: User onClose: () => void } export const BanUserModal = ({ visible, user, onClose }: BanUserModalProps) => { const { ref: projectRef } = useParams() const { data: apiData } = useProjectApiQuery({ projectRef }) const { mutate: updateUser, isLoading: isBanningUser } = useUserUpdateMutation({ onSuccess: (_, vars) => { const bannedUntil = dayjs() .add(Number(vars.banDuration), 'hours') .format('DD MMM YYYY HH:mm (ZZ)') toast.success(`User banned successfully until ${bannedUntil}`) onClose() }, }) const FormSchema = z.object({ value: z.string().min(1, { message: 'Please provide a duration' }), unit: z.enum(['hours', 'days']), }) type FormType = z.infer const defaultValues: FormType = { value: '24', unit: 'hours' } const form = useForm({ mode: 'onBlur', reValidateMode: 'onChange', resolver: zodResolver(FormSchema), defaultValues, }) const { value, unit } = form.watch() const bannedUntil = dayjs().add(Number(value), unit).format('DD MMM YYYY HH:mm (ZZ)') const onSubmit = (data: FormType) => { if (!apiData) { return toast.error(`Failed to ban user: Error loading project config`) } else if (user.id === undefined) { return toast.error(`Failed to ban user: User ID not found`) } const durationHours = data.unit === 'hours' ? Number(data.value) : Number(data.value) * 24 const { protocol, endpoint, serviceApiKey } = apiData.autoApiService updateUser({ projectRef, protocol, endpoint, serviceApiKey, userId: user.id, banDuration: durationHours, }) } useEffect(() => { if (visible) form.reset(defaultValues) // eslint-disable-next-line react-hooks/exhaustive-deps }, [visible]) return ( onClose()} >

This will revoke the user's access to your project and prevent them from logging in for a specified duration.

( )} /> ( form.setValue('unit', value as 'hours' | 'days')} > {field.value} Hours Days )} />

This user will not be able to log in until:

{!!value ? bannedUntil : 'Invalid duration set'}

) }