Problem: two parallel booking systems:
1. 'رزرو نوبت آنلاین' contact form — never saved data (fake submit)
2. Health section inline form — saved to /api/health-request
Fix:
- Contact form now POSTs to /api/health-request (real save)
- Added ids to all form inputs so JS can read them
- Category auto-detected from service dropdown (سلامت عمومی → health)
- Health section 'درخواست...' buttons now scroll to contact form
and pre-select the right category — no duplicate inline form
- Removed the duplicate healthFormWrap + submitHealthForm()
- All reservations visible in admin under 'درخواستها'
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Every row now has a 'مشاهده' button regardless of handled status
- Opens a modal with: name, phone, email, category, date, status,
and full message text (no truncation)
- Modal includes 'علامتگذاری' button if request is still pending
- Message column in table kept short (truncated) as a preview only
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
archive.ubuntu.com is unreachable from the build server, causing
apt-get to time out and fail every build. curl was only used for
the HEALTHCHECK. Replace with a zero-dependency bash TCP check:
bash -c 'echo > /dev/tcp/localhost/8080'
No packages needed, no external network access required.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Post.cshtml.cs: load hero image, tag from SiteSettings in SetViewDataAsync
- Post.cshtml: show <img> with hero image in .doc-avatar when set,
fall back to emoji only if no image is configured
- .doc-avatar: circular crop with object-fit:cover, gold border
- doc-title now uses HeroTag from settings (not hardcoded)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. Beauty category icon: was pink (#C2185B), now uses site primary gold
(var(--gold) / var(--gold-pale)) to match brand color
2. Dashboard now shows health requests:
- Two new stat cards: total patients + pending requests (clickable)
- 'آخرین درخواستها' mini-table showing last 6 requests
- Sidebar badge updates from dashboard load too
- loadDashboard() now fetches /api/patients + /api/health-requests
3. Blog image edit fix:
- applyCrop() now captures inputId/previewId BEFORE closeCropper()
to prevent any potential race condition when replacing images
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Backend:
- Patient model: name, phone, email, age, weight, height, gender,
blood type, disease history, allergies, medications, notes, category
- PatientVisit model: title, content, prescription, visit type,
visit/next-visit dates, linked to patient (cascade delete)
- HealthRequest model: public form submissions for beauty/health care
- Runtime SQLite migrations for all 3 new tables
- Full CRUD API: /api/patients, /api/patients/{id}/visits,
/api/health-requests (public POST + admin GET/PUT/DELETE)
Admin panel:
- 'پرونده بیماران' page: list, search, filter by category (beauty/health)
- Patient profile page: personal info + medical history + visits timeline
- Add/edit patient modal with all medical fields
- Add visit modal: type, date, clinical notes, prescription, next visit
- 'درخواستها' page: manage public health requests, mark as handled
- Badge counter for unhandled requests in sidebar
Frontend (SEO):
- New #health-care section with Schema.org MedicalClinic markup
- Two category cards: زیبایی پوست and سلامت عمومی
- Feature lists with checkmarks per category
- Inline request form that submits to /api/health-request
- Mobile responsive (single column on small screens)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Instead of overlaying text on top of the image (hard to read),
restructure each gallery card to flex-column:
- Image section (.gallery-img-wrap) on top with aspect-ratio:4/3
- Before/After labels row (.ba-labels) below the image, full text visible
- Caption (.gallery-caption) below that, with padding and border
Labels now show full text 'قبل از درمان' / 'بعد از درمان' in a clean
row under the split image — never overlapping, always readable.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The .hidden class only covered .modal-overlay and .fm-overlay.
Without the rule, display:flex on .cropper-overlay overrode .hidden
and the modal showed immediately on every page load.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Admin: all upload buttons now open a crop-before-upload modal
- Canvas-based cropper (no external library)
- Ratio presets: 1:1, 4:3, 16:9, 3:4, free
- Drag to move crop box, drag corners to resize
- Touch support for mobile
- Crops client-side then uploads the result
- Frontend gallery: ba-label (قبل/بعد) now:
- Centered horizontally (block + width 100%)
- Wraps to multiple lines (white-space:normal)
- Responsive — never overflows or gets clipped
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add "Backup database" step that copies drsousan.db out of the
running container to /opt/drsousan-backups/ before any container
changes, keeping the last 10 backups
- Replace --force-recreate (broken on this Docker version) with
explicit docker stop + docker rm before docker compose up
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
docker compose up --force-recreate only works when Compose owns the
container. If the container was started outside Compose (e.g. manually
via docker restart), Compose can't recreate it and errors with
"container name already in use". Explicitly stopping and removing it
first handles both cases cleanly.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Without this flag, the deploy fails with "container name already in use"
when a container with the same name exists from a previous run.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Gallery section now fetches /api/gallery and renders real items
instead of hardcoded placeholders
- Before+after pairs render as side-by-side split with قبل/بعد labels
- Single imageUrl items render as a standard gallery card
- Tab buttons now filter items by category via data-cat attribute
- CSS added for .before-after, .ba-half, .ba-divider, .ba-label, .gallery-caption
- Fixes applied to correct file (Index.cshtml Razor page, not root index.html)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Prevents runner workspace directory name from being used as project name,
which caused Meezi containers to be treated as orphans and stopped on deploy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed <br> between name parts and added white-space:nowrap.
Adjusted clamp min from 2.2rem to 1.6rem so it scales down on
small screens without wrapping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>