All changes are gated behind max-md:/md:hidden so the >=768px desktop layout is untouched (verified with lint + build + live checks at 375px). - globals.css: one mobile block — 16px inputs (no iOS auto-zoom), units sidebar stacks above content, wizard item rows become 2-col (text fields full-width, delete button full-width), dd-panels / flow diagram / conv-form stack, larger touch targets - ui/dialog.tsx: dialogs become full-width bottom sheets on mobile (all modals inherit it); desktop keeps the centered dialog - Header: sticky on mobile only + PageLayout bottom clearance - New MobileTabBar: role-aware bottom tabs (office admin/manager, inventory PM, inventory admin); hidden on /wizard - Wizard step 4: TouchSensor (150ms delay) so touch drag works without stealing scroll - JalaliDatePicker: dropdown capped to viewport; bigger day cells and time inputs on mobile - PWA: manifest.webmanifest + 192/512 icons (scripts/gen-pwa-icons.ps1) + theme-color/manifest links in index.html - New docs/mobile-responsive.md documenting the full change set
8.3 KiB
Mobile-Responsive UI — Change Log (v1.4)
هدف: تجربهی کاربری قابلاستفاده برای کاربران موبایل (اکثریت کاربران)، بدون اینکه ظاهر دسکتاپ هیچ تغییری بکند. هیچ بکاند، nginx، docker-compose یا ساختار جدیدی اضافه نشده — همهچیز داخل همان اپ React است.
Core principle
یک کدبیس، دو نمایش. همهی تغییرات «فقط موبایل» هستند و پشت بریکپوینت
Tailwind max-md: (زیر 768px) یا md:hidden (فقط روی موبایل نمایش داده میشود)
قفل شدهاند. دسکتاپ (≥768px) همان استایلهای قبلی را میخواند و بنابراین
پیکسلبهپیکسل بدون تغییر میماند — بهساختار.
What changed
1. frontend/src/styles/globals.css — consolidated mobile block (new)
یک بلوک @media (max-width: 767.98px) در انتهای فایل اضافه شد:
| Rule | Effect (mobile only) |
|---|---|
input/select/textarea { font-size: 16px !important } |
جلوگیری از زوم خودکار iOS روی فوکوس (فونتهای ۱۲–۱۴px زوم میشدند) |
.units-layout { grid-template-columns: 1fr } |
سایدبار ۲۲۰px دستهها روی موبایل بالای پنل محتوا قرار میگیرد |
.item-row-head { display: none } + .wizard-item-row دوستونه |
ردیف اقلام ویزارد (گرید ۸ ستونه) روی موبایل میشود: فیلدهای متنی تمامعرض، عددها دوستونه؛ placeholderها نقش برچسب را دارند |
.wizard-item-row > :last-child تمامعرض + حداقل ۴۴×۴۰px |
دکمهی حذف قلم بزرگ و قابل لمس |
.dd-panels { grid-template-columns: 1fr } |
پنلهای درگاندروپ مرحلهی ۴ تکستونه |
.flow-cols تکستونه + .flow-lines { display: none } |
نمودار جریان باکسها روی هم؛ خطوط SVG اتصال که فقط در چیدمان دوستونه معنی داشتند روی موبایل مخفی میشوند |
.conv-form تکستونه، .conv-row wrap |
فرم تبدیل واحد (گرید ۵ ستونه) روی موبایل ستونی |
touch targets بزرگتر (.chip, .quick-chip, .spec-chip, .dd-item, .ut-cat, .btn-line-file, دکمههای × و ...) |
ارتفاع هدف لمسی به ~۴۰px رسید |
2. frontend/src/components/ui/dialog.tsx — dialogs become bottom sheets
DialogContent با کلاسهای max-md: به bottom-sheet تمامعرض تبدیل شد
(inset-x-0 bottom-0، گوشههای گرد فقط بالا، max-h-[85dvh]، padding با
safe-area-inset-bottom). چون همهی مودالها (ویرایش، پذیرش، تایید حذف) از همین
کامپوننت استفاده میکنند، همه یکجا درست شدند. دکمهی بستن هم بزرگتر شد.
3. Form grids stacked — one-line additions each
EditModal.tsx— گرید تأمینکننده/پروژه و گرید تاریخها:max-md:grid-cols-1Wizard/Step1TopicSupplier.tsx— فرم تأمینکنندهی جدید:max-md:grid-cols-1Wizard/Step5Review.tsx— گرید تاریخها:max-md:grid-cols-1Suppliers/CategoryPage.tsx— فرم افزودن تأمینکننده:max-md:grid-cols-1
4. frontend/src/components/layout/Header.tsx — sticky header + clearance
- هدر فقط روی موبایل
sticky top-0 z-40شد (max-md:) - دکمهی بازگشت بزرگتر شد
PageLayoutروی موبایلpb-24گرفت تا نوار تب پایین روی محتوا نیفتد
5. frontend/src/components/layout/MobileTabBar.tsx — NEW mobile bottom tab bar
نوار تب پایین (فقط <768px با md:hidden):
- ادمین / مدیر تدارکات در دفتر: داشبورد / تأمینکنندهها / پروژهها / ضرایب
- ادمین / مدیر تدارکات در پنل انبار: انبار / کنترل روزانه / کالاهای در راه / سازماندهی (آینهی ناوبری دسکتاپ)
- مدیر پروژه: انبار / تغییر موجودی / کنترل روزانه / کالاهای در راه
- هدف لمسی ≥۵۶px، padding برای
safe-area-inset-bottom، هایلایت تب فعال - در
/wizardنمایش داده نمیشود (تا با جابهجایی تصادفی کارِ کاربر از بین نرود)
6. frontend/src/App.tsx — renders <MobileTabBar />
7. frontend/src/pages/Wizard/Step4Projects.tsx — touch drag & drop
TouchSensor با { delay: 150, tolerance: 8 } به سنسورهای dnd-kit اضافه شد:
درگ لمسی کار میکند بدون اینکه اسکرول صفحه را بدزدد. مسیر کلیک-قلم-بعد-کلیک-پروژه
همچنان مسیر جایگزین است. دسکتاپ همان PointerSensor قبلی را دارد.
8. frontend/src/components/JalaliDatePicker.tsx — dropdown width + targets
- داپداون تقویم:
max-w-[calc(100vw-2rem)](در صفحههای باریک سرریز نمیشود) - سلولهای روز و ورودیهای ساعت/دقیقه روی موبایل بزرگتر شدند
9. PWA layer (optional installability)
frontend/public/manifest.webmanifest— NEW (name فارسی،dir: rtl،display: standalone، theme#4f46e5، آیکون 192/512 + maskable)frontend/public/icons/icon-192.png,icon-512.png— NEW (تولیدشده باfrontend/scripts/gen-pwa-icons.ps1— NEW، بدون وابستگی)frontend/index.html—theme-color+ لینک manifest + آیکونها اضافه شد- روی HTTP مثل میانبر صفحهی اصلی کار میکند؛ پرامپت نصب رسمی PWA به HTTPS نیاز دارد (بعداً با پروکسی/Let's Encrypt — بدون تغییر کد).
Deliberately NOT changed
SpecDrawer.tsx: کد مرده است (هیچجا import نمیشود) — تصمیم تیم: دست نمیزنیم، فایل میماند..e-item-row/.spec-drawerدر CSS: کلاسهای بلااستفاده — دستنخورده ماندند.- هیچ کلاس/استایل دسکتاپی ویرایش نشد؛ تمام تغییرات داخل
max-md:یا کامپوننتهایmd:hiddenاست.
Verification performed
npm run lint(oxlint) → 0 errors (4 هشدار از قبل موجود)npm run build(tsc + vite) → موفق- تست مرورگر روی Vite dev (viewport واقعی 375px):
- نوار تب:
fixed bottom-0، قابلمشاهده، ۴ تب با برچسب درست، ارتفاع ≥56px - هدر
sticky، ورودیها 16px، padding پایین صفحه 96px (جای نوار تب) - صفحات ضرایب/ویزارد چیدمان تکستونه (
.units-layoutفقط بعد از انتخاب موضوع رندر میشود)
- نوار تب:
- رگرسیون دسکتاپ: کلاسهای دسکتاپ دستنخوردهاند (بریکپوینتگیت)؛
npm run buildسلامت باندل را تایید میکند.
How to test manually
cd C:\Users\Reza\Desktop\v1.4
docker compose up -d --build # بازسازی ایمیج فرانت
سپس در مرورگر دسکتاپ DevTools → device toolbar (مثلاً iPhone SE 375px) یا مستقیم با گوشی (بخش «دیدن روی گوشی» در README/جواب نهایی). دسکتاپ را هم در 1280px چک کنید — باید دقیقاً مثل قبل باشد.
Notes / known considerations
- خطوط اتصال نمودار جریان (SVG) روی موبایل عمداً مخفی شد — فقط باکسها روی هم
قرار میگیرند؛ اگر روزی خواستید اتصالها را روی موبایل هم ببینید باید
FlowDiagramبرای حالت تکستونه بازنویسی شود. - نوار تب موبایل «انبارها» را ندارد (PMها از منوی همبرگری به آن میرسند).