add input mask, edit valitation and validation message
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
'use client'
|
||||
|
||||
import { useState, ChangeEvent } from 'react';
|
||||
import styles from '@/app/styles/login.module.scss';
|
||||
|
||||
interface PhoneInputProps {
|
||||
phoneState: string | undefined;
|
||||
}
|
||||
|
||||
export default function PhoneInput({ phoneState }: PhoneInputProps) {
|
||||
const [phone, setPhone] = useState(phoneState ? phoneState : '');
|
||||
|
||||
const formatPhoneNumber = (value: string, isBackspace: boolean): string => {
|
||||
if (value === '+') {
|
||||
return value;
|
||||
}
|
||||
|
||||
const digitsOnly = value.replace(/\D/g, '');
|
||||
|
||||
if (!digitsOnly) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const limitedDigits = digitsOnly.slice(0, 11);
|
||||
const countryCode = limitedDigits.startsWith('8') ? '8' : '7';
|
||||
const phoneNumber = limitedDigits.startsWith('8') || limitedDigits.startsWith('7')
|
||||
? limitedDigits.slice(1)
|
||||
: limitedDigits;
|
||||
|
||||
let formatted = `+${countryCode}`;
|
||||
|
||||
if (phoneNumber.length > 0) {
|
||||
formatted += ` (${phoneNumber.slice(0, 3)}`;
|
||||
}
|
||||
if (phoneNumber.length >= 3) {
|
||||
formatted += `) ${phoneNumber.slice(3, 6)}`;
|
||||
}
|
||||
if (phoneNumber.length >= 6) {
|
||||
formatted += `-${phoneNumber.slice(6, 8)}`;
|
||||
}
|
||||
if (phoneNumber.length >= 8) {
|
||||
formatted += `-${phoneNumber.slice(8, 10)}`;
|
||||
}
|
||||
|
||||
if (isBackspace) {
|
||||
const lastChar = formatted[formatted.length - 1];
|
||||
const specialChars = ['-', '(', ')', ' '];
|
||||
|
||||
if (specialChars.includes(lastChar)) {
|
||||
if (lastChar === ' ' && formatted[formatted.length - 2] === ')') {
|
||||
return formatted.slice(0, -2);
|
||||
}
|
||||
return formatted.slice(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return formatted;
|
||||
};
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
const input = e.target.value;
|
||||
//@ts-ignore
|
||||
const isBackspace = e.nativeEvent.inputType === 'deleteContentBackward';
|
||||
const formatted = formatPhoneNumber(input, isBackspace);
|
||||
setPhone(formatted);
|
||||
};
|
||||
|
||||
return (
|
||||
<input
|
||||
type="phone"
|
||||
id="phone"
|
||||
name="phone"
|
||||
className={`${styles['form-input']}`}
|
||||
placeholder="+7 (999) 123-45-67"
|
||||
value={phone}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import styles from '@/app/styles/login.module.scss';
|
||||
import { useActionState } from 'react';
|
||||
import { registration } from '@/app/actions/auth';
|
||||
import PhoneInput from '@/app/ui/inputs/phone-input';
|
||||
|
||||
export default function RegisterForm() {
|
||||
const [state, formAction, isPending] = useActionState(
|
||||
@@ -48,15 +49,11 @@ export default function RegisterForm() {
|
||||
)}
|
||||
</div>
|
||||
<div className={`${styles['form-group']}`}>
|
||||
<label className={`${styles['form-label']}`}>Телефон</label>
|
||||
<input
|
||||
type="phone"
|
||||
id="phone"
|
||||
name="phone"
|
||||
className={`${styles['form-input']}`}
|
||||
placeholder="+7 (999) 123-45-67"
|
||||
defaultValue={state?.previousState?.phone ? state?.previousState?.phone : ''}
|
||||
/>
|
||||
<label className={`${styles['form-label']} ${styles['required']}`}>Телефон</label>
|
||||
<PhoneInput phoneState={state?.previousState?.phone} />
|
||||
{state?.error?.phone && (
|
||||
<p className="text-sm text-red-500">{state?.error?.phone}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${styles['form-group']}`}>
|
||||
@@ -103,11 +100,22 @@ export default function RegisterForm() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${styles['form-checkbox']}`} style={{ marginBottom: "20px" }}>
|
||||
<input type="checkbox" id="remember" name="remember" />
|
||||
<label>Я соглашаюсь с <a href="forgot-password" >условиями использования и политикой конфиденциальности</a></label>
|
||||
<div className={`${styles['form-checkbox']}`}>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="agree"
|
||||
name="agree"
|
||||
defaultChecked={state?.previousState?.agree ? true : false}
|
||||
/>
|
||||
<label htmlFor="agree">Я соглашаюсь с <a href="/" >условиями использования и политикой конфиденциальности</a></label>
|
||||
</div>
|
||||
<button type="submit" className={`${styles['btn']}`}>Создать аккаунт</button>
|
||||
</form>
|
||||
{state?.error?.agree && (
|
||||
<p className="text-sm text-red-500">{state?.error?.agree}</p>
|
||||
)}
|
||||
{state?.error?.server && (
|
||||
<p className="text-sm text-red-500">{state?.error?.server}</p>
|
||||
)}
|
||||
<button type="submit" className={`${styles['btn']}`} style={{ marginTop: "20px" }}>Создать аккаунт</button>
|
||||
</form >
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user