Commit Graph
334 Commits
Author SHA1 Message Date
hamed 672a7d89bf Fix community IDs and update sitemap functionality
- Updated community IDs for various components in graph.json to reflect correct associations.
- Added new function `getPublishedDoctors()` in app/sitemap.js and established relationships with existing functions.
- Adjusted source locations for several functions in app/sitemap.js to ensure accurate mapping.
- Enhanced canonical URL handling in lib/getCanonicalUrl.js to prevent incorrect canonicalization for paginated specialty pages.
- Updated manifest.json with new modification times and AST hashes for affected files.
2026-07-19 09:32:00 +03:30
hamed 8eb55679b2 feat(sitemap): optimize doctor URL fetching and add sitemap index threshold warning 2026-07-19 09:10:04 +03:30
hamed 4d7b87ee1a feat(blog): enhance metadata generation and blog fetching by city context 2026-07-19 09:02:14 +03:30
hamed fd48b48613 feat: add canonical URL handling and entity quality checks
- Implemented canonical URL strategies for city-specific domains and entities.
- Added helper functions for domain and city resolution.
- Created tests for canonical URL generation and domain resolution.
- Introduced entity quality checks for doctors and clinics to ensure meaningful content.
- Developed unique introductory texts for listing pages to avoid duplicate content.
- Established robots.txt policies for listing pages to manage indexing based on user filters.
- Enhanced specialty content with dynamic introductions and FAQs to improve SEO.
2026-07-19 07:52:50 +03:30
hamedandClaude Fable 5 36816eded2 fix(doctor): derive booking state from booking_locations
The profile decided "نوبت‌دهی غیرفعال است" from `doctor.active` alone, while the
page already had `booking_locations` — the more precise source, since the backend
only returns locations that are genuinely bookable. The two could disagree, and
for a doctor bookable only at a clinic they did.

A shared `bookingState` helper now drives both the desktop card and the mobile
bar: any location means bookable, the label comes from the earliest
`next_available_at`, and locations with no capacity yet read as "فعلاً نوبت خالی
ندارد" rather than disabled. With no locations at all it falls back to the
previous `doctor.active` / `free_turn` fields.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:25:37 +03:30
hamedandClaude Opus 4.8 b37096048c feat(booking): show only locations that can actually be booked that day
The site offered a "personal practice" for a doctor who has no personal address
at all — the schedule existed but its shifts pointed at the clinic's address, so
there was nowhere to go. The backend now filters those out; this consumes the
filtered contract and adds the per-day dimension.

- getBookingLocations takes an optional date and the appointment page refetches
  on it, merging available_on_date into the existing list rather than replacing
  it, so browsing the calendar never resets the user's choice.
- The browsed day had to be lifted out of the Date step: selectedDate is only
  set once a slot is confirmed, far too late to drive availability.
- A location closed on the chosen day renders disabled with «در این روز نوبت
  ندارد», and when every location is closed the step says so instead of showing
  an empty slot list. If the already-selected location closes, a notice appears
  with a link back to the picker — silently showing nothing was the failure mode
  worth avoiding.
- Doctor profile: workLocation in the Physician JSON-LD is limited to addresses
  that appear in booking_locations, since schema.org presents them as places a
  patient can attend. The address card still lists the others — they are real
  practice details — tagged «بدون نوبت‌دهی آنلاین».

Verified end-to-end with a temporary unused address on the test doctor: the
visible card listed both and tagged the unused one, while workLocation carried
only the bookable one. The row was removed afterwards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 14:44:49 +03:30
hamedandClaude Opus 4.8 0eb172517f feat(seo): emit openingHoursSpecification per work location
The doctor page listed where a doctor works but never when, so search engines
had no working hours for any location. booking_locations now carries
opening_hours per context, so each MedicalClinic in the Physician JSON-LD gets
its own openingHoursSpecification, matched to the address by uuid.

Verified against the rendered page: the clinic location emits five shifts with
schema.org weekday URLs alongside the availableService entries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 13:53:28 +03:30
hamedandClaude Opus 4.8 eba0c6a5ba feat(booking): let patients choose the booking location
A doctor now has one booking schedule per context — the personal practice plus
one per clinic — and every booking endpoint takes an optional clinic_uuid where
omitting it means the personal practice, not a wildcard. This site sent none, so
a clinic-only doctor showed no availability at all and a doctor working in both
places silently booked into the wrong one.

- services/response.js: getBookingLocations + clinic_uuid on slots,
  service-slots, booking-services and month-availability. The manual query
  building is kept so the service_item_uuids[] serialisation does not change.
- AppointmentPage owns the selected location; booking_mode and services are
  derived from it instead of a separate getBookingServices call, which drops a
  request. Changing location clears the selected service, slot and date, since
  a service from one location cannot be booked into another.
- New LocationSelect step, shown only when there is more than one location.
  The list arrives sorted by earliest free slot, so the first item is the
  default and is not re-sorted here.
