feat: add PhoneNumberInput component and integrate it into employee create and edit forms
This commit is contained in:
parent
da30f12fc2
commit
d0b288a117
58
resources/js/components/phone-number-input.tsx
Normal file
58
resources/js/components/phone-number-input.tsx
Normal file
@ -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<HTMLInputElement>) => {
|
||||||
|
const formatted = formatPhone(e.target.value);
|
||||||
|
lastValidRef.current = formatted;
|
||||||
|
setDisplayValue(formatted);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleBlur = useCallback(() => {
|
||||||
|
setDisplayValue(lastValidRef.current);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
name={name}
|
||||||
|
type="text"
|
||||||
|
inputMode="tel"
|
||||||
|
value={displayValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
placeholder={placeholder}
|
||||||
|
disabled={disabled}
|
||||||
|
className={className}
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import { DatePicker } from '@/components/date-picker';
|
import { DatePicker } from '@/components/date-picker';
|
||||||
import InputError from '@/components/input-error';
|
import InputError from '@/components/input-error';
|
||||||
|
import { PhoneNumberInput } from '@/components/phone-number-input';
|
||||||
import { RupiahInput } from '@/components/rupiah-input';
|
import { RupiahInput } from '@/components/rupiah-input';
|
||||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@ -108,11 +109,7 @@ export default function EmployeeCreate() {
|
|||||||
<Label htmlFor="phone_number">
|
<Label htmlFor="phone_number">
|
||||||
Nomor HP
|
Nomor HP
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<PhoneNumberInput name="phone_number"/>
|
||||||
id="phone_number"
|
|
||||||
name="phone_number"
|
|
||||||
placeholder="Masukkan nomor HP"
|
|
||||||
/>
|
|
||||||
<InputError message={errors.phone_number} />
|
<InputError message={errors.phone_number} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { DatePicker } from '@/components/date-picker';
|
import { DatePicker } from '@/components/date-picker';
|
||||||
import InputError from '@/components/input-error';
|
import InputError from '@/components/input-error';
|
||||||
|
import { PhoneNumberInput } from '@/components/phone-number-input';
|
||||||
import { RupiahInput } from '@/components/rupiah-input';
|
import { RupiahInput } from '@/components/rupiah-input';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
@ -133,12 +134,7 @@ export default function EmployeeEdit({ employee }: Props) {
|
|||||||
<Label htmlFor="phone_number">
|
<Label htmlFor="phone_number">
|
||||||
Nomor HP
|
Nomor HP
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<PhoneNumberInput name="phone_number"/>
|
||||||
id="phone_number"
|
|
||||||
name="phone_number"
|
|
||||||
placeholder="Masukkan nomor HP"
|
|
||||||
defaultValue={employee.user_profile?.phone_number ?? ''}
|
|
||||||
/>
|
|
||||||
<InputError message={errors.phone_number} />
|
<InputError message={errors.phone_number} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user