Files
clinicpro/.claude/skills/redesign-page/SKILL.md
T

9.2 KiB

name, description
name description
redesign-page بازطراحی UI/UX یک صفحه از پنل ادمین ClinicPro از روی URL آن — اسکرین‌شات گرفتن از صفحه، نگاشت URL به فایل سورس، آدیت انحراف‌ها از دیزاین‌سیستم، و بازنویسی صفحه با کامپوننت‌ها و توکن‌های موجود. استفاده کن وقتی کاربر یک URL از /admin می‌دهد و می‌گوید «این صفحه ui/ux خوبی ندارد»، «این صفحه را بازطراحی کن»، «redesign this page»، «این قسمت را درست کن»، یا «screenshot این صفحه».

بازطراحی صفحه پنل ادمین ClinicPro

پنل ادمین یک SPA کلاینت‌ساید است (React 19 + Webpack Encore، سرو شده از /admin/*). یعنی curl و فلگ --screenshot کروم به درد نمی‌خورند: هر دو روی فرم لاگین می‌نشینند، چون توکن JWT در localStorage['clinicpro-auth'] است.

درایور این skill آن کار را انجام می‌دهد: با API لاگین می‌کند، localStorage را seed می‌کند، بعد ناوبری و اسکرین‌شات می‌گیرد — با CDP روی WebSocket نیتیو Node 22، بدون هیچ وابستگی npm (نه playwright، نه puppeteer).

مسیرها نسبت به clinicpro/ هستند.

پیش‌نیازها

هیچ نصبی لازم نیست. فقط این دو:

ddev describe | head -3          # باید بالا باشد: https://clinic-pro.ddev.site
ls "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"

کروم در مسیر دیگری است؟ CHROME_BIN را ست کن.

گردش کار

۱. اسکرین‌شات صفحه فعلی

node .claude/skills/redesign-page/driver.mjs shot \
  "https://clinic-pro.ddev.site/admin/appointments" --out /tmp/before.png

بعد حتماً تصویر را با ابزار Read باز کن و نگاه کن. بدون دیدنِ صفحه، بازطراحی یعنی حدس زدن.

فلگ‌ها: --w 1440 --h 900 (سایز ویوپورت)، --wait 4000 (میلی‌ثانیه صبر برای رندر)، --full (کل صفحه، نه فقط ویوپورت).

موبایل هم ببین — این پنل RTL و پرجدول است و بیشتر مشکلات ریسپانسیو آنجاست:

node .claude/skills/redesign-page/driver.mjs shot \
  "https://clinic-pro.ddev.site/admin/appointments" --w 390 --h 844 --out /tmp/mobile.png

۲. نگاشت URL به سورس + آدیت

node .claude/skills/redesign-page/driver.mjs inspect \
  "https://clinic-pro.ddev.site/admin/clinics/41e325c4-e825-4067-8438-5d828ecaee09"

خروجی واقعی:

route     clinics/:uuid
component ClinicDetailPage
file      assets/admin/pages/ClinicDetailPage.tsx
components ConfirmDialog, Modal, PageHeader, SearchableSelect, NotificationMobileCard
lines     1035

AUDIT
  assets/admin/pages/ClinicDetailPage.tsx:242  hand-rolled overlay — use the shared <Modal>

روی هر فایل دلخواه هم مستقیم:

node .claude/skills/redesign-page/driver.mjs audit assets/admin/pages/AppointmentsPage.tsx

۳. قبل از نوشتن کد، دیزاین‌سیستم را بخوان

منبع حقیقتِ توکن‌ها assets/admin/styles.css است — نه docs/admin-ui/ui-design-spec.md (آن سند قدیمی و پالت بنفشش با کد شیپ‌شده نمی‌خواند).

sed -n '/^:root/,/^}/p' assets/admin/styles.css | head -60   # توکن‌ها
ls assets/admin/components/ui/                               # کامپوننت‌های آماده

قانون: اول کامپوننت موجود، بعد توسعه‌اش، در آخر ساخت کامپوننت جدید — و دلیلش را بنویس.

۴. بازنویسی، سپس مقایسه

بعد از ادیت، دوباره اسکرین‌شات بگیر و با before.png مقایسه کن:

yarn dev   # یا: yarn watch
node .claude/skills/redesign-page/driver.mjs shot "<همان url>" --out /tmp/after.png

۵. تست + تایپ‌چک (بدون این، تسک تمام نیست)

npx tsc --noEmit -p tsconfig.json
npx vitest run assets/admin/pages/<YourPage>.test.tsx

توجه: سوییت کامل همین الان ۲۱ تست از پیش شکسته دارد (api.test.ts، LoginPage، PatientDetailPage، …) که ربطی به کار تو ندارند. قبل از شروع یک‌بار npx vitest run بگیر و عدد پایه را یادداشت کن، وگرنه خطاهای موجود را به گردن تغییر خودت می‌اندازی.

چک‌لیست بازطراحی

درایور موارد گرپ‌شدنی را می‌گیرد؛ این‌ها را باید خودت با چشم ببینی:

  • .field در مقابل .field-block.field یک باکس افقی بوردردار است که لیبل داخلش می‌نشیند. اگر <label> داخل .field بگذاری، لیبل کنار اینپوت می‌چسبد؛ و اگر SearchableSelect داخلش بگذاری، دو باکس تودرتو می‌شود. برای «لیبل بالای فیلد» از .field-block استفاده کن.
  • className="btn" بدون واریانت بی‌رنگ و بدون بوردر رندر می‌شود — عملاً نامرئی. همیشه btn primary / btn ghost / btn soft / btn danger.
  • دکمه‌های فقط-آیکونmini-btn، نه btn ghost sm با پدینگ دستی.
  • توکن مرده — مثلاً var(--error) وجود ندارد (--danger درست است). درایور این را می‌گیرد.
  • سلسله‌مراتب — عنوان صفحه در PageHeader بیاید و در کارت زیرش تکرار نشود.
  • RTL/جلالی — رشته‌های جدید فارسی، تاریخ‌ها جلالی، اعداد با formatNumber/formatRial.
  • دارک‌مود — چون توکن استفاده می‌کنی خودکار درست است؛ هگز هاردکد آن را می‌شکند.

Gotchas

  • ریدایرکت خاموش نقش‌ها. RoleRoute کاربری که نقشش اجازه ندارد را بی‌صدا به /admin/dashboard می‌برد. یعنی یک اسکرین‌شات کاملاً سالم از صفحهٔ اشتباه می‌گیری. درایور مسیر نهایی را با مسیر درخواستی مقایسه می‌کند و هشدار می‌دهد:

    ⚠ WRONG PAGE: asked for /admin/clinics/…, landed on /admin/dashboard
    

    کاربر پیش‌فرض (09390039833) نقش doctor دارد. صفحات ادمین/کلینیک با آن باز نمی‌شوند. برای آن‌ها CLINICPRO_USER / CLINICPRO_PASS را ست کن.

  • کاربران تستی ممکن است seed نشده باشند. TEST_USERS.md ادمین 09100000001 با رمز Test@1234 را مستند می‌کند، ولی روی این دیتابیس وجود نداشت و لاگین ERR_AUTH_005 داد. ساختنشان: ddev exec php create_test_users.php (دیتابیس را می‌نویسد — اول بپرس).

  • مودال نصب PWA جلوی صفحه را می‌گیرد. درایور localStorage['pwa-dismissed']='1' را seed می‌کند. اگر با کروم خام اسکرین‌شات بگیری، این مودال وسط تصویر است.

  • کپچا (altcha) لوکال اجباری نیست. POST /api/v1/user/login بدون فیلد altcha هم توکن می‌دهد؛ درایور به همین تکیه می‌کند. اگر روی محیطی که کپچا را اجبار می‌کند اجرا شود، می‌شکند.

  • سرت ddev را Node رد می‌کند (UNABLE_TO_VERIFY_LEAF_SIGNATURE). درایور فقط برای هاست‌های *.ddev.site / localhost تأیید TLS را خاموش می‌کند، نه برای هر مبدأ.

  • صفحهٔ نوبت‌ها خودش اسکرول می‌شود به ساعت جاری، پس ویوپورت وسط تایم‌لاین می‌افتد. برای دیدن هدر از --full استفاده کن.

  • بیلد CSS داخل ddev خطای نیتیو lightningcss می‌دهد — از قبل وجود دارد و جلوی کامپایل JS/TS را نمی‌گیرد. خطاهای TypeScript همچنان در خروجی tsc می‌آیند.

Troubleshooting

علامت علت / راه‌حل
Chrome did not expose CDP on :9333 نمونهٔ کروم قبلی زنده مانده. CDP_PORT=9444 بده یا پروسه را بکش.
login failed: … ERR_AUTH_005 کاربر seed نشده یا رمز فرق دارد. TEST_USERS.md را ببین.
⚠ redirected to /login توکن رد شد؛ معمولاً یعنی JWT منقضی شده — دوباره اجرا کن.
⚠ page text is only N chars صفحه خالی رندر شده. --wait 8000 بده یا کنسول را چک کن.
اسکرین‌شات تغییرات را نشان نمی‌دهد باندل قدیمی است. yarn dev بزن (یا yarn watch روشن باشد).