feat(schedule): enhance time selection with separate hour and minute dropdowns
This commit is contained in:
@@ -294,7 +294,7 @@ const SCHEDULE_DAYS = [
|
||||
{ key: '5', label: 'پنجشنبه' },
|
||||
{ key: '6', label: 'جمعه' },
|
||||
];
|
||||
const DURATION_OPTS = [10, 15, 20, 30, 45, 60];
|
||||
const DURATION_OPTS = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60];
|
||||
const DEFAULT_SESSION: SessionConfig = {
|
||||
active: true, location_id: null,
|
||||
start_time: '09:00', end_time: '13:00',
|
||||
@@ -1020,6 +1020,32 @@ function AddressCard({ addr, onEdit, onDelete }: {
|
||||
|
||||
// ── Schedule components ────────────────────────────────────────────────────
|
||||
|
||||
// انتخاب ساعت و دقیقه به صورت دو منوی جدا (24 ساعته، دقیقه با گام 5)
|
||||
const HOUR_VALUES = Array.from({ length: 24 }, (_, h) => h.toString().padStart(2, '0'));
|
||||
const MINUTE_VALUES = Array.from({ length: 12 }, (_, i) => (i * 5).toString().padStart(2, '0'));
|
||||
|
||||
function TimeSelect({ value, onChange }: { value: string; onChange: (v: string) => void }) {
|
||||
const [hRaw, mRaw] = (value || '00:00').split(':');
|
||||
const h = (hRaw ?? '00').padStart(2, '0');
|
||||
// دقیقه را به نزدیکترین گام ۵ گرد کن تا همیشه در لیست موجود باشد
|
||||
const mNum = Math.round((Number(mRaw) || 0) / 5) * 5;
|
||||
const m = (mNum >= 60 ? 55 : mNum).toString().padStart(2, '0');
|
||||
|
||||
return (
|
||||
<div className="cp-time-select" style={{ display: 'flex', alignItems: 'center', gap: 6 }} dir="ltr">
|
||||
<select className="cp-input" style={{ height: 38, width: 72, textAlign: 'center' }}
|
||||
value={h} onChange={e => onChange(`${e.target.value}:${m}`)}>
|
||||
{HOUR_VALUES.map(hv => <option key={hv} value={hv}>{hv}</option>)}
|
||||
</select>
|
||||
<span style={{ fontWeight: 700, color: 'var(--text-2)' }}>:</span>
|
||||
<select className="cp-input" style={{ height: 38, width: 72, textAlign: 'center' }}
|
||||
value={m} onChange={e => onChange(`${h}:${e.target.value}`)}>
|
||||
{MINUTE_VALUES.map(mv => <option key={mv} value={mv}>{mv}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SlotEditor({ slots, onChange }: {
|
||||
slots: SlotConfig[];
|
||||
onChange: (slots: SlotConfig[]) => void;
|
||||
@@ -1078,25 +1104,19 @@ function SessionEditor({ session, onChange, onRemove, addresses }: {
|
||||
<div style={{ padding: '14px 16px 12px', display: 'grid', gridTemplateColumns: '1fr 1fr auto', gap: 12, alignItems: 'end' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 5 }}>از ساعت</div>
|
||||
<div className="field">
|
||||
<input type="time" dir="ltr" value={session.start_time}
|
||||
onChange={e => upd('start_time', e.target.value)} />
|
||||
</div>
|
||||
<TimeSelect value={session.start_time} onChange={v => upd('start_time', v)} />
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 5 }}>تا ساعت</div>
|
||||
<div className="field">
|
||||
<input type="time" dir="ltr" value={session.end_time}
|
||||
onChange={e => upd('end_time', e.target.value)} />
|
||||
</div>
|
||||
<TimeSelect value={session.end_time} onChange={v => upd('end_time', v)} />
|
||||
</div>
|
||||
<button type="button" className="mini-btn danger" onClick={onRemove} style={{ marginBottom: 1 }}>
|
||||
<TrashIcon style={{ width: 15, height: 15 }} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Duration + Location + Limit */}
|
||||
<div style={{ padding: '0 16px 14px', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
|
||||
{/* Duration + Location */}
|
||||
<div style={{ padding: '0 16px 14px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 5 }}>بازه هر نوبت</div>
|
||||
<GlobalSearchableSelect
|
||||
@@ -1124,14 +1144,6 @@ function SessionEditor({ session, onChange, onRemove, addresses }: {
|
||||
isClearable
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 5 }}>حداکثر نوبت</div>
|
||||
<div className="field">
|
||||
<input type="number" min={1} placeholder="—"
|
||||
value={session.patient_limit ?? ''}
|
||||
onChange={e => upd('patient_limit', e.target.value ? Number(e.target.value) : null)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Rest toggle */}
|
||||
|
||||
Reference in New Issue
Block a user