Replace all native <select> elements in the admin panel with SearchableSelect for a consistent UI experience. This change enhances accessibility, supports RTL and dark mode, and improves the overall design by utilizing a common component. The updates include adjustments to state management and event handling to ensure seamless integration with existing functionality across various pages and components.

This commit is contained in:
hamed
2026-07-16 08:56:59 +03:30
parent 7b8a5c2775
commit b1b99903ec
21 changed files with 571 additions and 288 deletions
+29 -40
View File
@@ -1393,29 +1393,25 @@ function MyPatientsPageInner() {
>
<div className="field" style={{ flexDirection: "column", alignItems: "stretch", height: "auto", gap: 5, padding: 0, border: "none", background: "none" }}>
<label style={{ fontSize: 12.5, fontWeight: 600 }}>بیمه پایه</label>
<select
className="input"
value={baseInsuranceId}
onChange={(e) => applyBaseInsurance(e.target.value)}
>
<option value="">بدون بیمه پایه</option>
{baseInsuranceOptions.map((o) => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
<SearchableSelect
options={baseInsuranceOptions}
value={baseInsuranceId || null}
onChange={(v) => applyBaseInsurance(v ? String(v) : "")}
placeholder="بدون بیمه پایه"
isClearable
height={38}
/>
</div>
<div className="field" style={{ flexDirection: "column", alignItems: "stretch", height: "auto", gap: 5, padding: 0, border: "none", background: "none" }}>
<label style={{ fontSize: 12.5, fontWeight: 600 }}>بیمه تکمیلی</label>
<select
className="input"
value={suppInsuranceId}
onChange={(e) => applySuppInsurance(e.target.value)}
>
<option value="">بدون بیمه تکمیلی</option>
{suppInsuranceOptions.map((o) => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
<SearchableSelect
options={suppInsuranceOptions}
value={suppInsuranceId || null}
onChange={(v) => applySuppInsurance(v ? String(v) : "")}
placeholder="بدون بیمه تکمیلی"
isClearable
height={38}
/>
</div>
</div>
<div
@@ -1460,17 +1456,14 @@ function MyPatientsPageInner() {
</div>
</div>
<div style={{ fontWeight: 700, fontSize: 13.5, color: "var(--text-2)", borderTop: "1px solid var(--border)", paddingTop: 12 }}>پرداخت و یادداشت</div>
<div className="field">
<div className="field" style={{ flexDirection: "column", alignItems: "stretch", height: "auto", gap: 5, padding: 0, border: "none", background: "none" }}>
<label>روش پرداخت</label>
<select {...form.register("payment_method")}>
{Object.entries(PAYMENT_LABELS).map(
([v, l]) => (
<option key={v} value={v}>
{l}
</option>
),
)}
</select>
<SearchableSelect
options={Object.entries(PAYMENT_LABELS).map(([v, l]) => ({ value: v, label: l }))}
value={form.watch("payment_method")}
onChange={(v) => form.setValue("payment_method", v as "cash" | "card" | "insurance" | "online" | "pending", { shouldDirty: true })}
height={38}
/>
</div>
<div className="field">
<label>یادداشت</label>
@@ -2026,18 +2019,14 @@ function EditSessionModal({
return (
<Modal open={!!session} onClose={onClose} title="ویرایش مراجعه">
<div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
<div className="field">
<div className="field" style={{ flexDirection: "column", alignItems: "stretch", height: "auto", gap: 5, padding: 0, border: "none", background: "none" }}>
<label>روش پرداخت</label>
<select
<SearchableSelect
options={Object.entries(PAYMENT_LABELS).map(([v, l]) => ({ value: v, label: l }))}
value={method}
onChange={(e) => setMethod(e.target.value)}
>
{Object.entries(PAYMENT_LABELS).map(([v, l]) => (
<option key={v} value={v}>
{l}
</option>
))}
</select>
onChange={(v) => setMethod(v ? String(v) : "cash")}
height={38}
/>
</div>
<div className="field">
<label>یادداشت</label>