Commit Graph
561 Commits
Author SHA1 Message Date
hamed af6da197dc chore: update graphify graph 2026-07-16 10:18:16 +03:30
hamedandClaude Opus 4.8 029b5f632e feat: section-then-service picker with cross-section accumulation
Rework slot-mode service selection: pick a section, its services show as a
checkbox list, and chosen services collect into a removable 'selected'
chip list that persists when switching to another section (services from
multiple sections accumulate). Changing the section no longer clears the
selection. Add a test covering multi-section accumulation and chip removal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 10:18:10 +03:30
hamed 08aa3a78b8 chore: update graphify graph 2026-07-16 10:10:56 +03:30
hamedandClaude Opus 4.8 4642506c0f feat: support multiple services per appointment (checkbox selection)
Appointments could only reference a single service (ManyToOne). Add an
appointment_service_items join table (ManyToMany) so an appointment can
carry several services; the first stays the primary service_item for
backward compatibility, and toArray now also returns service_items[].

Both create endpoints (my/appointment, admin/appointment) accept
service_item_uuids[] and attach all of them. A new duration_from_services
flag gates the slot_end recompute: service-booking mode sends it true
(slot_end = start + Σ durations); slot mode omits it so the manual end
time is preserved. The admin endpoint previously ignored services entirely.

Frontend: in slot mode the single service dropdown becomes a checkbox list
filtered by the selected section (multi-select); service mode sends the
duration flag. Migration + backend/entity tests + docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 10:10:47 +03:30
hamed d76fd73529 chore: update graphify graph 2026-07-16 09:57:11 +03:30
hamedandClaude Opus 4.8 3e8126c520 fix: return patient national code from profile in patients list
National code is stored on the profiles table, not users, so the patients
search returned null user_national_code for patients that actually have one
— which blocked selecting an existing patient on the appointment create
form. Backfill user_national_code from the profile (batch query) in the
list endpoint. On the create page, show a picked patient's stored national
code read-only and only prompt for input when the record genuinely lacks
one. Add backend tests and update docs/api/patient.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:57:03 +03:30
hamed 110c210cf4 chore: update graphify graph 2026-07-16 09:45:13 +03:30
hamedandClaude Opus 4.8 e1fb63eb0f feat: add DigitInput component; force English digits for phone & national code
New reusable DigitInput normalizes Persian/Arabic digits to English on
input, strips non-digits, enforces maxDigits, and is always LTR + numeric
keyboard. Use it for the phone and national-code fields on the appointment
create page (phone previously kept raw Persian digits; national code lost
Persian digits to the \D strip).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:45:04 +03:30
hamed b2347f00e7 chore: update graphify graph 2026-07-16 09:39:40 +03:30
hamedandClaude Opus 4.8 bc4030251d fix: allow submit when picking an existing patient
Backend requires a valid national code for every appointment, but a picked
patient record may have none stored. Show a selected-patient card with an
editable national-code field (prefilled from the record) so submit can
enable. Add happy-path and boundary tests for the picked-patient flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:39:33 +03:30
hamed 10adfa3b15 chore: update graphify graph 2026-07-16 09:33:24 +03:30
hamedandClaude Opus 4.8 a40fb7e598 feat: toggle new-patient form on appointment create page
Show name/phone/national-code fields only after clicking 'مراجعه کننده جدید';
hide the existing-patient search while in new-patient mode, with a
'انتخاب از لیست موجود' link to switch back. Update tests to click the
toggle before filling the fields.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:33:16 +03:30
hamed 6e040402e1 chore: update graphify graph 2026-07-16 09:28:25 +03:30
hamedandClaude Opus 4.8 54bdc73f37 fix: correct deposit section layout on appointment create page
Move switch to its own row; render amount field (wrapped in .field for a
proper bordered box) and wallet-charge button on a following aligned row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:28:19 +03:30
hamed a6c11a20bd chore: update graphify graph 2026-07-16 09:18:53 +03:30
hamedandClaude Opus 4.8 170cd5f37e style: restyle appointment create page to match tauri CreateTurn mockup
Widen card to 1080px, 18px section headings, multi-column grids
(patient 3-col, service 3-col, slot-mode time 4-col), search field +
outlined 'new patient' button row, toggle switch for deposit, orange
wallet charge button, right-aligned submit. Service/slot booking logic,
endpoints, validation, and placeholders unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:18:29 +03:30
hamed b7730f545a fix(appointment): update EmptyCard to display 'افزودن نوبت سریع' for better clarity 2026-07-16 09:05:26 +03:30
hamed b1b99903ec Replace all native <select> elements in the admin panel with SearchableSelect for a consistent UI experience. This change enhances accessibility, supports RTL and dark mode, and improves the overall design by utilizing a common component. The updates include adjustments to state management and event handling to ensure seamless integration with existing functionality across various pages and components. 2026-07-16 08:56:59 +03:30
hamed 7b8a5c2775 feat(date-input): refactor PersianDateInput to use PersianDatePicker for Jalali calendar support 2026-07-16 08:26:39 +03:30
hamed 2f060bd5be feat(timezone): implement Tehran timezone handling across the application 2026-07-16 00:25:21 +03:30
hamed 8cd1253b81 feat(appointment): enhance service mode to display available booking slots between appointments 2026-07-16 00:16:37 +03:30
hamed 4715649fd8 feat(appointment): implement service mode functionality with service slot selection and validation 2026-07-16 00:02:36 +03:30
hamed ac4a430564 feat(appointment): add booking services endpoint and update security configuration for public access 2026-07-15 23:48:38 +03:30
hamed 2df16c6d29 feat(appointment): implement immutable booking mode after first save and update API documentation 2026-07-15 23:33:00 +03:30
hamed ad94c165e8 feat(appointment): add service mode functionality and update API documentation for service-based booking 2026-07-15 23:22:57 +03:30
hamed 5937f7e176 feat: add service-based booking mode to appointment scheduling
- Introduced a new booking mode in WeeklySchedule to support service-based appointments.
- Updated SlotCalculatorService to calculate available start times based on selected service durations and buffer times.
- Enhanced AppointmentController to handle service items during booking, calculating slot_end on the server side.
- Implemented validation to ensure at least one bookable service exists for doctors in service mode.
- Added new API endpoint to retrieve available appointment slots based on selected services.
- Updated MyAppointmentsController to accept service items during appointment creation.
- Modified ServiceItem entity to include a bookable flag, allowing services to be marked for scheduling.
- Created migration to add bookable column to service_items table.
- Added tests for service-based slot calculations and validation logic.
2026-07-15 23:15:45 +03:30
hamed 6904361e32 feat(appointment): update patient name handling to prioritize existing profile name for new appointments 2026-07-15 22:35:33 +03:30
hamed 13bf9453e5 feat(appointment): ensure existing profile name is used over modal input for patient name 2026-07-15 20:33:15 +03:30
hamed d91867bd63 fix(appointment): resolve issue with reserved slots incorrectly shown as available 2026-07-15 19:13:27 +03:30
hamed de6fe1bd56 feat(appointment): update patient identification to use national code from profile and enhance appointment creation logic 2026-07-15 18:46:56 +03:30
hamed 0dc1ab949a feat(appointment): add Enter key functionality for mobile search in appointment modal 2026-07-15 18:29:59 +03:30
hamed 5d5089244b feat: add mobile-based patient lookup for appointment booking
- Implemented a new endpoint `/api/v1/my/appointment/patient-lookup` to search for patients by mobile number before booking an appointment.
- Updated the `NewAppointmentModal` component to utilize the new patient lookup feature, allowing for direct booking if the patient is found with a national code.
- Enhanced the appointment booking form to handle mobile input normalization and display relevant fields based on the search results.
- Added tests for the new patient lookup functionality, ensuring proper behavior for found and not found cases, as well as validation for mobile input.
- Updated sidebar tests to reflect changes in the sidebar component structure and functionality.
2026-07-15 18:27:29 +03:30
hamed f378bf58e6 Add AST JSON representation for BookingScopeTest.php with nodes and edges 2026-07-15 18:14:59 +03:30
hamedandClaude Opus 4.8 5548d79d4c feat(appointment): identify admin-booked patient by national code
Admin-side booking (POST /api/v1/my/appointment and
/api/v1/admin/appointment) resolved the patient User by mobile only, so
one person booked under two mobiles produced two User rows — and two
case-files, since PatientRecord is keyed on user_id. National code is the
real unique identity (User.national_code is already unique); a person may
have several mobiles.

