From d0b288a117a4dfc39b80a4b37c525b245cd7750b Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Wed, 29 Jul 2026 22:42:35 +0700 Subject: [PATCH] feat: add PhoneNumberInput component and integrate it into employee create and edit forms --- .../js/components/phone-number-input.tsx | 58 +++++++++++++++++++ .../js/pages/admin/hr/employee/create.tsx | 7 +-- resources/js/pages/admin/hr/employee/edit.tsx | 8 +-- 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 resources/js/components/phone-number-input.tsx diff --git a/resources/js/components/phone-number-input.tsx b/resources/js/components/phone-number-input.tsx new file mode 100644 index 0000000..029a26c --- /dev/null +++ b/resources/js/components/phone-number-input.tsx @@ -0,0 +1,58 @@ +import { useCallback, useRef, useState } from 'react'; +import { Input } from '@/components/ui/input'; + +type PhoneNumberInputProps = { + name?: string; + defaultValue?: string; + placeholder?: string; + disabled?: boolean; + className?: string; +}; + +function formatPhone(value: string): string { + const digits = value.replace(/[^0-9]/g, ''); + const groups: string[] = []; + for (let i = 0; i < digits.length; i += 4) { + groups.push(digits.slice(i, i + 4)); + } + return groups.join(' '); +} + +export function PhoneNumberInput({ + name, + defaultValue = '', + placeholder = '0812 3456 7890', + disabled = false, + className, +}: PhoneNumberInputProps) { + const [displayValue, setDisplayValue] = useState(formatPhone(defaultValue)); + const lastValidRef = useRef(displayValue); + + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const formatted = formatPhone(e.target.value); + lastValidRef.current = formatted; + setDisplayValue(formatted); + }, + [], + ); + + const handleBlur = useCallback(() => { + setDisplayValue(lastValidRef.current); + }, []); + + return ( + + ); +} diff --git a/resources/js/pages/admin/hr/employee/create.tsx b/resources/js/pages/admin/hr/employee/create.tsx index dea2471..a39485d 100644 --- a/resources/js/pages/admin/hr/employee/create.tsx +++ b/resources/js/pages/admin/hr/employee/create.tsx @@ -1,5 +1,6 @@ import { DatePicker } from '@/components/date-picker'; import InputError from '@/components/input-error'; +import { PhoneNumberInput } from '@/components/phone-number-input'; import { RupiahInput } from '@/components/rupiah-input'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; @@ -108,11 +109,7 @@ export default function EmployeeCreate() { - +
diff --git a/resources/js/pages/admin/hr/employee/edit.tsx b/resources/js/pages/admin/hr/employee/edit.tsx index 5a22e14..c045c2c 100644 --- a/resources/js/pages/admin/hr/employee/edit.tsx +++ b/resources/js/pages/admin/hr/employee/edit.tsx @@ -1,5 +1,6 @@ import { DatePicker } from '@/components/date-picker'; import InputError from '@/components/input-error'; +import { PhoneNumberInput } from '@/components/phone-number-input'; import { RupiahInput } from '@/components/rupiah-input'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; @@ -133,12 +134,7 @@ export default function EmployeeEdit({ employee }: Props) { - +