- DatePicker drops its month cache when the location changes; otherwise the
  previous location's disabled days stayed on the calendar.
- The slot address now comes from the selected location rather than
  doctor.address, which does not contain clinic addresses.
- clinic_uuid rides through to the appointment payload, and
  /appointment/[doctorId]?clinic_uuid=… preselects a location.
- Doctor page JSON-LD gains availableService from the bookable services.
  openingHoursSpecification still needs a public weekly-hours endpoint.

Removed the dead locateVisit state, which was initialised true and never unset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 13:48:31 +03:30
hamed 6f9640cea6 fix(payment): adjust date formatting to use UTC offset for consistency 2026-07-16 00:30:20 +03:30
hamed 165a0a2240 feat(appointment): implement service-based booking flow with service selection and slot adaptation 2026-07-15 23:48:40 +03:30
hamed d5845bf84d refactor(dateTime): streamline slot handling and improve session management 2026-07-15 19:16:24 +03:30
hamed 58f05f8f4f feat(login): add redirect parameter to login links for better user experience 2026-07-12 10:06:15 +03:30
hamed 42ac6645d5 feat(doctor profile): implement unclaimed doctor handling and UI adjustments 2026-07-12 10:00:03 +03:30
hamed 8f1c63d3b1 Refactor code structure for improved readability and maintainability 2026-07-11 17:50:54 +03:30
hamedandClaude Opus 4.8 c007ffa2b3 fix(doctor page): addresses were mis-extracted from double-nested response
GET /api/v1/clinic-pro/doctor-addresses/{id} returns { data: { data: [...] } },
but getDoctorAddresses read json.data (the wrapper object, not the array), so
addresses.length/.map were undefined — the locations card + map never rendered
even when the doctor had an address. Extract json.data.data.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 15:25:39 +03:30
hamedandClaude Opus 4.8 4fed9a8c57 feat(doctor): fix map render + claim modal captcha/mobile + owner delete
- Doctor page map: the visible locations card read doctor.address (empty
  from the detail endpoint) while coordinates live in the separately
  fetched addresses. Thread `addresses` (with map.latitude/longitude) down
  page → DoctorPage → DetailDoctor → Locations; card hidden when empty