Booking now requires + validates patient_national_code and resolves the
patient national-code-first (then mobile) via a shared PatientResolver, so
the case-file stays unique per national code even across mobiles. Reusing a
mobile already bound to a different national code returns 422
ERR_PROFILE_MOBILE_TAKEN. The admin create form and NewAppointmentDrawer
gain a national-code field and send it; both had a dead patient-picker URL
(/api/v1/patient) fixed to the real /api/v1/patients, whose payload already
carries user_national_code for autofill.

Docs (appointment.md, admin.md) and tests updated; new
AppointmentNationalCodeTest covers success, single-file reuse, missing,
invalid, and identity-conflict cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:11:40 +03:30
hamed 141ce478a2 chore: update graphify graph 2026-07-15 17:45:07 +03:30
hamedandClaude Opus 4.8 1aa6794786 feat: port tauri header top-menu to admin topbar
Rebuild admin Topbar to match clinic-pro-tauri header:
- Icon order: theme -> settings -> bell (was theme -> bell -> settings)
- Settings gear now navigates to the role-based settings page
  instead of opening the personalization panel
- Search placeholder changed to «جستجو», dropped the ⌘K hint
- Add ProfileMenu: avatar + user name + context/role subtitle + caret,
  with a dropdown (profile / payments / settings / personalization / logout).
  Links are role-aware; personalization keeps the existing settings panel.

