'use client' import styles from '@/app/styles/module/login.module.scss' import { useActionState, useState, useEffect } from 'react'; import { createStuff } from '@/app/actions/stuffActions'; import { useTranslations } from 'next-intl'; import { IconEye } from '@/app/ui/icons/icons'; import { useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { z } from 'zod'; const createStuffSchema = z.object({ fullName: z.string() .min(2, 'full-name-too-short') .max(100, 'full-name-too-long') .trim(), email: z.string() .email('register-error-email-invalid') .toLowerCase() .trim(), password: z.string() .min(4, 'register-error-password-min') .max(124, 'register-error-password-max'), changePassword: z.boolean().default(true), permissions: z.object({ subscriptions: z.number().min(0).max(3), mailings: z.number().min(0).max(3), complaints: z.number().min(0).max(3), agreements: z.number().min(0).max(3), staff: z.number().min(0).max(3), content_moderation: z.number().min(0).max(3), users: z.number().min(0).max(3), money: z.number().min(0).max(3), kyc: z.number().min(0).max(3), claims: z.number().min(0).max(3), api: z.number().min(0).max(3), dash: z.number().min(0).max(3), tariffs: z.number().min(0).max(3), }).default({ subscriptions: 0, mailings: 0, complaints: 0, agreements: 0, staff: 0, content_moderation: 0, users: 0, money: 0, kyc: 0, claims: 0, api: 0, dash: 0, tariffs: 0, }) }) export function CreateStaffForm({ onSuccess }: { onSuccess?: () => void }) { const [state, formAction, isPending] = useActionState( createStuffAction, undefined, ); const t = useTranslations('Login-register-form'); const tGeneral = useTranslations('Global'); const tPermissions = useTranslations('Permissions'); const [showPassword, setShowPassword] = useState(false); const [changePassword, setChangePassword] = useState(true); const [permissions, setPermissions] = useState({ subscriptions: 0, mailings: 0, complaints: 0, agreements: 0, staff: 0, content_moderation: 0, users: 0, money: 0, kyc: 0, claims: 0, api: 0, dash: 0, tariffs: 0, }); const permissionsConfig = [ { key: 'subscriptions', label: tPermissions('subscriptions'), description: tPermissions('subscriptions-desc') }, { key: 'mailings', label: tPermissions('mailings'), description: tPermissions('mailings-desc') }, { key: 'complaints', label: tPermissions('complaints'), description: tPermissions('complaints-desc') }, { key: 'agreements', label: tPermissions('agreements'), description: tPermissions('agreements-desc') }, { key: 'staff', label: tPermissions('staff'), description: tPermissions('staff-desc') }, { key: 'content_moderation', label: tPermissions('content_moderation'), description: tPermissions('content_moderation-desc') }, { key: 'users', label: tPermissions('users'), description: tPermissions('users-desc') }, { key: 'kyc', label: tPermissions('kyc'), description: tPermissions('kyc-desc') }, { key: 'money', label: tPermissions('money'), description: tPermissions('money-desc') }, { key: 'claims', label: tPermissions('claims'), description: tPermissions('claims-desc') }, { key: 'api', label: tPermissions('api'), description: tPermissions('api-desc') }, { key: 'dash', label: tPermissions('dash'), description: tPermissions('dash-desc') }, { key: 'tariffs', label: tPermissions('tariffs'), description: tPermissions('tariffs-desc') }, ]; const handlePermissionChange = (key: keyof typeof permissions, value: number) => { setPermissions(prev => ({ ...prev, [key]: value })); }; function toggleShowPassword() { setShowPassword(!showPassword); } const queryClient = useQueryClient(); useEffect(() => { if (state?.success) { toast.success(tGeneral('staff-created-successfully')); queryClient.invalidateQueries({ queryKey: ['stuffList'] }); if (onSuccess) { onSuccess(); } } if (state?.error?.server) { toast.error(t(state.error.server)); } }, [state, queryClient, onSuccess, t, tGeneral]); return (
{/* Поле Email */}
{ e.target.value = e.target.value.toLowerCase(); }} /> {state?.error?.email && (

{t(state?.error?.email)}

)}
{/* Поле Password */}
{state?.error?.password && (

{t(state?.error?.password)}

)}
{/* Поле Full Name */}
{state?.error?.fullName && (

{t(state?.error?.fullName)}

)}
{/* Чекбокс */}

{tGeneral('permissions')}

{permissionsConfig.map((perm) => { const currentValue = permissions[perm.key as keyof typeof permissions]; return (

{perm.label}

{perm.description}

); })}
{state?.error?.server && !state.success && (

{t(state?.error?.server)}

)}
) } async function createStuffAction( state: { previousState: { fullName?: string; email?: string; password?: string; } error: Record success?: boolean; } | undefined, formData: FormData, ) { const fullName = formData.get('fullName') as string || ''; const email = formData.get('email') as string || ''; const password = formData.get('password') as string || ''; const changePassword = formData.get('changePassword') === 'on'; const permissions = { subscriptions: parseInt(formData.get('permissions.subscriptions') as string) || 0, mailings: parseInt(formData.get('permissions.mailings') as string) || 0, complaints: parseInt(formData.get('permissions.complaints') as string) || 0, agreements: parseInt(formData.get('permissions.agreements') as string) || 0, staff: parseInt(formData.get('permissions.staff') as string) || 0, content_moderation: parseInt(formData.get('permissions.content_moderation') as string) || 0, users: parseInt(formData.get('permissions.users') as string) || 0, money: parseInt(formData.get('permissions.money') as string) || 0, kyc: parseInt(formData.get('permissions.kyc') as string) || 0, claims: parseInt(formData.get('permissions.claims') as string) || 0, api: parseInt(formData.get('permissions.api') as string) || 0, dash: parseInt(formData.get('permissions.dash') as string) || 0, tariffs: parseInt(formData.get('permissions.tariffs') as string) || 0, }; const validatedFields = createStuffSchema.safeParse({ fullName, email, password, changePassword, permissions }); if (!validatedFields.success) { const errors: Record = {} JSON.parse(validatedFields.error.message).forEach((obj: { message: string, path: string[] }) => { const fieldName = obj.path[0]; if (errors[fieldName]) { errors[fieldName] = `${errors[fieldName]} ${obj.message}`; } else { errors[fieldName] = obj.message; } }); return { previousState: { fullName, email, password }, error: errors, success: false }; } try { const { fullName, email, password, changePassword, permissions } = validatedFields.data; const result = await createStuff(fullName, email, password, permissions, changePassword); if (result) { return { previousState: { fullName: '', email: '', password: '' }, error: {}, success: true }; } else { throw new Error('creation-failed'); } } catch (error) { const errors: Record = {} if (error === 'email-already-exists') { errors['email'] = 'email-already-exists'; } else if (error === 'invalid-email') { errors['email'] = 'invalid-email'; } else { errors['server'] = 'request-ended-with-an-error'; } return { previousState: { fullName, email, password }, error: errors, success: false }; } }