import { Stack, Group, Grid, Image } from '@mantine/core'; import { FileWithPath, IMAGE_MIME_TYPE } from '@mantine/dropzone'; import { useForm } from '@mantine/form'; import { useClipboard, useFocusTrap } from '@mantine/hooks'; import { RiImage2Line } from 'react-icons/ri'; import { User } from '@/renderer/api/types'; import { Button, PasswordInput, TextInput, Switch, toast, Dropzone, Text, } from '@/renderer/components'; import { usePermissions } from '@/renderer/features/shared'; import { useUpdateUser } from '@/renderer/features/users/mutations/update-user'; import { randomString } from '@/renderer/utils'; interface EditUserFormProps { onCancel: () => void; repeatPassword?: boolean; user?: User; } export const EditUserForm = ({ user, onCancel, repeatPassword, }: EditUserFormProps) => { const permissions = usePermissions(); const focusTrapRef = useFocusTrap(true); const clipboard = useClipboard({ timeout: 1000 }); const form = useForm({ initialValues: { displayName: user?.displayName || '', image: null as FileWithPath | null, isAdmin: user?.isAdmin || false, password: '', repeatPassword: '', username: user?.username || '', }, }); const handleGeneratePassword = () => { const pass = randomString(); form.setFieldValue('password', pass); clipboard.copy(pass); toast.info({ message: 'Password copied to clipboard' }); }; const isSubmitValid = () => { if (!repeatPassword) return true; return form.values.password === form.values.repeatPassword; }; const updateUserMutation = useUpdateUser(); const handleUpdateUser = form.onSubmit((values) => { if (!user) return; const body = { ...values, displayName: values.displayName || undefined, image: values.image || undefined, password: values.password || undefined, repeatPassword: values.repeatPassword || undefined, }; updateUserMutation.mutate( { body, query: { userId: user.id }, }, { onError: (err) => toast.error({ message: err.response?.data?.error?.message }), onSuccess: () => { toast.success({ message: `${values.username} was successfully updated.`, title: 'User updated', }); onCancel(); }, } ); }); const getPreview = () => { if (form.values.image instanceof File) { const imageUrl = URL.createObjectURL(form.values.image); return ( URL.revokeObjectURL(imageUrl) }} radius={100} src={imageUrl} sx={{ objectFit: 'contain' }} width={150} /> ); } return null; }; const handleRemoveImage = () => form.setFieldValue('image', null); return (
form.setFieldValue('image', file[0])} onReject={(err) => toast.error({ message: `${err[0].errors[0].message}`, title: 'Invalid Image', }) } > {form.values.image ? ( {getPreview()} ) : ( Profile image Max size: 5MB )} {repeatPassword && ( )} {permissions.isAdmin && !user?.isSuperAdmin ? ( Admin ) : ( )} {!repeatPassword && ( )}
); }; EditUserForm.defaultProps = { repeatPassword: false, user: undefined, };