"use client" import { Select, SelectContent, SelectGroup, SelectItem, SelectSeparator, SelectTrigger, SelectValue } from "./select" import { Input } from "./input" import type { CountryCode } from 'libphonenumber-js' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { getCountryPhoneData, validatePhoneNumber, type CountryPhoneData } from '../../utils/country-phone-utils' export interface PhoneInputProps { value: string countryCode: CountryCode onPhoneChange: (phone: string) => void onCountryChange: (country: CountryCode) => void onValidationChange?: (isInvalid: boolean) => void disabled?: boolean placeholder?: string onKeyDown?: (e: React.KeyboardEvent) => void } export function PhoneInput({ value, countryCode, onPhoneChange, onCountryChange, onValidationChange, disabled, placeholder = "Phone Number (optional)", onKeyDown, }: PhoneInputProps) { const { priority, others } = useMemo(() => getCountryPhoneData(), []) const selectedCountry = useMemo( () => [...priority, ...others].find(c => c.code === countryCode), [countryCode, priority, others] ) const [isInvalid, setIsInvalid] = useState(false) const debounceRef = useRef>(null) const digitCount = useCallback((val: string) => val.replace(/[^0-9]/g, '').length, []) const runValidation = useCallback((phone: string) => { if (!phone || digitCount(phone) === 0) { setIsInvalid(false) onValidationChange?.(false) return } const invalid = !validatePhoneNumber(phone, countryCode) setIsInvalid(invalid) onValidationChange?.(invalid) }, [countryCode, digitCount, onValidationChange]) const debouncedValidation = useCallback((phone: string) => { if (debounceRef.current) clearTimeout(debounceRef.current) debounceRef.current = setTimeout(() => runValidation(phone), 300) }, [runValidation]) useEffect(() => { return () => { if (debounceRef.current) clearTimeout(debounceRef.current) } }, []) return (
{ const val = e.target.value if (val === '' || /^[0-9\-() ]*$/.test(val)) { onPhoneChange(val) if (digitCount(val) > 4) { debouncedValidation(val) } else if (digitCount(val) === 0) { setIsInvalid(false) onValidationChange?.(false) } } }} onBlur={() => runValidation(value)} disabled={disabled} placeholder={placeholder} onKeyDown={onKeyDown} className={`min-w-0 flex-1 ${isInvalid ? '!border-ods-warning' : ''}`} />
) } function CountryOption({ country }: { country: CountryPhoneData }) { return ( {country.flag} {country.dialCode} {country.name} ) }