Frontend-only, no API changes. Adds ProfileMenu.test + Topbar.test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:44:47 +03:30
hamed 952fcf3634 style: enhance SettingsLayout and AppointmentSettingsPage for improved layout and spacing 2026-07-15 17:35:24 +03:30
hamed ffc4351038 fix: update PurchaseSubscriptionSidebar and AppointmentSettingsPage for pixel-perfect alignment and color consistency 2026-07-15 17:30:26 +03:30
hamedandClaude Opus 4.8 810293764a chore: update graphify graph
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:06:42 +03:30
hamedandClaude Opus 4.8 62e0cdb518 feat(admin): add orange rgb(241,119,50) as an exact brand-color option
Revert the earlier mis-scoped orange on the personalization panel and
instead expose rgb(241,119,50) as a selectable 'رنگ اصلی' swatch. When
picked it overrides --primary/-600/-700/-soft/-soft2/-ring inline with
exact hex, so every var(--primary) consumer across the whole admin
(buttons, active nav, rings) becomes that orange. Non-fixed hues keep
the oklch hue pipeline (inline overrides removed on switch).

- uiStore: BrandHue interface + optional fixed hex; shared applyBrand()
  helper handles fixed vs hue, dark-aware soft tints
- AdminLayout: reuse applyBrand() (no divergence with store)
- Topbar: swatch shows the exact fixed color
- tests: fixed-color apply, dark soft, and override-cleanup on switch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:06:24 +03:30
hamedandClaude Opus 4.8 89ebeb8fce style(admin): orange accent for شخصی‌سازی panel
Apply rgb(241,119,50) exclusively to the personalization (شخصی‌سازی)
settings panel — its heading and active segmented buttons — matching
the product requirement that this section use the dedicated orange
while the rest of the panel keeps tauri's purple.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:55:53 +03:30
hamedandClaude Opus 4.8 edf3cea51f chore: update graphify graph
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:48:58 +03:30
hamedandClaude Opus 4.8 0a78bf7a6b style(admin): align design tokens to clinic-pro-tauri
Match the admin panel's visual system to the tauri source app:
- neutralize color tokens (border/surface-2/3, text 1-3) from the
  bluish indigo tint to tauri's neutral grays (#efefef/#3b3b3b/#7e7e7e/#a1a1a1)
- add --nav-active-bg (#f8f8ff light) for the sidebar active item,
  matching tauri active-link-side
- enable Vazirmatn ss02 stylistic set on body (tauri typography)
- responsive topbar heights 56/67/79/90 exactly as tauri

Settings sub-sidebar active orange (#f17732 = rgb(241,119,50)) and
ClinicPro branding/section grouping kept per product decision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:48:25 +03:30
hamed 5c15a4dd7f feat(services): add services menu item to sidebar and update related components 2026-07-15 16:35:02 +03:30
hamed 704e69f05f chore: update graphify graph 2026-07-15 16:20:34 +03:30
hamedandClaude Opus 4.8 10d289cfd1 fix(appointments): detail page back/breadcrumb return to the appointment day
AppointmentDetailPage now derives the appointment's local day from slot_start
and points both the «بازگشت» button and the «نوبت‌ها» breadcrumb to
/admin/appointments?date=<that day>, so viewing/acting on an appointment from
any day returns to that day instead of today.

Test: the «نوبت‌ها» breadcrumb links back to the appointment's date.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:20:22 +03:30
hamed ab2904b81a chore: update graphify graph 2026-07-15 16:13:41 +03:30
hamedandClaude Opus 4.8 526048fd56 fix(appointments): stay on the same day after edit/create
AppointmentsPage now reads an optional ?date=YYYY-MM-DD query param as its
initial selected date. AppointmentEditPage and AppointmentCreatePage navigate
back to /admin/appointments?date=<the appointment's day> on save (and the edit
page's back link carries the date too), so the user returns to the day they
were viewing instead of today.

Test: AppointmentsPage honors ?date= and fetches that day.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:13:32 +03:30
hamed 41e193ab83 chore: update graphify graph 2026-07-15 16:07:15 +03:30
hamedandClaude Opus 4.8 f41852b168 feat(appointments): profile-aware doctor tabs + toolbar to match tauri turns
- Multi-doctor clinic profile (clinic/admin) shows the doctor tabs for
  multi-doctor management; clinic auto-selects the first doctor so the timeline
  loads immediately (as in the reference). Admin keeps the «همه» tab.
- Independent doctor profile (doctor role, incl. clinic-scoped guest) shows no
  tabs and only its own schedule — no clinic/doctor selection.
- Toolbar reordered to match the reference: date + service select
  («سرویس مورد نظر را انتخاب کنید...») + view toggle on the right; filter +
  «افزودن نوبت» on the left. The in-toolbar doctor picker is removed (doctor
  selection is via tabs); the personnel select is replaced by a service filter
  bound to the existing itemUuid filter (client-side, no new endpoint).

Tests: added clinic-profile tests (tabs shown, no «همه», first doctor
auto-selected) and independent-doctor test (no tabs, service filter shown).

No API endpoints changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:07:04 +03:30