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