This commit is contained in:
Estifo77
2026-08-19 10:31:13 +03:00
parent 0832e5d339
commit 9185df64b9
2 changed files with 22 additions and 28 deletions

View File

@@ -49,7 +49,7 @@ import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod'; import { z } from 'zod';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { notify, PageHeader, useErrorHandler, passwordSchema as strongPasswordSchema, PasswordRequirements, getCountryCode, splitPersonName, joinPersonName } from '@ema-platform/ui'; import { notify, PageHeader, useErrorHandler, passwordSchema as strongPasswordSchema, PasswordRequirements, getCountryCode } from '@ema-platform/ui';
import { useApiMutation, useLocalized } from '@ema-platform/api'; import { useApiMutation, useLocalized } from '@ema-platform/api';
import { PORTAL_PERMISSIONS, setUser, useCurrentProfile, usePermissions } from '@ema-platform/auth'; import { PORTAL_PERMISSIONS, setUser, useCurrentProfile, usePermissions } from '@ema-platform/auth';
import { SUPPORTED_LANGUAGES, type AppLanguage } from '../../../i18n/config'; import { SUPPORTED_LANGUAGES, type AppLanguage } from '../../../i18n/config';
@@ -89,6 +89,15 @@ function getInitials(name: string, fallback: string) {
return letters.toUpperCase(); return letters.toUpperCase();
} }
function splitProfileName(fullName: string) {
const [firstName = '', middleName = '', ...lastName] = fullName.trim().split(/\s+/);
return { firstName, middleName, lastName: lastName.join(' ') };
}
function formatProfileName({ firstName, middleName, lastName }: Pick<ProfileValues, 'firstName' | 'middleName' | 'lastName'>) {
return [firstName, middleName, lastName].filter(Boolean).join(' ');
}
function normalizeName(name: string) { function normalizeName(name: string) {
return name.trim().replace(/\s+/g, ' '); return name.trim().replace(/\s+/g, ' ');
} }
@@ -196,7 +205,7 @@ export function ProfilePage() {
// already holds so the form does not flash empty on a refetch. // already holds so the form does not flash empty on a refetch.
const currentProfile = resolvedProfile ?? storedProfile; const currentProfile = resolvedProfile ?? storedProfile;
if (currentProfile) { if (currentProfile) {
const accountName = user?.name?.en ? splitPersonName(user.name.en) : null; const accountName = user?.name?.en ? splitProfileName(user.name.en) : null;
setLoadedProfile({ setLoadedProfile({
professionId: currentProfile.professionId || currentProfile.profession?.id || '', professionId: currentProfile.professionId || currentProfile.profession?.id || '',
firstName: accountName?.firstName || currentProfile.firstName || '', firstName: accountName?.firstName || currentProfile.firstName || '',
@@ -277,7 +286,7 @@ export function ProfilePage() {
setIsSavingProfile(true); setIsSavingProfile(true);
try { try {
const profileName = splitPersonName(values.nameEn); const profileName = splitProfileName(values.nameEn);
const saves: Promise<unknown>[] = [ const saves: Promise<unknown>[] = [
updateTrigger({ updateTrigger({
url: '/auth/update-profile', url: '/auth/update-profile',
@@ -354,7 +363,7 @@ export function ProfilePage() {
const onSaveProfile = async (values: ProfileValues) => { const onSaveProfile = async (values: ProfileValues) => {
if (!profileId) return; if (!profileId) return;
const fullName = joinPersonName(values); const fullName = formatProfileName(values);
if (user && normalizeName(fullName) !== normalizeName(user.name.en)) { if (user && normalizeName(fullName) !== normalizeName(user.name.en)) {
notify.error(t('profile.nameMismatch')); notify.error(t('profile.nameMismatch'));
return; return;

View File

@@ -29,7 +29,7 @@ import { useNavigate, Link } from 'react-router-dom';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useApiMutation } from '@ema-platform/api'; import { useApiMutation } from '@ema-platform/api';
import { useErrorHandler, passwordSchema, PasswordRequirements, joinPersonName } from '@ema-platform/ui'; import { useErrorHandler, passwordSchema, PasswordRequirements } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell'; import { AuthShell } from '../components/AuthShell';
import { loginSuccess, setUser } from '../store/auth.slice'; import { loginSuccess, setUser } from '../store/auth.slice';
import type { AuthUser } from '../types/auth.types'; import type { AuthUser } from '../types/auth.types';
@@ -124,7 +124,7 @@ export function SignupPage() {
username: values.username, username: values.username,
phoneNumber: values.phoneNumber, phoneNumber: values.phoneNumber,
userType: values.userType, userType: values.userType,
name: { en: joinPersonName(values), am: values.nameAm ?? '' }, name: { en: values.nameEn, am: values.nameAm ?? '' },
password: values.password, password: values.password,
confirmPassword: values.confirmPassword, confirmPassword: values.confirmPassword,
}; };
@@ -213,30 +213,14 @@ export function SignupPage() {
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<Stack gap="md"> <Stack gap="md">
<SimpleGrid cols={{ base: 1, sm: 3 }} spacing="md"> <SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
<TextInput
label={t('signup.firstNameLabel', 'First name')}
placeholder={t('signup.firstNamePlaceholder', 'Abebe')}
leftSection={<IconUser size={18} />}
error={errors.firstName?.message}
{...register('firstName')}
/>
<TextInput <TextInput
label={t('signup.nameEnLabel', 'Full name (English)')} label={t('signup.nameEnLabel', 'Full name (English)')}
placeholder={t('signup.nameEnPlaceholder', 'Abebe Bekele')} placeholder={t('signup.nameEnPlaceholder', 'Abebe Bekele')}
leftSection={<IconUser size={18} />} leftSection={<IconUser size={18} />}
error={errors.middleName?.message} error={errors.nameEn?.message}
{...register('middleName')} {...register('nameEn')}
/> />
<TextInput
label={t('signup.lastNameLabel', 'Last name')}
placeholder={t('signup.lastNamePlaceholder', 'Bekele')}
leftSection={<IconUser size={18} />}
error={errors.lastName?.message}
{...register('lastName')}
/>
</SimpleGrid>
<TextInput <TextInput
label={t('signup.nameAmLabel', 'Name (Amharic)')} label={t('signup.nameAmLabel', 'Name (Amharic)')}
placeholder={t('signup.nameAmPlaceholder', 'ስም')} placeholder={t('signup.nameAmPlaceholder', 'ስም')}
@@ -244,6 +228,7 @@ export function SignupPage() {
error={errors.nameAm?.message} error={errors.nameAm?.message}
{...register('nameAm')} {...register('nameAm')}
/> />
</SimpleGrid>
<SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md"> <SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
<TextInput <TextInput