2025-12-08 13:57:26 +07:00
|
|
|
'use client'
|
|
|
|
|
|
2025-12-22 17:19:59 +07:00
|
|
|
import { useState, ChangeEvent, useEffect, useRef, KeyboardEvent } from 'react';
|
2025-12-08 13:57:26 +07:00
|
|
|
import styles from '@/app/styles/login.module.scss';
|
|
|
|
|
|
|
|
|
|
interface PhoneInputProps {
|
|
|
|
|
phoneState: string | undefined;
|
2025-12-22 13:02:39 +07:00
|
|
|
validateHandler: (e: ChangeEvent<HTMLInputElement>) => void;
|
2025-12-08 13:57:26 +07:00
|
|
|
}
|
|
|
|
|
|
2025-12-22 13:02:39 +07:00
|
|
|
export default function PhoneInput({ phoneState, validateHandler }: PhoneInputProps) {
|
2025-12-08 13:57:26 +07:00
|
|
|
const [phone, setPhone] = useState(phoneState ? phoneState : '');
|
2025-12-22 17:19:59 +07:00
|
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
2025-12-08 13:57:26 +07:00
|
|
|
|
|
|
|
|
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);
|
2025-12-16 21:04:55 +07:00
|
|
|
const countryCode = 7;
|
|
|
|
|
const phoneNumber = limitedDigits.startsWith('7')
|
2025-12-08 13:57:26 +07:00
|
|
|
? 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;
|
2025-12-22 17:19:59 +07:00
|
|
|
const nativeEvent = e.nativeEvent as InputEvent;
|
|
|
|
|
const isBackspace = nativeEvent.inputType === 'deleteContentBackward';
|
2025-12-08 13:57:26 +07:00
|
|
|
const formatted = formatPhoneNumber(input, isBackspace);
|
|
|
|
|
setPhone(formatted);
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-22 17:19:59 +07:00
|
|
|
const range = useRef<{
|
|
|
|
|
start: number | null,
|
|
|
|
|
key: string;
|
|
|
|
|
} | null>(null);
|
|
|
|
|
|
|
|
|
|
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
|
|
|
|
|
const input = e.currentTarget;
|
|
|
|
|
range.current = {
|
|
|
|
|
start: input.selectionStart,
|
|
|
|
|
key: e.key
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log('use');
|
|
|
|
|
if (range.current?.key === 'Backspace' && inputRef.current) {
|
|
|
|
|
const startPos = range.current.start ?? 0;
|
|
|
|
|
const newPosition = Math.max(0, startPos - 1);
|
|
|
|
|
inputRef.current.setSelectionRange(newPosition, newPosition);
|
|
|
|
|
} else if (range.current?.key === 'Delete' && inputRef.current) {
|
|
|
|
|
inputRef.current.setSelectionRange(range.current.start, range.current.start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}, [phone]);
|
|
|
|
|
|
2025-12-08 13:57:26 +07:00
|
|
|
return (
|
|
|
|
|
<input
|
|
|
|
|
type="phone"
|
|
|
|
|
id="phone"
|
|
|
|
|
name="phone"
|
2025-12-22 17:19:59 +07:00
|
|
|
ref={inputRef}
|
2025-12-08 13:57:26 +07:00
|
|
|
className={`${styles['form-input']}`}
|
|
|
|
|
placeholder="+7 (999) 123-45-67"
|
|
|
|
|
value={phone}
|
2025-12-22 13:02:39 +07:00
|
|
|
onChange={(e) => {
|
|
|
|
|
handleChange(e);
|
|
|
|
|
validateHandler(e);
|
|
|
|
|
}}
|
2025-12-22 17:19:59 +07:00
|
|
|
onKeyDown={(e) => {
|
|
|
|
|
handleKeyDown(e);
|
|
|
|
|
}}
|
2025-12-08 13:57:26 +07:00
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
}
|