From ffc43510381e6a64be96853e6a3b03792ea143a7 Mon Sep 17 00:00:00 2001
From: hamed <15238-genius.ha@users.noreply.drupalcode.org>
Date: Wed, 15 Jul 2026 17:30:26 +0330
Subject: [PATCH] fix: update PurchaseSubscriptionSidebar and
AppointmentSettingsPage for pixel-perfect alignment and color consistency
---
.claude/prompt/settings-menu-pixel-perfect.md | 159 ++++++++++++++++++
.../layout/PurchaseSubscriptionSidebar.tsx | 2 +-
.../components/layout/SettingsLayout.tsx | 5 +-
.../admin/pages/AppointmentSettingsPage.tsx | 2 +-
4 files changed, 165 insertions(+), 3 deletions(-)
create mode 100644 .claude/prompt/settings-menu-pixel-perfect.md
diff --git a/.claude/prompt/settings-menu-pixel-perfect.md b/.claude/prompt/settings-menu-pixel-perfect.md
new file mode 100644
index 00000000..2056c548
--- /dev/null
+++ b/.claude/prompt/settings-menu-pixel-perfect.md
@@ -0,0 +1,159 @@
+# پیکسلبهپیکسل کردن منوی تنظیمات + ریشهگرفتن رنگها از شخصیسازی
+
+## پروژه
+
+`clinicpro` (فقط پنل ادمین React — تغییر backend ندارد).
+
+اپ دسکتاپ `clinic-pro-tauri` فقط **مرجع بصری** است، نه هدف تغییر. صفحهی مرجع:
+`http://127.0.0.1:5170/setting/purchase-subscription`
+(کد آن: `clinic-pro-tauri/src/components/setting/listMenu/purchaseSubscription/PurchaseSubscriptionSidebar.jsx`)
+
+## زمینه
+
+پنل ادمین `clinicpro` یک ناحیهی «تنظیمات» دارد که کنار محتوا یک سایدمنوی مشترک (`PurchaseSubscriptionSidebar`) نمایش میدهد. این منو در همهی صفحات تنظیمات از طریق `SettingsLayout` رندر میشود.
+
+- صفحهی `/admin/subscription` (`SubscriptionPage.tsx`) درست و پیکسلبهپیکسل است — **مرجع درونپروژهای**.
+- صفحهی `/admin/appointment-settings` (`AppointmentSettingsPage.tsx`) **خراب** است: محتوا روی زمینهی خاکستری `#fafafa` نشسته، پنل سفید ندارد و فاصلهها با مرجع فرق دارد.
+
+## مشکل / هدف
+
+سه اصلاح مشخص:
+
+1. **رنگها باید از شخصیسازی ریشه بگیرند.** رنگ ردیف فعال منو در `PurchaseSubscriptionSidebar.tsx` بهصورت هاردکد `#f17732` است. باید از متغیر برند شخصیسازی (`var(--accent)`) استفاده کند تا با «رنگ اصلی» انتخابشده در پنل شخصیسازی (`Topbar.tsx` → `setBrandHue`) هماهنگ شود.
+
+2. **محتوای appointment-settings باید روی پنل سفید `#ffffff` بنشیند، نه `#fafafa`.** مرجع (tauri و نیز `SubscriptionPage.tsx`) محتوا را داخل یک پنل با `background: var(--surface)` (سفید) میگذارد. در appointment-settings محتوا مستقیم روی `--bg` صفحه (`#fafafa`) است. `#fafafa` رنگِ **ناحیهی منو** است، نه محتوا.
+
+3. **منو باید چسبیده به نوارِ کناری اصلی (سمت راست) باشد.** در مرجع tauri منوی تنظیمات فلاش به سایدبار اصلی میچسبد؛ در clinicpro بهخاطر padding محتوا فاصله افتاده.
+
+## فایلهای مرتبط
+
+| فایل | نقش |
+|------|-----|
+| `assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx` | سایدمنوی مشترک تنظیمات — رنگ ردیف فعال اینجاست |
+| `assets/admin/pages/AppointmentSettingsPage.tsx` | صفحهی خراب که باید پیکسلبهپیکسل شود |
+| `assets/admin/pages/SubscriptionPage.tsx` | **مرجع درست** — الگوی wrap محتوا در پنل سفید |
+| `assets/admin/components/layout/SettingsLayout.tsx` | شل تنظیمات (grid: `[248px_minmax(0,1fr)] gap-5`) — محل اصلاح فلاششدن |
+| `assets/admin/styles.css` | تعریف متغیرها: `--surface:#ffffff`، `--bg:#fafafa`، `--accent:#f0682a`، `--gap:20px`، `.content{padding:var(--gap);max-width:1480px;margin:0 auto}` |
+| `clinic-pro-tauri/.../PurchaseSubscriptionSidebar.jsx` | مرجع بصری (تغییر نده) |
+
+## وضعیت فعلی
+
+### ۱) رنگ هاردکد در سایدمنو — `PurchaseSubscriptionSidebar.tsx`
+
+```tsx
+const rowStyle: React.CSSProperties = {
+ borderRadius: 12, height: 44, marginBottom: 8,
+ display: 'flex', alignItems: 'center', justifyContent: 'flex-start',
+ padding: '0 14px', fontSize: 16, fontWeight: isActive ? 700 : 500,
+ lineHeight: 1, textAlign: 'right',
+ background: isActive ? '#f17732' : 'transparent', // ← هاردکد
+ color: isActive ? '#FFFFFF' : 'var(--text-2)',
+ cursor: item.to ? 'pointer' : 'not-allowed',
+ transition: 'background .14s',
+};
+// ...
+onMouseEnter={(e) => { if (!isActive) (e.currentTarget as HTMLElement).style.background = 'var(--surface-2)'; }}
+onMouseLeave={(e) => { if (!isActive) (e.currentTarget as HTMLElement).style.background = 'transparent'; }}
+```
+
+### ۲) صفحهی خراب — `AppointmentSettingsPage.tsx` (بازگشت فعلی)
+
+```tsx
+return (
+
+ {/* ← fade-in تکراری؛ SettingsLayout خودش fade-in دارد */}
+
مدیریت نوبت دهی
+
+ {!uuid ? (
+
این بخش فقط برای پزشک در دسترس است.
+ ) : isLoading ? (
+
در حال بارگذاری...
+ ) : (
+
{/* ← مستقیم روی #fafafa */}
+ )}
+
+
+);
+```
+
+### مرجع درست — `SubscriptionPage.tsx` (محتوا داخل پنل سفید)
+
+```tsx
+return (
+
+ {/* ← پنل سفید #ffffff */}
+
+ {/* محتوا */}
+
+
+
+);
+```
+
+## وظایف
+
+### ۱. رنگ ردیف فعال سایدمنو را از شخصیسازی بگیر
+
+در `PurchaseSubscriptionSidebar.tsx`:
+
+- `background: isActive ? '#f17732'` → `background: isActive ? 'var(--accent)'`
+- بررسی کن که در حالت hover و active در تم تیره هم درست باشد (متغیرهای `--accent`، `--surface-2` هر دو تم را در `styles.css` پوشش میدهند — نیازی به `.dark &` جدا نیست).
+- رنگ متن ردیف فعال `#FFFFFF` بماند (روی برند خوانا است).
+
+### ۲. محتوای appointment-settings را داخل پنل سفید بگذار و ساختار را مثل مرجع کن
+
+در `AppointmentSettingsPage.tsx`:
+
+- `
` تکراری را حذف کن (چون `SettingsLayout` خودش `fade-in` دارد) و بهجای آن دقیقاً الگوی `SubscriptionPage` را بهکار ببر:
+
+```tsx
+return (
+
+
+
مدیریت نوبت دهی
+
+ {!uuid ? (
+
+ این بخش فقط برای پزشک در دسترس است.
+
+ ) : isLoading ? (
+
در حال بارگذاری...
+ ) : (
+
+ )}
+
+
+);
+```
+
+- بعد از تغییر، چشمی چک کن که `WeeklyScheduleTab` و `FreeVisitPrice` روی سفید (`--surface`) بنشینند و padding/فاصلهها با `SubscriptionPage` یکی باشد. اگر `WeeklyScheduleTab` خودش زمینه/کارت داخلی دارد، مطمئن شو با پنل سفید بیرونی دوبارکارت (double-card) نمیشود.
+
+### ۳. منوی تنظیمات را فلاش به نوار کناری اصلی بچسبان
+
+مشکل: `.content` در `styles.css` دارای `padding: var(--gap)` (۲۰px) و `max-width:1480px; margin:0 auto` است؛ همین padding سمت راست، بین نوار کناری اصلی و منوی تنظیمات فاصله میاندازد.
+
+در `SettingsLayout.tsx` کاری کن ستون منو تا لبهی نوار کناری اصلی کشیده شود؛ گزینهی پیشنهادی: یک negative margin سمت راست روی ریشهی `SettingsLayout` برابر `--gap` تا padding محتوا خنثی شود، بدون شکستن `max-width` بخش محتوا:
+
+```tsx
+return (
+
+);
+```
+
+- **مهم:** RTL است؛ نوار کناری اصلی سمت راست است و منوی تنظیمات هم سمت راستِ گرید. جهت negative margin را با تست چشمی درست کن (`marginInlineStart`/`marginInlineEnd`) تا منو دقیقاً به نوار کناری بچسبد و لبهی چپِ محتوا از قاب بیرون نزند.
+- چون `SettingsLayout` مشترک است، بعد از این تغییر **همهی صفحات تنظیمات** (subscription، appointment، tags، insurance، …) را چک کن که همزمان درست بمانند.
+
+## نکات مهم
+
+- **هیچ تغییری در tauri نده** — فقط مرجع بصری است.
+- منبع رنگها = متغیرهای CSS در `assets/admin/styles.css`؛ رنگ برند شخصیسازی از `--accent` میآید (پنل `Topbar.tsx` → `setBrandHue`). هر رنگ هاردکد جدید ممنوع.
+- هر دو تم روشن/تیره باید سالم بمانند (`--surface`، `--accent`، `--surface-2` در هر دو تم تعریف شدهاند).
+- تست بصری پیکسلبهپیکسل: `SubscriptionPage` (درست) را کنار `AppointmentSettingsPage` بگذار؛ عرض منو، فاصله، زمینهی سفید و رنگ ردیف فعال باید یکسان باشند.
+- تستهای موجود را نگهدار: `PurchaseSubscriptionSidebar.test.tsx`، `SettingsLayout.test.tsx`، `AppointmentSettingsPage.test.tsx` — بعد از تغییر `npm test` (یا `ddev exec`) اجرا کن. اگر تستی رنگ هاردکد `#f17732` را چک میکند، آن را به `var(--accent)` بهروزرسانی کن.
+- backend/API دست نمیخورد → نیازی به بهروزرسانی `docs/api/*` نیست.
diff --git a/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx b/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx
index a3dd8385..c7c1e4e2 100644
--- a/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx
+++ b/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx
@@ -78,7 +78,7 @@ export default function PurchaseSubscriptionSidebar({ active }: { active: string
display: 'flex', alignItems: 'center', justifyContent: 'flex-start',
padding: '0 14px', fontSize: 16, fontWeight: isActive ? 700 : 500,
lineHeight: 1, textAlign: 'right',
- background: isActive ? '#f17732' : 'transparent',
+ background: isActive ? 'var(--accent)' : 'transparent',
color: isActive ? '#FFFFFF' : 'var(--text-2)',
cursor: item.to ? 'pointer' : 'not-allowed',
transition: 'background .14s',
diff --git a/assets/admin/components/layout/SettingsLayout.tsx b/assets/admin/components/layout/SettingsLayout.tsx
index 99b11f38..cdcbc3b9 100644
--- a/assets/admin/components/layout/SettingsLayout.tsx
+++ b/assets/admin/components/layout/SettingsLayout.tsx
@@ -50,7 +50,10 @@ export function menuForRole(role: string | null | undefined): SettingsMenuItem[]
export default function SettingsLayout({ active, children }: { active: string; children: React.ReactNode }) {
return (
-
+
diff --git a/assets/admin/pages/AppointmentSettingsPage.tsx b/assets/admin/pages/AppointmentSettingsPage.tsx
index f9247a93..f1d4be08 100644
--- a/assets/admin/pages/AppointmentSettingsPage.tsx
+++ b/assets/admin/pages/AppointmentSettingsPage.tsx
@@ -27,7 +27,7 @@ export default function AppointmentSettingsPage() {
return (
-