The backend already returns is_available:false for past slots, but a
slot can lapse after the list is loaded. Disable any slot whose start
(unix seconds) is before now in the time grid, so a just-passed slot
can't be clicked. The grid disabling makes a SendAppo-level guard
redundant — a past slot can no longer be selected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DatePicker now loads month-availability for the two displayed Jalali
months (mapped to the Gregorian months they span, fetched once and
cached per month) and disables any day in disabled_dates plus past
days. Auto-select skips disabled days. When the doctor has online
booking turned off, show a notice instead of the calendar. doctorUuid
comes from the route params.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The two months rendered reversed (current month on the left). Pin the
calendar row to dir=rtl and render the base month first so the current
month sits on the right and the next month on the left, matching the
design. Pin each month header to dir=ltr so the nav arrows stay on the
expected outer edges regardless of the RTL flip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The day picker used a Popover-based JalaliDatePicker that only showed two
empty text inputs on the booking page — the calendar was hidden until you
clicked the input, so it never matched the design. Replace it with an
always-visible inline two-month calendar (InlineJalaliMonth) rendered side
by side: current month on the right, next on the left (RTL), weekday
headers, Fridays in red, disabled days greyed, selected day in orange,
shared month navigation on the outer edges. Preserves the existing
contract: setDate(unix timestamp), disabledDates[], auto-select nearest
available day.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follow-ups found while sweeping for stale shapes:
- The date picker emits a unix timestamp, but appointment-slots needs
Y-m-d; convert with moment before calling (slots never loaded before).
- Appointment summary (information/Detail.js) used the auth-required
getDoctorAddress and selectedSlot.time; derive the address from the
loaded doctor.address by location_id and use selectedSlot.start_time.
- SendAppo: drop the dead postAppointment block, unused useParams/loading,
and a duplicate disabled prop on the button.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The slots API returns data.sessions[].slots[] with start_time (HH:MM),
is_available, and start/end unix timestamps — not the morning/evening +
time/status shape the UI assumed. Add lib/appointmentSlots.js to flatten
sessions into morning/evening by start_time, fetch with doctor.uuid, and
read item.start_time / item.is_available in the slot grid. Derive the
clinic address from the already-loaded doctor.address by location_id
instead of a separate auth-required call.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
prop loading روی Button فقط در MUI v6+ پشتیبانی میشود؛ این پروژه v5 است
و هشدار "Received false for a non-boolean attribute loading" میداد.
- دکمههای login/verify: disabled + CircularProgress شرطی (بازخورد بصری حفظ شد)
- بقیه دکمهها: loading → disabled (ادغام با disabled موجود در صورت وجود)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>