"use client"; import { useEffect, useRef, useState } from "react"; import { Alert, Spinner } from "../UI"; import type { Branch } from "../../types/branch"; import type { Role } from "../../types/role"; import type { FormErrors, User, UserFormData } from "../../types/user"; // ── fixed styles ───────────────────────────────────────────────── const S = { input: { width: "100%", height: 40, padding: "0 0.75rem", borderRadius: "var(--radius-md)", border: "1px solid var(--color-border)", background: "var(--color-surface)", fontSize: 13, color: "var(--color-text-primary)", outline: "none", fontFamily: "var(--font-sans)", } as React.CSSProperties, label: { display: "flex", flexDirection: "column" as const, gap: 6, fontSize: 12, fontWeight: 600, color: "var(--color-text-secondary)", } as React.CSSProperties, errorText: { fontSize: 11, color: "var(--color-danger)", fontWeight: 500 } as React.CSSProperties, }; // ── macksure data validation ───────────────────────────────────────────────────── const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const PHONE_RE = /^\+?[0-9]{10,15}$/; function validate(data: UserFormData, isNew: boolean): FormErrors { const e: FormErrors = {}; if (!data.name.trim()) e.name = "الاسم الكامل مطلوب"; if (data.email && !EMAIL_RE.test(data.email)) e.email = "صيغة البريد الإلكتروني غير صحيحة"; if (!data.phone.trim()) e.phone = "رقم الهاتف مطلوب"; else if (!PHONE_RE.test(data.phone.replace(/\s/g, ""))) e.phone = "رقم هاتف غير صالح (10–15 رقم)"; if (isNew && !data.password) e.password = "كلمة المرور مطلوبة"; if (isNew && data.password && data.password.length < 6) e.password = "كلمة المرور 6 أحرف على الأقل"; if (!data.roleId) e.roleId = "الدور مطلوب"; if (!data.branchId) e.branchId = "الفرع مطلوب"; return e; } // ── Props ───────────────────────────────────────────────────────────────────── interface UserFormModalProps { editUser: User | null; roles: Role[]; branches: Branch[]; onClose: () => void; onSubmit: (data: UserFormData, isNew: boolean) => Promise; } // ── main component ──────────────────────────────────────────────────────────── export function UserFormModal({ editUser, roles, branches, onClose, onSubmit }: UserFormModalProps) { const isNew = editUser === null; const [form, setForm] = useState({ name: editUser?.name ?? "", email: editUser?.email ?? "", phone: editUser?.phone ?? "", password: "", roleId: editUser?.role?.id ?? "", branchId: editUser?.branch?.id ?? "", }); const [errors, setErrors] = useState({}); const [saving, setSaving] = useState(false); const [apiError, setApiError] = useState(""); const firstInputRef = useRef(null); useEffect(() => { firstInputRef.current?.focus(); }, []); useEffect(() => { const handler = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [onClose]); const set = (field: keyof UserFormData) => (e: React.ChangeEvent) => { setForm(p => ({ ...p, [field]: e.target.value })); if (errors[field]) setErrors(p => ({ ...p, [field]: undefined })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // makesure data is valid before sending to API const errs = validate(form, isNew); if (Object.keys(errs).length) { setErrors(errs); return; } // final check to prevent sending bad data to API (shouldn't happen because of validation, but just in case) if (!form.name.trim() || !form.phone.trim() || !form.roleId || !form.branchId) { setApiError("يرجى التأكد من إدخال جميع البيانات المطلوبة."); return; } setSaving(true); setApiError(""); const ok = await onSubmit(form, isNew); setSaving(false); if (ok) onClose(); else setApiError("حدث خطأ غير متوقع. يرجى المحاولة لاحقاً."); }; // dynamic styles for inputs with errors const inputStyle = (field: keyof FormErrors): React.CSSProperties => ({ ...S.input, ...(errors[field] ? { borderColor: "var(--color-danger)", background: "#FEF2F2" } : {}), }); return (
{ if (e.target === e.currentTarget) onClose(); }} style={{ position: "fixed", inset: 0, zIndex: 50, background: "rgba(15,23,42,0.55)", backdropFilter: "blur(4px)", display: "flex", alignItems: "center", justifyContent: "center", padding: "1rem", }} >
e.stopPropagation()} style={{ width: "100%", maxWidth: 520, background: "var(--color-surface)", borderRadius: "var(--radius-2xl)", border: "1px solid var(--color-border)", boxShadow: "0 24px 64px rgba(0,0,0,.18)", overflow: "hidden", }} > {/* header */}

{isNew ? "إضافة مستخدم" : "تعديل مستخدم"}

{/* body*/}
{apiError && setApiError("")} />} {/* name field*/} {/* email and phone fields */}
{/* password field */} {/* role and branch fields */}
{/* action buttons */}
); }