feat(claims): replace PersianDateInput with PersianDatePicker and add quick date range buttons
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { CalendarDaysIcon, XMarkIcon } from '@heroicons/react/24/outline';
|
||||||
|
import { formatDate } from '../../lib/utils';
|
||||||
|
import PersianCalendar from './PersianCalendar';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: string; // YYYY-MM-DD میلادی
|
||||||
|
onChange: (v: string) => void;
|
||||||
|
placeholder?: string;
|
||||||
|
height?: number;
|
||||||
|
minWidth?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PersianDatePicker({ value, onChange, placeholder = 'انتخاب تاریخ', height = 38, minWidth = 148 }: Props) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||||
|
<div
|
||||||
|
onClick={() => setOpen((o) => !o)}
|
||||||
|
style={{
|
||||||
|
display: 'flex', alignItems: 'center', gap: 7,
|
||||||
|
height, padding: '0 10px', borderRadius: 'var(--r-sm)',
|
||||||
|
border: '1px solid var(--border)', background: 'var(--surface)',
|
||||||
|
cursor: 'pointer', fontSize: 13, color: value ? 'var(--text)' : 'var(--text-3)',
|
||||||
|
userSelect: 'none', minWidth, whiteSpace: 'nowrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CalendarDaysIcon style={{ width: 15, height: 15, color: 'var(--text-3)', flexShrink: 0 }} />
|
||||||
|
<span style={{ flex: 1 }}>{value ? formatDate(value) : placeholder}</span>
|
||||||
|
{value && (
|
||||||
|
<span
|
||||||
|
onClick={(e) => { e.stopPropagation(); onChange(''); }}
|
||||||
|
style={{ display: 'flex', alignItems: 'center', cursor: 'pointer', color: 'var(--text-3)' }}
|
||||||
|
>
|
||||||
|
<XMarkIcon style={{ width: 13, height: 13 }} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{open && (
|
||||||
|
<PersianCalendar
|
||||||
|
value={value}
|
||||||
|
onChange={(v) => { onChange(v); setOpen(false); }}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,9 +7,16 @@ import { formatRial, formatNumber, formatDate } 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';
|
import SearchableSelect from '../components/ui/SearchableSelect';
|
||||||
import PersianDateInput from '../components/ui/PersianDateInput';
|
import PersianDatePicker from '../components/ui/PersianDatePicker';
|
||||||
import FeatureGate from '../components/ui/FeatureGate';
|
import FeatureGate from '../components/ui/FeatureGate';
|
||||||
|
|
||||||
|
const isoNDaysAgo = (days: number): string => {
|
||||||
|
const d = new Date();
|
||||||
|
d.setDate(d.getDate() - days);
|
||||||
|
return d.toISOString().slice(0, 10);
|
||||||
|
};
|
||||||
|
const todayIso = (): string => new Date().toISOString().slice(0, 10);
|
||||||
|
|
||||||
const toUnix = (iso: string): number | null => {
|
const toUnix = (iso: string): number | null => {
|
||||||
if (!iso) return null;
|
if (!iso) return null;
|
||||||
const t = new Date(iso + 'T00:00:00').getTime();
|
const t = new Date(iso + 'T00:00:00').getTime();
|
||||||
@@ -188,11 +195,29 @@ export default function ClaimsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="field-label">از تاریخ</label>
|
<label className="field-label">از تاریخ</label>
|
||||||
<PersianDateInput value={fromDate} onChange={setFromDate} placeholder="از تاریخ" />
|
<PersianDatePicker value={fromDate} onChange={setFromDate} placeholder="از تاریخ" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="field-label">تا تاریخ</label>
|
<label className="field-label">تا تاریخ</label>
|
||||||
<PersianDateInput value={toDate} onChange={setToDate} placeholder="تا تاریخ" />
|
<PersianDatePicker value={toDate} onChange={setToDate} placeholder="تا تاریخ" />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: 6, alignItems: 'flex-end', paddingBottom: 1 }}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn sm"
|
||||||
|
onClick={() => { setFromDate(isoNDaysAgo(365)); setToDate(todayIso()); }}
|
||||||
|
title="از یک سال پیش تا امروز"
|
||||||
|
>
|
||||||
|
یک سال اخیر
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn sm"
|
||||||
|
onClick={() => { setFromDate(isoNDaysAgo(30)); setToDate(todayIso()); }}
|
||||||
|
title="از یک ماه پیش تا امروز"
|
||||||
|
>
|
||||||
|
یک ماه اخیر
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ flex: 1, minWidth: 200 }}>
|
<div style={{ flex: 1, minWidth: 200 }}>
|
||||||
<label className="field-label">جستجوی بیمار (نام / موبایل / کدملی)</label>
|
<label className="field-label">جستجوی بیمار (نام / موبایل / کدملی)</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user