update client and client adresses pages also create branch pages and role pages and update some pages to be batter
This commit is contained in:
258
src/Components/Client_Adress/AddressDetails.tsx
Normal file
258
src/Components/Client_Adress/AddressDetails.tsx
Normal file
@@ -0,0 +1,258 @@
|
||||
"use client";
|
||||
|
||||
import type { ClientAddress } from "@/src/types/client_adresses";
|
||||
|
||||
// ─── Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
function labelIcon(label: string): string {
|
||||
const map: Record<string, string> = {
|
||||
"فوترة": "💳",
|
||||
"شحن": "📦",
|
||||
"المقر الرئيسي": "🏢",
|
||||
"فرع": "🏬",
|
||||
"مستودع": "🏭",
|
||||
billing: "💳",
|
||||
shipping: "📦",
|
||||
"head office": "🏢",
|
||||
branch: "🏬",
|
||||
warehouse: "🏭",
|
||||
};
|
||||
return map[label.toLowerCase()] ?? "📍";
|
||||
}
|
||||
|
||||
// ─── Sub-components ────────────────────────────────────────────────────────
|
||||
|
||||
function DetailRow({
|
||||
label,
|
||||
value,
|
||||
ltr = false,
|
||||
}: {
|
||||
label: string;
|
||||
value?: string | null;
|
||||
ltr?: boolean;
|
||||
}) {
|
||||
if (!value) return null;
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
padding: "0.75rem 0",
|
||||
borderBottom: "1px solid var(--color-border)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
color: "var(--color-text-muted)",
|
||||
textTransform: "uppercase",
|
||||
letterSpacing: "0.07em",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<span
|
||||
dir={ltr ? "ltr" : "rtl"}
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-text-primary)",
|
||||
fontFamily: ltr ? "var(--font-mono)" : "var(--font-sans)",
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SectionCard({
|
||||
title,
|
||||
icon,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
icon: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "var(--radius-xl)",
|
||||
border: "1px solid var(--color-border)",
|
||||
background: "var(--color-surface)",
|
||||
boxShadow: "var(--shadow-card)",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{/* Card header */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 10,
|
||||
padding: "0.875rem 1.5rem",
|
||||
borderBottom: "1px solid var(--color-border)",
|
||||
background: "var(--color-surface-muted)",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 16 }} aria-hidden="true">{icon}</span>
|
||||
<p
|
||||
style={{
|
||||
margin: 0,
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
color: "var(--color-text-secondary)",
|
||||
letterSpacing: "0.05em",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Card body */}
|
||||
<div
|
||||
dir="rtl"
|
||||
style={{ padding: "0 1.5rem" }}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Main component ────────────────────────────────────────────────────────
|
||||
|
||||
interface AddressDetailsProps {
|
||||
address: ClientAddress;
|
||||
}
|
||||
|
||||
export function AddressDetails({ address }: AddressDetailsProps) {
|
||||
const { details, contactPerson, location } = address;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1rem",
|
||||
}}
|
||||
>
|
||||
{/* Identity card — label + branch */}
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "var(--radius-xl)",
|
||||
border: "1px solid var(--color-border)",
|
||||
background: "var(--color-surface)",
|
||||
boxShadow: "var(--shadow-card)",
|
||||
padding: "1.25rem 1.5rem",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "1rem",
|
||||
}}
|
||||
dir="rtl"
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 52,
|
||||
height: 52,
|
||||
borderRadius: "var(--radius-lg)",
|
||||
background: "var(--color-brand-50)",
|
||||
border: "1px solid var(--color-brand-100)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
fontSize: 24,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{labelIcon(address.label)}
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<p
|
||||
style={{
|
||||
margin: 0,
|
||||
fontSize: 18,
|
||||
fontWeight: 700,
|
||||
color: "var(--color-text-primary)",
|
||||
}}
|
||||
>
|
||||
{address.label}
|
||||
</p>
|
||||
{address.branchName && (
|
||||
<p
|
||||
style={{
|
||||
margin: "3px 0 0",
|
||||
fontSize: 13,
|
||||
color: "var(--color-text-muted)",
|
||||
}}
|
||||
>
|
||||
{address.branchName}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Address details */}
|
||||
<SectionCard title="تفاصيل العنوان" icon="🗺️">
|
||||
<DetailRow label="الشارع" value={details.street} />
|
||||
<DetailRow label="المدينة" value={details.city} />
|
||||
<DetailRow label="المنطقة / الولاية" value={details.state} />
|
||||
<DetailRow label="الحي" value={details.district} />
|
||||
<DetailRow label="رقم المبنى" value={details.buildingNo} ltr />
|
||||
<DetailRow label="رقم الوحدة" value={details.unitNo} ltr />
|
||||
<DetailRow label="الرقم الإضافي" value={details.additionalNo} ltr />
|
||||
<DetailRow label="الرمز البريدي" value={details.zipCode} ltr />
|
||||
<DetailRow label="الشقة / الطابق" value={details.apartment} />
|
||||
<DetailRow label="الدولة" value={details.country} />
|
||||
</SectionCard>
|
||||
|
||||
{/* Contact person — only when present */}
|
||||
{(contactPerson?.name || contactPerson?.phone) && (
|
||||
<SectionCard title="جهة الاتصال" icon="👤">
|
||||
<DetailRow label="الاسم" value={contactPerson.name} />
|
||||
<DetailRow label="رقم الهاتف" value={contactPerson.phone} ltr />
|
||||
</SectionCard>
|
||||
)}
|
||||
|
||||
{/* Coordinates */}
|
||||
{location?.coordinates && (
|
||||
<SectionCard title="الإحداثيات الجغرافية" icon="📡">
|
||||
<DetailRow
|
||||
label="خط الطول (Longitude)"
|
||||
value={String(location.coordinates[0])}
|
||||
ltr
|
||||
/>
|
||||
<DetailRow
|
||||
label="خط العرض (Latitude)"
|
||||
value={String(location.coordinates[1])}
|
||||
ltr
|
||||
/>
|
||||
</SectionCard>
|
||||
)}
|
||||
|
||||
{/* System metadata */}
|
||||
<SectionCard title="معلومات النظام" icon="🕐">
|
||||
<DetailRow
|
||||
label="تاريخ الإنشاء"
|
||||
value={new Date(address.createdAt).toLocaleString("ar-SA", {
|
||||
dateStyle: "long",
|
||||
timeStyle: "short",
|
||||
})}
|
||||
/>
|
||||
<DetailRow
|
||||
label="آخر تحديث"
|
||||
value={new Date(address.updatedAt).toLocaleString("ar-SA", {
|
||||
dateStyle: "long",
|
||||
timeStyle: "short",
|
||||
})}
|
||||
/>
|
||||
</SectionCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
type CreateAddressFormValues,
|
||||
type UpdateAddressFormValues,
|
||||
} from "@/src/validations/client_address.validator";
|
||||
import type { ClientAddress } from "@/src/types/client";
|
||||
import type { ClientAddress } from "@/src/types/client_adresses";
|
||||
|
||||
// ── Styles ─────────────────────────────────────────────────────────────────
|
||||
const S = {
|
||||
@@ -50,12 +50,9 @@ const S = {
|
||||
} as React.CSSProperties,
|
||||
};
|
||||
|
||||
// FIX 2: Use only the `border` shorthand in both branches — no borderColor/border conflict
|
||||
const withError = (hasError: boolean): React.CSSProperties => ({
|
||||
...S.input,
|
||||
border: hasError
|
||||
? "1px solid var(--color-danger)"
|
||||
: "1px solid var(--color-border)",
|
||||
border: hasError ? "1px solid var(--color-danger)" : "1px solid var(--color-border)",
|
||||
background: hasError ? "#FEF2F2" : S.input.background,
|
||||
});
|
||||
|
||||
@@ -63,39 +60,27 @@ const withError = (hasError: boolean): React.CSSProperties => ({
|
||||
interface AddressFormModalProps {
|
||||
editAddress: ClientAddress | null;
|
||||
onClose: () => void;
|
||||
// FIX: removed the "isNew" second argument. The parent (page.tsx) now
|
||||
// figures out create-vs-update itself from addrFormTarget, so it no longer
|
||||
// needs us to tell it isNew. This avoids the two values (isNew here vs
|
||||
// addrFormTarget there) ever disagreeing with each other.
|
||||
onSubmit: (
|
||||
data: CreateAddressFormValues | UpdateAddressFormValues
|
||||
) => Promise<boolean>;
|
||||
onSubmit: (data: CreateAddressFormValues | UpdateAddressFormValues) => Promise<boolean>;
|
||||
}
|
||||
|
||||
// ── Component ──────────────────────────────────────────────────────────────
|
||||
export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressFormModalProps) {
|
||||
const isNew = editAddress === null;
|
||||
|
||||
// NOTE: "schema" variable removed — resolver now picks createAddressSchema
|
||||
// or updateAddressSchema directly inline (see useForm below).
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
setError,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm<CreateAddressFormValues | UpdateAddressFormValues>({
|
||||
// FIX: "as never" was hiding all type errors on resolver/errors.
|
||||
// yupResolver only works with ONE concrete schema type, not a union,
|
||||
// so we still need a cast — but cast to the real Resolver type instead
|
||||
// of "never", so formState.errors keeps proper typing.
|
||||
resolver: (isNew ? yupResolver(createAddressSchema) : yupResolver(updateAddressSchema)) as Resolver<
|
||||
CreateAddressFormValues | UpdateAddressFormValues
|
||||
>,
|
||||
resolver: (isNew
|
||||
? yupResolver(createAddressSchema)
|
||||
: yupResolver(updateAddressSchema)
|
||||
) as Resolver<CreateAddressFormValues | UpdateAddressFormValues>,
|
||||
|
||||
defaultValues: {
|
||||
label: editAddress?.label ?? "",
|
||||
branchName: editAddress?.branchName ?? "",
|
||||
isPrimary: editAddress?.isPrimary ?? false,
|
||||
|
||||
contactPerson: {
|
||||
name: editAddress?.contactPerson?.name ?? "",
|
||||
@@ -121,9 +106,9 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
},
|
||||
});
|
||||
|
||||
const detailsErr = (errors as never as Record<string, Record<string, { message?: string }>>)?.details ?? {};
|
||||
const contactErr = (errors as never as Record<string, Record<string, { message?: string }>>)?.contactPerson ?? {};
|
||||
const locationErr = (errors as never as Record<string, Record<string, { message?: string }>>)?.location ?? {};
|
||||
const detailsErr = (errors as any)?.details ?? {};
|
||||
const contactErr = (errors as any)?.contactPerson ?? {};
|
||||
const locationErr = (errors as any)?.location ?? {};
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); };
|
||||
@@ -132,7 +117,7 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
}, [onClose]);
|
||||
|
||||
const submitHandler = async (data: CreateAddressFormValues | UpdateAddressFormValues) => {
|
||||
const ok = await onSubmit(data); // FIX: no more isNew arg, see prop type above
|
||||
const ok = await onSubmit(data);
|
||||
if (ok) {
|
||||
onClose();
|
||||
} else {
|
||||
@@ -173,7 +158,7 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{/* Header — pinned */}
|
||||
{/* Header */}
|
||||
<div
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
@@ -186,26 +171,12 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<p
|
||||
style={{
|
||||
fontSize: 11,
|
||||
letterSpacing: "0.3em",
|
||||
textTransform: "uppercase",
|
||||
color: "#2563EB",
|
||||
fontWeight: 600,
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
<p style={{ fontSize: 11, letterSpacing: "0.3em", textTransform: "uppercase", color: "#2563EB", fontWeight: 600, margin: 0 }}>
|
||||
{isNew ? "إضافة عنوان" : "تعديل عنوان"}
|
||||
</p>
|
||||
<h2
|
||||
id="addr-modal-title"
|
||||
style={{
|
||||
fontSize: 17,
|
||||
fontWeight: 700,
|
||||
color: "var(--color-text-primary)",
|
||||
margin: "4px 0 0",
|
||||
}}
|
||||
style={{ fontSize: 17, fontWeight: 700, color: "var(--color-text-primary)", margin: "4px 0 0" }}
|
||||
>
|
||||
{isNew ? "عنوان جديد" : editAddress?.label}
|
||||
</h2>
|
||||
@@ -237,12 +208,7 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
<form
|
||||
onSubmit={handleSubmit(submitHandler)}
|
||||
noValidate
|
||||
style={{
|
||||
padding: "1.5rem",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1rem",
|
||||
}}
|
||||
style={{ padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1rem" }}
|
||||
>
|
||||
{errors.label?.type === "manual" && (
|
||||
<Alert type="error" message={errors.label.message ?? ""} onClose={() => {}} />
|
||||
@@ -251,58 +217,22 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
{/* Address Meta */}
|
||||
<p style={S.sectionTitle}>بيانات العنوان</p>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr auto",
|
||||
gap: "0.75rem",
|
||||
alignItems: "end",
|
||||
}}
|
||||
>
|
||||
{/* FIX 3: Replaced <select> with a free-text <input> */}
|
||||
<label style={S.label}>
|
||||
نوع العنوان
|
||||
<input
|
||||
{...register("label")}
|
||||
style={withError(!!errors.label && errors.label.type !== "manual")}
|
||||
placeholder="مقترح: منزل / مكتب"
|
||||
dir="rtl"
|
||||
/>
|
||||
{errors.label && errors.label.type !== "manual" && (
|
||||
<span style={S.errorText}>{errors.label.message}</span>
|
||||
)}
|
||||
</label>
|
||||
|
||||
<label
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
color: "var(--color-text-secondary)",
|
||||
paddingBottom: 2,
|
||||
cursor: "pointer",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
{...register("isPrimary")}
|
||||
style={{ width: 14, height: 14, cursor: "pointer" }}
|
||||
/>
|
||||
عنوان رئيسي
|
||||
</label>
|
||||
</div>
|
||||
<label style={S.label}>
|
||||
نوع العنوان
|
||||
<input
|
||||
{...register("label")}
|
||||
style={withError(!!errors.label && errors.label.type !== "manual")}
|
||||
placeholder="مثال: منزل / مكتب / شحن"
|
||||
dir="rtl"
|
||||
/>
|
||||
{errors.label && errors.label.type !== "manual" && (
|
||||
<span style={S.errorText}>{errors.label.message}</span>
|
||||
)}
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
اسم الفرع (اختياري)
|
||||
<input
|
||||
{...register("branchName")}
|
||||
style={S.input}
|
||||
placeholder="فرع الرياض"
|
||||
dir="rtl"
|
||||
/>
|
||||
<input {...register("branchName")} style={S.input} placeholder="فرع الرياض" dir="rtl" />
|
||||
</label>
|
||||
|
||||
{/* Address Details */}
|
||||
@@ -316,119 +246,60 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
placeholder="شارع الملك فهد، مبنى 12"
|
||||
dir="rtl"
|
||||
/>
|
||||
{detailsErr.street && (
|
||||
<span style={S.errorText}>{detailsErr.street.message}</span>
|
||||
)}
|
||||
{detailsErr.street && <span style={S.errorText}>{detailsErr.street.message}</span>}
|
||||
</label>
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
المدينة {isNew && "*"}
|
||||
<input
|
||||
{...register("details.city")}
|
||||
style={withError(!!detailsErr.city)}
|
||||
placeholder="الرياض"
|
||||
dir="rtl"
|
||||
/>
|
||||
{detailsErr.city && (
|
||||
<span style={S.errorText}>{detailsErr.city.message}</span>
|
||||
)}
|
||||
<input {...register("details.city")} style={withError(!!detailsErr.city)} placeholder="الرياض" dir="rtl" />
|
||||
{detailsErr.city && <span style={S.errorText}>{detailsErr.city.message}</span>}
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
المنطقة
|
||||
<input
|
||||
{...register("details.state")}
|
||||
style={withError(!!detailsErr.state)}
|
||||
placeholder="منطقة الرياض"
|
||||
dir="rtl"
|
||||
/>
|
||||
{detailsErr.state && (
|
||||
<span style={S.errorText}>{detailsErr.state.message}</span>
|
||||
)}
|
||||
<input {...register("details.state")} style={withError(!!detailsErr.state)} placeholder="منطقة الرياض" dir="rtl" />
|
||||
{detailsErr.state && <span style={S.errorText}>{detailsErr.state.message}</span>}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
الحي (اختياري)
|
||||
<input
|
||||
{...register("details.district")}
|
||||
style={S.input}
|
||||
placeholder="حي العليا"
|
||||
dir="rtl"
|
||||
/>
|
||||
<input {...register("details.district")} style={S.input} placeholder="حي العليا" dir="rtl" />
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
رقم المبنى (اختياري)
|
||||
<input
|
||||
{...register("details.buildingNo")}
|
||||
style={S.input}
|
||||
placeholder="1234"
|
||||
dir="ltr"
|
||||
/>
|
||||
<input {...register("details.buildingNo")} style={S.input} placeholder="1234" dir="ltr" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
رقم الوحدة (اختياري)
|
||||
<input
|
||||
{...register("details.unitNo")}
|
||||
style={S.input}
|
||||
placeholder="5678"
|
||||
dir="ltr"
|
||||
/>
|
||||
<input {...register("details.unitNo")} style={S.input} placeholder="5678" dir="ltr" />
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
الرقم الإضافي (اختياري)
|
||||
<input
|
||||
{...register("details.additionalNo")}
|
||||
style={S.input}
|
||||
placeholder="0000"
|
||||
dir="ltr"
|
||||
/>
|
||||
<input {...register("details.additionalNo")} style={S.input} placeholder="0000" dir="ltr" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
الرمز البريدي (اختياري)
|
||||
<input
|
||||
{...register("details.zipCode")}
|
||||
style={withError(!!detailsErr.zipCode)}
|
||||
placeholder="11564"
|
||||
dir="ltr"
|
||||
/>
|
||||
{detailsErr.zipCode && (
|
||||
<span style={S.errorText}>{detailsErr.zipCode.message}</span>
|
||||
)}
|
||||
<input {...register("details.zipCode")} style={withError(!!detailsErr.zipCode)} placeholder="11564" dir="ltr" />
|
||||
{detailsErr.zipCode && <span style={S.errorText}>{detailsErr.zipCode.message}</span>}
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
الدولة
|
||||
<input
|
||||
{...register("details.country")}
|
||||
style={withError(!!detailsErr.country)}
|
||||
placeholder="SA"
|
||||
dir="ltr"
|
||||
/>
|
||||
{detailsErr.country && (
|
||||
<span style={S.errorText}>{detailsErr.country.message}</span>
|
||||
)}
|
||||
<input {...register("details.country")} style={withError(!!detailsErr.country)} placeholder="SA" dir="ltr" />
|
||||
{detailsErr.country && <span style={S.errorText}>{detailsErr.country.message}</span>}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label style={S.label}>
|
||||
الشقة / الطابق (اختياري)
|
||||
<input
|
||||
{...register("details.apartment")}
|
||||
style={S.input}
|
||||
placeholder="الطابق الثالث"
|
||||
dir="rtl"
|
||||
/>
|
||||
<input {...register("details.apartment")} style={S.input} placeholder="الطابق الثالث" dir="rtl" />
|
||||
</label>
|
||||
|
||||
{/* Contact Person */}
|
||||
@@ -437,29 +308,13 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
الاسم
|
||||
<input
|
||||
{...register("contactPerson.name")}
|
||||
style={withError(!!contactErr.name)}
|
||||
placeholder="أحمد محمد"
|
||||
dir="rtl"
|
||||
/>
|
||||
{contactErr.name && (
|
||||
<span style={S.errorText}>{contactErr.name.message}</span>
|
||||
)}
|
||||
<input {...register("contactPerson.name")} style={withError(!!contactErr.name)} placeholder="أحمد محمد" dir="rtl" />
|
||||
{contactErr.name && <span style={S.errorText}>{contactErr.name.message}</span>}
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
رقم الهاتف
|
||||
<input
|
||||
{...register("contactPerson.phone")}
|
||||
style={withError(!!contactErr.phone)}
|
||||
type="tel"
|
||||
placeholder="05xxxxxxxx"
|
||||
dir="ltr"
|
||||
/>
|
||||
{contactErr.phone && (
|
||||
<span style={S.errorText}>{contactErr.phone.message}</span>
|
||||
)}
|
||||
<input {...register("contactPerson.phone")} style={withError(!!contactErr.phone)} type="tel" placeholder="05xxxxxxxx" dir="ltr" />
|
||||
{contactErr.phone && <span style={S.errorText}>{contactErr.phone.message}</span>}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -469,41 +324,17 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }}>
|
||||
<label style={S.label}>
|
||||
خط الطول (Longitude) {isNew && "*"}
|
||||
<input
|
||||
{...register("location.coordinates.0" as never)}
|
||||
style={withError(!!locationErr.coordinates)}
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="46.6753"
|
||||
dir="ltr"
|
||||
/>
|
||||
<input {...register("location.coordinates.0" as never)} style={withError(!!locationErr.coordinates)} type="number" step="any" placeholder="46.6753" dir="ltr" />
|
||||
</label>
|
||||
|
||||
<label style={S.label}>
|
||||
خط العرض (Latitude) {isNew && "*"}
|
||||
<input
|
||||
{...register("location.coordinates.1" as never)}
|
||||
style={withError(!!locationErr.coordinates)}
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="24.7136"
|
||||
dir="ltr"
|
||||
/>
|
||||
{locationErr.coordinates && (
|
||||
<span style={S.errorText}>{locationErr.coordinates.message}</span>
|
||||
)}
|
||||
<input {...register("location.coordinates.1" as never)} style={withError(!!locationErr.coordinates)} type="number" step="any" placeholder="24.7136" dir="ltr" />
|
||||
{locationErr.coordinates && <span style={S.errorText}>{locationErr.coordinates.message}</span>}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "0.5rem",
|
||||
justifyContent: "flex-end",
|
||||
paddingTop: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", gap: "0.5rem", justifyContent: "flex-end", paddingTop: "0.5rem" }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
@@ -531,9 +362,7 @@ export function AddressFormModal({ editAddress, onClose, onSubmit }: AddressForm
|
||||
padding: "0 1.5rem",
|
||||
borderRadius: "var(--radius-md)",
|
||||
border: "none",
|
||||
background: isSubmitting
|
||||
? "var(--color-brand-400)"
|
||||
: "var(--color-brand-600)",
|
||||
background: isSubmitting ? "var(--color-brand-400)" : "var(--color-brand-600)",
|
||||
fontSize: 13,
|
||||
fontWeight: 700,
|
||||
color: "#FFF",
|
||||
|
||||
Reference in New Issue
Block a user