mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-30 09:58:13 +00:00
feat: implement reusable PhoneInput component with validation support and integrate across auth and portal modules.
This commit is contained in:
@@ -28,6 +28,7 @@ import { useDispatch } from "react-redux";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useApiMutation } from "@ema-platform/api";
|
||||
import { notify, useErrorHandler } from "@ema-platform/ui";
|
||||
import { isValidPhoneNumber, parsePhoneNumberFromString } from "libphonenumber-js";
|
||||
import { AuthShell } from "../components/AuthShell";
|
||||
import { loginSuccess, setUser, setCurrentProfile } from "../store/auth.slice";
|
||||
import type {
|
||||
@@ -67,24 +68,23 @@ export function LoginPage() {
|
||||
.string()
|
||||
.trim()
|
||||
.transform((value) => {
|
||||
// Convert 09xxxxxxxx -> +2519xxxxxxxx
|
||||
if (/^09\d{8}$/.test(value)) {
|
||||
return `+251${value.substring(1)}`;
|
||||
}
|
||||
|
||||
return value;
|
||||
// A phone-looking value normalizes to E.164 (bare Ethiopian
|
||||
// national numbers, e.g. 09xxxxxxxx, default to +251) so the
|
||||
// international check below can validate it; anything else
|
||||
// (an email) passes through untouched.
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (emailRegex.test(value)) return value;
|
||||
return parsePhoneNumberFromString(value, "ET")?.number ?? value;
|
||||
})
|
||||
.refine(
|
||||
(value) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const phoneRegex = /^\+2519\d{8}$/;
|
||||
|
||||
return emailRegex.test(value) || phoneRegex.test(value);
|
||||
return emailRegex.test(value) || isValidPhoneNumber(value);
|
||||
},
|
||||
{
|
||||
message: t(
|
||||
"login.emailOrPhoneInvalid",
|
||||
"Enter a valid email or phone number (+2519xxxxxxxx)",
|
||||
"Enter a valid email or phone number",
|
||||
),
|
||||
},
|
||||
),
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
IconAt,
|
||||
IconDeviceMobile,
|
||||
IconLock,
|
||||
IconMail,
|
||||
IconUser,
|
||||
@@ -29,7 +28,7 @@ import { useNavigate, Link } from 'react-router-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useApiMutation } from '@ema-platform/api';
|
||||
import { useErrorHandler, passwordSchema, PasswordRequirements } from '@ema-platform/ui';
|
||||
import { useErrorHandler, passwordSchema, PasswordRequirements, phoneNumber, PhoneInput } from '@ema-platform/ui';
|
||||
import { AuthShell } from '../components/AuthShell';
|
||||
import { loginSuccess, setUser } from '../store/auth.slice';
|
||||
import type { AuthUser } from '../types/auth.types';
|
||||
@@ -88,7 +87,7 @@ export function SignupPage() {
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
username: z.string().min(3, { message: t('signup.usernameMinLength', 'Username must be at least 3 characters') }),
|
||||
phoneNumber: z.string().min(1, { message: t('signup.phoneRequired', 'Phone number is required') }),
|
||||
phoneNumber,
|
||||
userType: z.literal('individual'),
|
||||
nameEn: z
|
||||
.string()
|
||||
@@ -111,6 +110,7 @@ export function SignupPage() {
|
||||
register,
|
||||
handleSubmit,
|
||||
watch,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
@@ -247,12 +247,12 @@ export function SignupPage() {
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<TextInput
|
||||
<PhoneInput
|
||||
label={t('signup.phoneLabel', 'Phone number')}
|
||||
placeholder={t('signup.phonePlaceholder', '+251 911 234 567')}
|
||||
leftSection={<IconDeviceMobile size={18} />}
|
||||
placeholder={t('signup.phonePlaceholder', '9XX XXX XXX')}
|
||||
value={watch('phoneNumber') || ''}
|
||||
onChange={(val) => setValue('phoneNumber', val, { shouldValidate: true })}
|
||||
error={errors.phoneNumber?.message}
|
||||
{...register('phoneNumber')}
|
||||
/>
|
||||
|
||||
<SimpleGrid cols={{ base: 1, xs: 2 }} spacing="md">
|
||||
|
||||
Reference in New Issue
Block a user