281 lines
8.5 KiB
Markdown
Executable file
281 lines
8.5 KiB
Markdown
Executable file
# گزارش بررسی Responsive Design صفحات فرانت
|
||
|
||
## خلاصه اجرایی
|
||
|
||
این گزارش وضعیت سازگاری صفحات فرانت با موبایل، تبلت و دسکتاپ را بررسی میکند و پیشنهاداتی برای بهبود ارائه میدهد.
|
||
|
||
---
|
||
|
||
## صفحات با وضعیت خوب ✅
|
||
|
||
### 1. BusinessDashboardPage
|
||
**وضعیت:** ✅ خوب
|
||
- استفاده از breakpoint های استاندارد (xs, sm, md, lg, xl)
|
||
- متدهای helper برای padding، spacing و اندازههای responsive
|
||
- LayoutBuilder برای تطبیق با اندازه صفحه
|
||
- مدیریت مناسب برای موبایل و دسکتاپ
|
||
|
||
**نکات مثبت:**
|
||
- `_currentBreakpoint()` برای تشخیص اندازه صفحه
|
||
- `_getPadding()`, `_getGridSpacing()`, `_getMinTileUnit()` برای مقادیر responsive
|
||
- `_isMobile()` برای چیدمان شرطی
|
||
|
||
---
|
||
|
||
### 2. ProfileDashboardPage
|
||
**وضعیت:** ✅ خوب
|
||
- مشابه BusinessDashboardPage
|
||
- استفاده از breakpoint های یکسان
|
||
- مدیریت responsive برای ویجتها
|
||
|
||
---
|
||
|
||
## صفحات نیازمند بهبود ⚠️
|
||
|
||
### 3. LoginPage
|
||
**وضعیت:** ⚠️ نیازمند بهبود
|
||
**مشکلات:**
|
||
- `maxWidth: 520` ثابت برای کارت - در تبلت و دسکتاپ خیلی کوچک است
|
||
- استفاده از `LayoutBuilder` اما بدون breakpoint های مناسب
|
||
|
||
**پیشنهادات:**
|
||
```dart
|
||
// به جای maxWidth ثابت:
|
||
ConstrainedBox(
|
||
constraints: BoxConstraints(
|
||
maxWidth: _isMobile(context) ? double.infinity : 520,
|
||
minHeight: constraints.maxHeight - 32,
|
||
),
|
||
child: Card(...)
|
||
)
|
||
|
||
// یا استفاده از breakpoint:
|
||
final width = MediaQuery.of(context).size.width;
|
||
final maxCardWidth = width < 600 ? double.infinity :
|
||
width < 904 ? 520 :
|
||
width < 1240 ? 600 : 700;
|
||
```
|
||
|
||
---
|
||
|
||
### 4. InvoicesListPage
|
||
**وضعیت:** ⚠️ نیازمند بهبود
|
||
**مشکلات:**
|
||
- `SegmentedButton` در `Row` با `Expanded` - در موبایل ممکن است overflow شود
|
||
- فیلترهای تاریخ در `Row` - در موبایل باید به Column تبدیل شود
|
||
- دکمه "افزودن" در هدر - در موبایل باید به FloatingActionButton تبدیل شود
|
||
|
||
**پیشنهادات:**
|
||
```dart
|
||
// استفاده از LayoutBuilder برای فیلترها:
|
||
LayoutBuilder(
|
||
builder: (context, constraints) {
|
||
final isMobile = constraints.maxWidth < 600;
|
||
if (isMobile) {
|
||
return Column(
|
||
children: [
|
||
// SegmentedButton در Column
|
||
// فیلترهای تاریخ در Column
|
||
],
|
||
);
|
||
} else {
|
||
return Row(
|
||
children: [
|
||
// چیدمان فعلی
|
||
],
|
||
);
|
||
}
|
||
},
|
||
)
|
||
|
||
// برای دکمه افزودن:
|
||
if (isMobile)
|
||
FloatingActionButton(...)
|
||
else
|
||
FilledButton.icon(...)
|
||
```
|
||
|
||
---
|
||
|
||
### 5. TaxWorkspacePage
|
||
**وضعیت:** ⚠️ نیازمند بهبود
|
||
**مشکلات:**
|
||
- مشابه InvoicesListPage
|
||
- `SegmentedButton` در `Row` - مشکل در موبایل
|
||
- فیلترهای تاریخ و وضعیت در `Row` - باید responsive باشد
|
||
|
||
**پیشنهادات:**
|
||
- مشابه InvoicesListPage
|
||
- استفاده از `LayoutBuilder` برای تشخیص موبایل
|
||
- تبدیل `Row` به `Column` در موبایل
|
||
|
||
---
|
||
|
||
### 6. ProductsPage
|
||
**وضعیت:** ⚠️ نیازمند بهبود
|
||
**مشکلات:**
|
||
- دیالوگ محصول با `maxWidth: 900` - در موبایل باید fullscreen شود
|
||
- GridView با `maxCrossAxisExtent: 260` - در موبایل باید تنظیم شود
|
||
- تصویر محصول با عرض ثابت `240` - باید responsive باشد
|
||
|
||
**پیشنهادات:**
|
||
```dart
|
||
// برای دیالوگ:
|
||
Dialog(
|
||
insetPadding: EdgeInsets.all(
|
||
MediaQuery.of(context).size.width < 600 ? 0 : 24
|
||
),
|
||
child: ConstrainedBox(
|
||
constraints: BoxConstraints(
|
||
maxWidth: MediaQuery.of(context).size.width < 600
|
||
? double.infinity
|
||
: 900,
|
||
maxHeight: MediaQuery.of(context).size.height * 0.9,
|
||
),
|
||
),
|
||
)
|
||
|
||
// برای GridView:
|
||
SliverGridDelegateWithMaxCrossAxisExtent(
|
||
maxCrossAxisExtent: MediaQuery.of(context).size.width < 600
|
||
? double.infinity
|
||
: 260,
|
||
childAspectRatio: 2.15,
|
||
)
|
||
|
||
// برای تصویر:
|
||
SizedBox(
|
||
width: MediaQuery.of(context).size.width < 600
|
||
? double.infinity
|
||
: 240,
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### 7. PersonsPage
|
||
**وضعیت:** ⚠️ نیازمند بررسی
|
||
**مشکلات:**
|
||
- استفاده از `DataTableWidget` - باید بررسی شود که آیا خود این ویجت responsive است یا نه
|
||
- تعداد ستونهای زیاد - در موبایل باید برخی ستونها مخفی شوند
|
||
|
||
**پیشنهادات:**
|
||
- بررسی `DataTableWidget` برای responsive بودن
|
||
- استفاده از `ColumnWidth` های مناسب
|
||
- در موبایل، نمایش فقط ستونهای ضروری
|
||
|
||
---
|
||
|
||
## صفحات نیازمند بررسی بیشتر 🔍
|
||
|
||
### 8. HomePage
|
||
**وضعیت:** 🔍 نیازمند بررسی
|
||
- صفحه ساده اما باید بررسی شود که آیا در موبایل مناسب است
|
||
|
||
---
|
||
|
||
## پیشنهادات کلی برای بهبود
|
||
|
||
### 1. ایجاد یک Utility Class برای Responsive Design
|
||
```dart
|
||
class ResponsiveHelper {
|
||
static String breakpoint(BuildContext context) {
|
||
final width = MediaQuery.of(context).size.width;
|
||
if (width < 600) return 'xs';
|
||
if (width < 904) return 'sm';
|
||
if (width < 1240) return 'md';
|
||
if (width < 1600) return 'lg';
|
||
return 'xl';
|
||
}
|
||
|
||
static bool isMobile(BuildContext context) {
|
||
return breakpoint(context) == 'xs';
|
||
}
|
||
|
||
static bool isTablet(BuildContext context) {
|
||
final bp = breakpoint(context);
|
||
return bp == 'sm' || bp == 'md';
|
||
}
|
||
|
||
static bool isDesktop(BuildContext context) {
|
||
final bp = breakpoint(context);
|
||
return bp == 'lg' || bp == 'xl';
|
||
}
|
||
|
||
static double responsiveValue(
|
||
BuildContext context, {
|
||
required double mobile,
|
||
double? tablet,
|
||
double? desktop,
|
||
}) {
|
||
if (isMobile(context)) return mobile;
|
||
if (isTablet(context)) return tablet ?? mobile * 1.5;
|
||
return desktop ?? mobile * 2;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. استفاده از LayoutBuilder به جای MediaQuery مستقیم
|
||
- `LayoutBuilder` بهتر است چون constraints واقعی را میدهد
|
||
- `MediaQuery` ممکن است در برخی موارد نادرست باشد
|
||
|
||
### 3. تبدیل Row به Column در موبایل
|
||
- برای فیلترها و دکمهها
|
||
- استفاده از `LayoutBuilder` برای تشخیص
|
||
|
||
### 4. استفاده از FloatingActionButton در موبایل
|
||
- برای دکمههای اصلی (افزودن، ذخیره)
|
||
- در دسکتاپ از `FilledButton` استفاده شود
|
||
|
||
### 5. تنظیم Dialog ها برای موبایل
|
||
- در موبایل: `insetPadding: EdgeInsets.zero` و `fullscreen: true`
|
||
- در دسکتاپ: `insetPadding: EdgeInsets.all(24)`
|
||
|
||
### 6. استفاده از Wrap به جای Row برای دکمهها
|
||
- `Wrap` به صورت خودکار به خط بعد میرود
|
||
- مناسب برای موبایل
|
||
|
||
### 7. تنظیم GridView برای موبایل
|
||
- در موبایل: `crossAxisCount: 1` یا `maxCrossAxisExtent: double.infinity`
|
||
- در تبلت: `crossAxisCount: 2`
|
||
- در دسکتاپ: `crossAxisCount: 3` یا بیشتر
|
||
|
||
---
|
||
|
||
## اولویتبندی بهبودها
|
||
|
||
### اولویت بالا 🔴
|
||
1. **InvoicesListPage** - فیلترها و دکمهها
|
||
2. **TaxWorkspacePage** - مشابه InvoicesListPage
|
||
3. **LoginPage** - کارت ورود
|
||
|
||
### اولویت متوسط 🟡
|
||
4. **ProductsPage** - دیالوگها و GridView
|
||
5. **PersonsPage** - بررسی DataTableWidget
|
||
|
||
### اولویت پایین 🟢
|
||
6. **HomePage** - بررسی کلی
|
||
7. ایجاد Utility Class برای Responsive Design
|
||
|
||
---
|
||
|
||
## Breakpoint های پیشنهادی
|
||
|
||
```dart
|
||
// موبایل (xs): < 600px
|
||
// تبلت کوچک (sm): 600px - 903px
|
||
// تبلت بزرگ (md): 904px - 1239px
|
||
// دسکتاپ کوچک (lg): 1240px - 1599px
|
||
// دسکتاپ بزرگ (xl): >= 1600px
|
||
```
|
||
|
||
این breakpoint ها با Material Design 3 و Flutter همخوانی دارند.
|
||
|
||
---
|
||
|
||
## نتیجهگیری
|
||
|
||
بیشتر صفحات نیازمند بهبود در responsive design هستند. صفحات Dashboard (Business و Profile) وضعیت خوبی دارند و میتوانند به عنوان الگو استفاده شوند.
|
||
|
||
**توصیه:** ابتدا صفحات با اولویت بالا را بهبود دهید، سپس Utility Class را ایجاد کنید و در تمام صفحات استفاده کنید.
|
||
|