fix(appointments): center timeline card and match tauri turns layout

- Center the whole page in a max-width container; move the toolbar above the
  card and make the doctor tabs the card header (as in the tauri turns design).
- Rebuild the timeline card to match the reference: inner start/end ring-dot
  time markers, patient name / phone / «سرویس» lines, and status pill + عملیات
  on the card's left; outer marker rail with time on the right.
- Timeline rows are width-capped and centered on the page.
- Empty slots render the light-blue «افزودن نوبت +» card with a «نوبت جدید» pill.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hamed
2026-07-15 15:45:51 +03:30
co-authored by Claude Opus 4.8
parent bf9fce4e05
commit 48c70e89f2
3 changed files with 127 additions and 86 deletions
+47 -49
View File
@@ -331,26 +331,16 @@ export default function AppointmentsPage() {
return (
<div style={{ padding: '20px 24px' }}>
{/* عنوان */}
<h1 style={{ fontSize: 20, fontWeight: 700, color: 'var(--text)', marginBottom: 16 }}>نوبت ها</h1>
<div style={{ maxWidth: 1050, margin: '0 auto' }}>
{/* عنوان */}
<h1 style={{ fontSize: 20, fontWeight: 700, color: 'var(--text)', marginBottom: 16 }}>نوبت ها</h1>
{/* نوار آمار */}
<TurnsStatInfo stats={stats} />
{/* نوار آمار */}
<TurnsStatInfo stats={stats} />
{/* تب دکترها */}
{showDoctorTabs && (
<DoctorTabs doctors={doctors} selected={selectedDoctorUuid} onSelect={setSelectedDoctorUuid} />
)}
{/* کارت اصلی */}
<div style={{
background: 'var(--surface)', border: '1px solid var(--border)',
borderRadius: 'var(--r)', overflow: 'hidden',
}}>
{/* نوار ابزار */}
{/* نوار ابزار (بیرونِ کارت، مطابق طرح) */}
<div style={{
padding: '12px 16px', borderBottom: '1px solid var(--border)',
display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', marginBottom: 16,
}}>
{/* افزودن نوبت → صفحهٔ کامل */}
{!isRepresentation && (
@@ -403,39 +393,47 @@ export default function AppointmentsPage() {
<DateNavigator date={selectedDate} onChange={setSelectedDate} />
</div>
{/* محتوا */}
<div style={{ padding: 16 }}>
{viewMode === 'table' ? (
<>
<TurnsTable
items={pagedAppointments}
loading={apptQuery.isLoading}
queryKey={apptQueryKey}
showDoctor={showDoctorCol}
/>
{filteredAppointments.length > TABLE_PAGE_SIZE && (
<div style={{ marginTop: 14 }}>
<Pagination page={tablePage} total={filteredAppointments.length} limit={TABLE_PAGE_SIZE} onPageChange={setTablePage} />
</div>
)}
</>
) : (
<>
{!selectedDoctorUuid ? (
<div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>
برای نمایش زمانبندی، ابتدا یک پزشک انتخاب کنید
</div>
) : (
<TurnsTimeline
slots={timelineSlots}
loading={apptQuery.isLoading || slotsQuery.isLoading}
queryKey={apptQueryKey}
onView={openDetail}
onBook={handleSlotClick}
/>
)}
</>
{/* کارت اصلی — تب دکترها (هدر) + محتوا */}
<div style={{
background: 'var(--surface)', border: '1px solid var(--border)',
borderRadius: 'var(--r)', overflow: 'hidden',
}}>
{showDoctorTabs && (
<DoctorTabs doctors={doctors} selected={selectedDoctorUuid} onSelect={setSelectedDoctorUuid} />
)}
<div style={{ padding: 16 }}>
{viewMode === 'table' ? (
<>
<TurnsTable
items={pagedAppointments}
loading={apptQuery.isLoading}
queryKey={apptQueryKey}
showDoctor={showDoctorCol}
/>
{filteredAppointments.length > TABLE_PAGE_SIZE && (
<div style={{ marginTop: 14 }}>
<Pagination page={tablePage} total={filteredAppointments.length} limit={TABLE_PAGE_SIZE} onPageChange={setTablePage} />
</div>
)}
</>
) : (
<>
{!selectedDoctorUuid ? (
<div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>
برای نمایش زمانبندی، ابتدا یک پزشک انتخاب کنید
</div>
) : (
<TurnsTimeline
slots={timelineSlots}
loading={apptQuery.isLoading || slotsQuery.isLoading}
queryKey={apptQueryKey}
onView={openDetail}
onBook={handleSlotClick}
/>
)}
</>
)}
</div>
</div>
</div>