- Claim modal: updated info-box text ("نوبت‌های این پروفایل عمومی و غیرخاص
  هستند")، added mobile field (validated, must match account), added ALTCHA
  widget (submit disabled until captcha resolves; payload sent as `altcha`)
- Owner delete: services.deleteDoctor + a guarded two-step "حذف این پروفایل"
  in the claim success screen (owner enforced server-side; 403/409 shown)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 15:04:28 +03:30
hamed ab2ab0dea2 feat: enhance domain handling for global representatives
- Updated `getStateInfo` to fetch site context for domains not in city.json, returning `repContext` with representative details.
- Implemented caching for site context requests to optimize performance.
- Modified doctor and clinic listing pages to pass the `domain` parameter when fetching data for global representatives.
- Adjusted metadata generation in layout and pages to reflect representative branding based on `repContext`.
- Added documentation for the new functionality in `.claude/prompt/global-rep-domain-site.md`.
2026-07-09 07:34:09 +03:30
hamed a56b7e8de5 fix: update handleChange to use optional chaining and add "use client" directive in Connect component 2026-07-08 18:24:33 +03:30
hamed ee47b535d8 Add empty AST cache file for version 0.8.44 with non-object root data 2026-07-08 17:38:32 +03:30
hamed 73c10f53ec fix: handle undefined slug and doctorId in cache functions 2026-07-07 11:47:44 +03:30
hamed df7fbb7530 Refactor code structure for improved readability and maintainability 2026-07-06 15:10:19 +03:30
hamed f6475d1a7d feat: improve error handling in API calls for blog, clinic, and doctor data retrieval 2026-07-05 15:56:30 +03:30
hamed b04bb45ca1 Implement multi-domain SEO improvements:
- Add metadata to login and login-verify pages to prevent indexing.
- Update robots.txt to disallow additional sensitive paths.
- Enhance sitemap generation to filter by city and include accurate last modified dates.
- Refactor canonical URL generation to support multi-domain architecture, ensuring self-canonicalization for city domains.
- Remove deprecated CanonicalHandler component and streamline canonical URL handling.
- Introduce safe JSON-LD output to prevent XSS vulnerabilities.
- Add payment layout with appropriate metadata to prevent indexing.
- Conduct a comprehensive technical SEO audit and implement necessary fixes across the application.
2026-07-05 15:47:47 +03:30
hamed aa75fb858f feat: replace PNG logo with SVG and add new icon SVG files 2026-07-03 12:06:11 +03:30
hamed e00db96150 chore: remove unused icon.png file 2026-07-03 12:06:06 +03:30
hamed a5c15c54a1 Refactor code structure for improved readability and maintainability 2026-07-03 11:13:59 +03:30
hamed 7694ca85a5 chore: remove unused favicon.ico file 2026-07-03 11:13:55 +03:30
hamed 90d4a871f5 feat: enhance payment flow with automatic redirection to appointment history after successful payment 2026-07-03 10:45:35 +03:30
hamed 5bec4848a2 feat: unify currency display to toman across the application 2026-07-03 10:31:16 +03:30
hamed 79f7df2e4d feat: implement root domain handling for nobat724.com to prevent city filtering 2026-07-02 21:53:45 +03:30
hamed e6b55c6bad feat: refactor payment handling to use direct backend redirect instead of API call 2026-07-02 17:08:52 +03:30
hamed e83a666adb feat: enhance payment flow with dynamic URL handling and improved error messaging 2026-07-02 15:36:09 +03:30
hamed 09373c46d6 fix(config): update hostname for API and add Google Analytics endpoints to CSP 2026-06-25 20:52:09 +03:30
hamed f87110c277 refactor: remove unused components and files related to date filtering and doctor search
- Deleted Date.js and FilterDate.js components as they are no longer needed.
- Removed SearchDoctor.js component which was responsible for searching doctors.
- Cleaned up the Head component by removing references to the deleted Date and SearchDoctor components.
- Removed TurnsPage component and its associated List component, which were not utilized.
- Deleted Cards and Table components from the list directory as they were not in use.
- Removed user account related components including Tab, Head, and Form components.
- Cleaned up bank account components including List, Item, and modal components.
- Removed representation adapters and related functions that were not in use.
2026-06-25 18:14:27 +03:30
hamed 537f3e47d5 fix(payment): update currency display from تومان to ریال and adjust amount formatting 2026-06-24 20:39:34 +03:30
hamed a83e352dd8 fix(appointment): update display logic for inactive doctors and free turns 2026-06-22 09:47:11 +03:30
hamed 12d2e2e3f1 fix(logo): add aria-labels and improve accessibility features in Logo component
fix(progress): enhance accessibility by adding aria-label to LinearProgress component
fix(share): add aria-label for better accessibility in Share button
fix(title): change h3 to h2 for semantic correctness and add aria-labels for links
fix(qrimg): add alt text for QR code image for improved accessibility
fix(buttonmenu): add aria-label for mobile menu button to enhance accessibility
2026-06-21 17:47:23 +03:30
hamed 1841a16b4d fix(logo): update city name display logic for improved localization 2026-06-21 17:10:21 +03:30
hamed bb559df1a9 fix(metadata): enhance title generation for better SEO and user context 2026-06-21 17:05:48 +03:30
hamed 35e8b65342 fix(accessibility): add aria-labels for improved screen reader support 2026-06-21 17:00:23 +03:30
hamed cbae19d270 feat(doctors): add loading state management and pass filter to sendReq 2026-06-21 16:24:09 +03:30
hamed cb13ba3f45 fix(doctors): improve filter performance and resolve modal closing issues 2026-06-21 15:47:37 +03:30
hamed 9dd71ab2f5 feat(clinic): enhance generateMetadata and JSON-LD for comprehensive clinic schema 2026-06-21 13:26:49 +03:30
hamed 8e7d10c859 feat(specialties): enhance specialties components to include city and state names in metadata and links 2026-06-21 13:03:50 +03:30
hamed cb9d9beaab feat(sitemap): refactor sitemap generation to include doctors, clinics, and blogs with improved URL handling 2026-06-21 12:52:41 +03:30
hamed a8c3a57114 feat(doctor): enhance doctor schema with addresses, ratings, and social media links
feat(robots): update disallow rules to include '/panel'
feat(sitemap): implement separate sitemaps for doctors, clinics, and blogs
feat(icons): add social media icons for doctor profiles
2026-06-21 12:35:15 +03:30
hamed 93b2710ae1 feat(doctor-avatar): enhance DoctorAvatar component with initials formatting and integrate into ItemAppointment 2026-06-21 12:07:14 +03:30
hamed 7462e69641 feat(doctor): enhance doctor page with specialty links and dynamic breadcrumb 2026-06-21 11:55:36 +03:30
hamed 704a514542 feat(loading): enhance loading components with responsive design and improved skeletons 2026-06-21 11:49:30 +03:30
hamed 06a877a725 feat(metadata): enhance SEO by adding Open Graph and Twitter metadata across various pages
feat(blog): implement loading and error handling components for blog pages

feat(clinic): add loading and error handling components for clinic pages

feat(doctor): create loading and error handling components for doctor pages

feat(clinics): add loading component for clinics page

feat(specialties): improve metadata for specialties page with Open Graph and Twitter images

feat(layout): add structured data for Organization and WebSite in layout

fix(middleware): restrict middleware execution to specific routes to improve performance

chore(audit): add comprehensive SEO and performance audit documentation
2026-06-21 11:38:39 +03:30