refactor(user-register): showing validation

This commit is contained in:
smanylov
2025-11-28 12:38:14 +07:00
parent 39dee22b89
commit 5c1a60645f
3 changed files with 61 additions and 25 deletions
+21 -7
View File
@@ -23,35 +23,49 @@ export async function authorization(
} }
export async function registration( export async function registration(
state: string | undefined, state: Record<string, string> | undefined,
formData: FormData, formData: FormData,
) { ) {
const validatedFields = SignupFormSchema.safeParse({ const validatedFields = SignupFormSchema.safeParse({
name: formData.get('full_name'), full_name: formData.get('full_name'),
email: formData.get('email'), email: formData.get('email'),
password: formData.get('password'), password: formData.get('password'),
confirm_password: formData.get('confirm_password'),
}) })
if (!validatedFields.success) { if (!validatedFields.success) {
return 'Something went wrong from valid.'; const errors: Record<string, string> = {}
JSON.parse(validatedFields.error.message).forEach((obj: {
message: string,
path: string
}) => {
if (errors[obj.path[0]]) {
errors[obj.path[0]] = `${errors[obj.path[0]]} ${obj.message}`;
} else {
errors[obj.path[0]] = obj.message;
}
});
return errors;
} }
try { try {
const { name, email, password } = validatedFields.data; const { full_name, email, password } = validatedFields.data;
const response = await fetch('http://localhost:8080/api/auth/register', { const response = await fetch('http://localhost:8080/api/auth/register', {
method: 'POST', method: 'POST',
body: JSON.stringify({ fullName: name, email, password }), body: JSON.stringify({ fullName: full_name, email, password }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json" "Accept": "application/json"
} }
}); });
let parsed = await response.json(); let parsed = await response.json();
await createSession(parsed.token); await createSession(parsed.token);
} catch (error) { } catch (error) {
if (error) { if (error) {
return 'Something went wrong. error'; const errors: Record<string, string> = {}
errors['server'] = 'Something went wrong. from server'
return errors;
} }
throw error; throw error;
} }
+20 -13
View File
@@ -1,18 +1,25 @@
import * as z from 'zod' import * as z from 'zod'
export const SignupFormSchema = z.object({ export const SignupFormSchema = z
name: z .object({
.string() full_name: z
.min(2, { error: 'Name must be at least 2 characters long.' }) .string()
.trim(), .min(3, { error: 'Name must be at least 3 characters long.' })
email: z.email({ error: 'Please enter a valid email.' }).trim(), .trim(),
password: z email: z.email({ error: 'Please enter a valid email.' }).trim(),
.string() password: z
.min(5, { error: 'Be at least 5 characters long' }) .string()
.regex(/[a-zA-Z]/, { error: 'Contain at least one letter.' }) .min(6, { error: 'Be at least 6 characters long' })
.regex(/[0-9]/, { error: 'Contain at least one number.' }) .regex(/[a-zA-Z]/, { error: 'Contain at least one letter.' })
.trim(), .regex(/[0-9]/, { error: 'Contain at least one number.' })
}) .trim(),
confirm_password: z
.string()
})
.refine((data) => data.password === data.confirm_password, {
message: 'passwordMismatchErrorMessage',
path: ['confirm_password'],
});
export type FormState = export type FormState =
| { | {
+20 -5
View File
@@ -1,7 +1,7 @@
'use client' 'use client'
import styles from '@/app/styles/login.module.scss'; import styles from '@/app/styles/login.module.scss';
import { useActionState } from 'react'; import { useActionState, useEffect } from 'react';
import { registration } from '@/app/actions/auth'; import { registration } from '@/app/actions/auth';
export default function RegisterForm() { export default function RegisterForm() {
@@ -10,8 +10,14 @@ export default function RegisterForm() {
undefined, undefined,
); );
useEffect(() => {
console.log(errorMessage);
}, [errorMessage])
return ( return (
<form action={formAction}> <form action={(e) => {
formAction(e);
}}>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<label <label
className={`${styles['form-label']} ${styles['required']}`} className={`${styles['form-label']} ${styles['required']}`}
@@ -19,11 +25,17 @@ export default function RegisterForm() {
Полное имя Полное имя
</label> </label>
<input type="readOnly" id="full_name" name="full_name" className={`${styles['form-input']}`} placeholder="Иванов Иван Иванович" /> <input type="readOnly" id="full_name" name="full_name" className={`${styles['form-input']}`} placeholder="Иванов Иван Иванович" />
{errorMessage?.full_name && (
<p className="text-sm text-red-500">{errorMessage!.full_name}</p>
)}
</div> </div>
<div className={`${styles['form-row']}`}> <div className={`${styles['form-row']}`}>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<label className={`${styles['form-label']} ${styles['required']}`}>Email адрес</label> <label className={`${styles['form-label']} ${styles['required']}`}>Email адрес</label>
<input type="text" id="email" name="email" className={`${styles['form-input']}`} placeholder="ivan@example.com" /> <input type="text" id="email" name="email" className={`${styles['form-input']}`} placeholder="ivan@example.com" />
{errorMessage?.email && (
<p className="text-sm text-red-500">{errorMessage!.email}</p>
)}
</div> </div>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<label className={`${styles['form-label']}`}>Телефон</label> <label className={`${styles['form-label']}`}>Телефон</label>
@@ -42,15 +54,18 @@ export default function RegisterForm() {
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<label className={`${styles['form-label']} ${styles['required']}`}>Пароль</label> <label className={`${styles['form-label']} ${styles['required']}`}>Пароль</label>
<input type="password" id="password" name="password" className={`${styles['form-input']}`} placeholder="Минимум 6 символов" /> <input type="password" id="password" name="password" className={`${styles['form-input']}`} placeholder="Минимум 6 символов" />
{errorMessage?.password && (
<p className="text-sm text-red-500">{errorMessage!.password}</p>
)}
</div> </div>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<label className={`${styles['form-label']} ${styles['required']}`}>Подтвердите пароль</label> <label className={`${styles['form-label']} ${styles['required']}`}>Подтвердите пароль</label>
<input type="password" id="confirm_password" name="confirm_password" className={`${styles['form-input']}`} placeholder="Повторите пароль" /> <input type="password" id="confirm_password" name="confirm_password" className={`${styles['form-input']}`} placeholder="Повторите пароль" />
{errorMessage?.confirm_password && (
<p className="text-sm text-red-500">{errorMessage!.confirm_password}</p>
)}
</div> </div>
</div> </div>
{errorMessage && (
<p className="text-sm text-red-500">{errorMessage}</p>
)}
<div className={`${styles['form-checkbox']}`} style={{ marginBottom: "20px" }}> <div className={`${styles['form-checkbox']}`} style={{ marginBottom: "20px" }}>
<input type="checkbox" id="remember" name="remember" /> <input type="checkbox" id="remember" name="remember" />
<label>Я соглашаюсь с <a href="forgot-password" >условиями использования и политикой конфиденциальности</a></label> <label>Я соглашаюсь с <a href="forgot-password" >условиями использования и политикой конфиденциальности</a></label>