183 lines
5.1 KiB
TypeScript
183 lines
5.1 KiB
TypeScript
import { Form } from "@remix-run/react";
|
||
import { useState, useEffect } from "react";
|
||
import { Input } from "~/components/ui/Input";
|
||
import { Button } from "~/components/ui/Button";
|
||
import { Flex } from "~/components/layout/Flex";
|
||
import type { Customer } from "~/types/database";
|
||
|
||
interface CustomerFormProps {
|
||
customer?: Customer;
|
||
onCancel: () => void;
|
||
errors?: Record<string, string>;
|
||
isLoading: boolean;
|
||
}
|
||
|
||
export function CustomerForm({
|
||
customer,
|
||
onCancel,
|
||
errors = {},
|
||
isLoading,
|
||
}: CustomerFormProps) {
|
||
const [formData, setFormData] = useState({
|
||
name: customer?.name || "",
|
||
phone: customer?.phone || "",
|
||
email: customer?.email || "",
|
||
address: customer?.address || "",
|
||
});
|
||
|
||
// Reset form data when customer changes
|
||
useEffect(() => {
|
||
if (customer) {
|
||
setFormData({
|
||
name: customer.name || "",
|
||
phone: customer.phone || "",
|
||
email: customer.email || "",
|
||
address: customer.address || "",
|
||
});
|
||
} else {
|
||
setFormData({
|
||
name: "",
|
||
phone: "",
|
||
email: "",
|
||
address: "",
|
||
});
|
||
}
|
||
}, [customer]);
|
||
|
||
const handleInputChange = (field: string, value: string) => {
|
||
setFormData(prev => ({
|
||
...prev,
|
||
[field]: value,
|
||
}));
|
||
};
|
||
|
||
const isEditing = !!customer;
|
||
|
||
return (
|
||
<Form method="post" className="space-y-6">
|
||
<input
|
||
type="hidden"
|
||
name="_action"
|
||
value={isEditing ? "update" : "create"}
|
||
/>
|
||
{isEditing && (
|
||
<input type="hidden" name="id" value={customer.id} />
|
||
)}
|
||
|
||
{/* Customer Name */}
|
||
<div>
|
||
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-2">
|
||
اسم العميل *
|
||
</label>
|
||
<Input
|
||
id="name"
|
||
name="name"
|
||
type="text"
|
||
value={formData.name}
|
||
onChange={(e) => handleInputChange("name", e.target.value)}
|
||
placeholder="أدخل اسم العميل"
|
||
error={errors.name}
|
||
required
|
||
disabled={isLoading}
|
||
/>
|
||
{errors.name && (
|
||
<p className="mt-1 text-sm text-red-600">{errors.name}</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Phone Number */}
|
||
<div>
|
||
<label htmlFor="phone" className="block text-sm font-medium text-gray-700 mb-2">
|
||
رقم الهاتف
|
||
</label>
|
||
<Input
|
||
id="phone"
|
||
name="phone"
|
||
type="tel"
|
||
value={formData.phone}
|
||
onChange={(e) => handleInputChange("phone", e.target.value)}
|
||
placeholder="أدخل رقم الهاتف"
|
||
error={errors.phone}
|
||
disabled={isLoading}
|
||
dir="ltr"
|
||
/>
|
||
{errors.phone && (
|
||
<p className="mt-1 text-sm text-red-600">{errors.phone}</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Email */}
|
||
<div>
|
||
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
|
||
البريد الإلكتروني
|
||
</label>
|
||
<Input
|
||
id="email"
|
||
name="email"
|
||
type="email"
|
||
value={formData.email}
|
||
onChange={(e) => handleInputChange("email", e.target.value)}
|
||
placeholder="أدخل البريد الإلكتروني"
|
||
error={errors.email}
|
||
disabled={isLoading}
|
||
dir="ltr"
|
||
/>
|
||
{errors.email && (
|
||
<p className="mt-1 text-sm text-red-600">{errors.email}</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Address */}
|
||
<div>
|
||
<label htmlFor="address" className="block text-sm font-medium text-gray-700 mb-2">
|
||
العنوان
|
||
</label>
|
||
<textarea
|
||
id="address"
|
||
name="address"
|
||
value={formData.address}
|
||
onChange={(e) => handleInputChange("address", e.target.value)}
|
||
placeholder="أدخل عنوان العميل"
|
||
rows={3}
|
||
disabled={isLoading}
|
||
className={`
|
||
w-full px-3 py-2 border rounded-lg shadow-sm
|
||
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500
|
||
disabled:bg-gray-50 disabled:text-gray-500
|
||
${errors.address
|
||
? 'border-red-300 focus:ring-red-500 focus:border-red-500'
|
||
: 'border-gray-300'
|
||
}
|
||
`}
|
||
/>
|
||
{errors.address && (
|
||
<p className="mt-1 text-sm text-red-600">{errors.address}</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Form Actions */}
|
||
<Flex justify="end" className="pt-4 gap-2 border-t">
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
onClick={onCancel}
|
||
disabled={isLoading}
|
||
className="w-20"
|
||
>
|
||
إلغاء
|
||
</Button>
|
||
|
||
<Button
|
||
type="submit"
|
||
disabled={isLoading || !formData.name.trim()}
|
||
className="bg-blue-600 hover:bg-blue-700"
|
||
>
|
||
{isLoading
|
||
? (isEditing ? "جاري التحديث..." : "جاري الإنشاء...")
|
||
: (isEditing ? "تحديث العميل" : "إنشاء العميل")
|
||
}
|
||
</Button>
|
||
</Flex>
|
||
</Form>
|
||
);
|
||
} |