refactor(ui): unify remaining native selects (claims/sms/wallet/secretaries)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { api } from '../lib/api';
|
||||
import { formatRial, formatNumber } from '../lib/utils';
|
||||
import PageHeader from '../components/ui/PageHeader';
|
||||
import Modal from '../components/ui/Modal';
|
||||
import SearchableSelect from '../components/ui/SearchableSelect';
|
||||
|
||||
interface ClaimItem {
|
||||
invoice_item_id: number;
|
||||
@@ -105,11 +106,14 @@ export default function ClaimsPage() {
|
||||
<div className="card" style={{ padding: 18 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
|
||||
<h2 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>مطالبات</h2>
|
||||
<select className="input" style={{ maxWidth: 160 }} value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
|
||||
{STATUS_FILTERS.map((s) => (
|
||||
<option key={s} value={s}>{s === '' ? 'همه وضعیتها' : STATUS_META[s]?.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<div style={{ minWidth: 160 }}>
|
||||
<SearchableSelect
|
||||
options={STATUS_FILTERS.map((s) => ({ value: s, label: s === '' ? 'همه وضعیتها' : STATUS_META[s]?.label ?? s }))}
|
||||
value={statusFilter}
|
||||
onChange={(v) => setStatusFilter(v ? String(v) : '')}
|
||||
placeholder="همه وضعیتها"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{claimsQuery.isLoading ? (
|
||||
|
||||
@@ -23,6 +23,7 @@ import type { ApiResponse } from "../lib/api";
|
||||
import { api } from "../lib/api";
|
||||
import { formatDate, maskMobile, iranMobileSchema } from "../lib/utils";
|
||||
import MobileInput from "../components/ui/MobileInput";
|
||||
import SearchableSelect from "../components/ui/SearchableSelect";
|
||||
import { useAuthStore } from "../stores/authStore";
|
||||
import type { Secretary, SecretaryPermissions } from "../types";
|
||||
|
||||
@@ -525,22 +526,14 @@ export default function MySecretariesPage() {
|
||||
پزشک اضافه کنید.
|
||||
</p>
|
||||
) : (
|
||||
<select
|
||||
value={selectedDoctorUuid}
|
||||
onChange={(e) =>
|
||||
setSelectedDoctorUuid(e.target.value)
|
||||
}
|
||||
style={{ width: "100%", maxWidth: 360 }}
|
||||
>
|
||||
<option value="">
|
||||
— یک پزشک را انتخاب کنید —
|
||||
</option>
|
||||
{clinicDoctors.map((d) => (
|
||||
<option key={d.uuid} value={d.uuid}>
|
||||
{d.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div style={{ maxWidth: 360 }}>
|
||||
<SearchableSelect
|
||||
options={clinicDoctors.map((d) => ({ value: d.uuid, label: d.name }))}
|
||||
value={selectedDoctorUuid}
|
||||
onChange={(v) => setSelectedDoctorUuid(v ? String(v) : "")}
|
||||
placeholder="یک پزشک را انتخاب کنید"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import StatusBadge from '../components/ui/StatusBadge';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
import ConfirmDialog from '../components/ui/ConfirmDialog';
|
||||
import Modal from '../components/ui/Modal';
|
||||
import SearchableSelect from '../components/ui/SearchableSelect';
|
||||
|
||||
const templateSchema = z.object({
|
||||
name: z.string().min(2, 'نام قالب الزامی است'),
|
||||
@@ -443,16 +444,14 @@ export default function SmsPage() {
|
||||
{activeTab === 'logs' && (
|
||||
<>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<select
|
||||
className="input"
|
||||
style={{ maxWidth: 200 }}
|
||||
value={tagFilter}
|
||||
onChange={(e) => { setTagFilter(e.target.value); setPage(1); }}
|
||||
>
|
||||
{TAG_FILTER_OPTIONS.map((o) => (
|
||||
<option key={o.value} value={o.value}>{o.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<div style={{ width: 200 }}>
|
||||
<SearchableSelect
|
||||
options={TAG_FILTER_OPTIONS.map((o) => ({ value: o.value, label: o.label }))}
|
||||
value={tagFilter}
|
||||
onChange={(v) => { setTagFilter(v ? String(v) : ''); setPage(1); }}
|
||||
placeholder="همه تگها"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DataTable<SmsLog>
|
||||
columns={logColumns}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { usePaymentConfig } from '../hooks/usePaymentConfig';
|
||||
import { formatRial, formatNumber, formatDateTime } from '../lib/utils';
|
||||
import Modal from '../components/ui/Modal';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
import SearchableSelect from '../components/ui/SearchableSelect';
|
||||
import PageHeader from '../components/ui/PageHeader';
|
||||
import FeatureGate from '../components/ui/FeatureGate';
|
||||
|
||||
@@ -220,16 +221,14 @@ function SmsWalletPageInner() {
|
||||
{currentSettings.reminder_enabled && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>
|
||||
<label style={{ fontSize: 13, color: 'var(--text-2)', whiteSpace: 'nowrap' }}>ارسال</label>
|
||||
<select
|
||||
className="cp-select"
|
||||
value={currentSettings.reminder_hours_before}
|
||||
onChange={(e) => setLocalSettings({ ...currentSettings, reminder_hours_before: +e.target.value })}
|
||||
style={{ width: 130, height: 36 }}
|
||||
>
|
||||
{REMINDER_HOUR_OPTIONS.map((h) => (
|
||||
<option key={h} value={h}>{h} ساعت قبل</option>
|
||||
))}
|
||||
</select>
|
||||
<div style={{ width: 150 }}>
|
||||
<SearchableSelect
|
||||
options={REMINDER_HOUR_OPTIONS.map((h) => ({ value: h, label: `${h} ساعت قبل` }))}
|
||||
value={currentSettings.reminder_hours_before}
|
||||
onChange={(v) => setLocalSettings({ ...currentSettings, reminder_hours_before: Number(v) || 0 })}
|
||||
placeholder="ساعت"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user