feat(settings): manage resource schedules beside the doctors'

A resource carries its own working hours and holidays in the resource-first
model, so it belongs on the same settings page as a doctor's schedule rather
than on a page of its own. The page now has a scope switch — doctors or
resources — with the per-item tab bar below it, and both scopes reuse the
panels that already existed: ScheduleSection for a doctor, the working-hours
and exceptions panels for a resource. The selection lives in the query
string, so back and refresh return to the same tab.

The screenshot of the finished tab caught two real defects, both fixed here:

Dates in the resource panels and the holidays page read as year 57932.
formatDate already multiplies seconds by 1000, and five call sites passed
`x * 1000` on top of it. This predates the tab — the code was inherited from
the old calendar page — but it was invisible until a two-week preview was put
on screen.

The working-hours panel still told the user their hours were intersected with
the branch's. Branches are gone; the shift is the only source now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-08-02 15:49:01 +03:30
co-authored by Claude Opus 5
parent f144401dd3
commit 9ba4c8d948
6 changed files with 286 additions and 63 deletions
+2 -2
View File
@@ -32,7 +32,7 @@ export default function HolidaysSettingsPage() {
{
key: 'gregorian',
header: 'میلادی',
render: (h) => <span style={{ fontSize: 12, color: 'var(--text-3)' }}>{formatDate(h.date * 1000)}</span>,
render: (h) => <span style={{ fontSize: 12, color: 'var(--text-3)' }}>{formatDate(h.date)}</span>,
},
{
key: 'status',
@@ -150,7 +150,7 @@ function ClosureCard({
{overrides.map((o) => (
<div key={o.uuid} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
<span style={{ flex: 1, color: 'var(--text-2)' }}>
{formatDate(o.date * 1000)}{o.note ? ` · ${o.note}` : ''}
{formatDate(o.date)}{o.note ? ` · ${o.note}` : ''}
</span>
{canUpdate && (
<button type="button" className="btn secondary sm" onClick={() => onRemove(o.uuid)} aria-label="حذف تعطیلی">