add price policy

This commit is contained in:
Phuoc Nguyen
2025-11-03 11:20:09 +07:00
parent c0527a086c
commit 21c1c3372c
53 changed files with 7160 additions and 2361 deletions

View File

@@ -151,6 +151,29 @@ class HomePage extends ConsumerWidget {
],
),
// Orders & Payments Section
QuickActionSection(
title: 'Đơn hàng & thanh toán',
actions: [
QuickAction(
icon: Icons.description,
label: 'Chính sách giá',
onTap: () => context.push(RouteNames.pricePolicy),
),
QuickAction(
icon: Icons.inventory_2,
label: 'Đơn hàng',
onTap: () => context.push(RouteNames.orders),
),
QuickAction(
icon: Icons.receipt_long,
label: 'Thanh toán',
onTap: () =>
context.push(RouteNames.payments)
),
],
),
// Loyalty Section
QuickActionSection(
title: 'Khách hàng thân thiết',
@@ -174,28 +197,7 @@ class HomePage extends ConsumerWidget {
],
),
// Orders & Payments Section
QuickActionSection(
title: 'Đơn hàng & thanh toán',
actions: [
QuickAction(
icon: Icons.description,
label: 'Yêu cầu báo giá',
onTap: () => context.push(RouteNames.quotes),
),
QuickAction(
icon: Icons.inventory_2,
label: 'Đơn hàng',
onTap: () => context.push(RouteNames.orders),
),
QuickAction(
icon: Icons.receipt_long,
label: 'Thanh toán',
onTap: () =>
context.push(RouteNames.payments)
),
],
),
// Sample Houses & News Section
QuickActionSection(
@@ -212,11 +214,11 @@ class HomePage extends ConsumerWidget {
onTap: () =>
_showComingSoon(context, 'Đăng ký dự án', l10n),
),
QuickAction(
icon: Icons.article,
label: 'Tin tức',
onTap: () => _showComingSoon(context, 'Tin tức', l10n),
),
// QuickAction(
// icon: Icons.article,
// label: 'Tin tức',
// onTap: () => _showComingSoon(context, 'Tin tức', l10n),
// ),
],
),

View File

@@ -83,26 +83,70 @@ class QuickActionSection extends StatelessWidget {
}
Widget _buildActionGrid() {
return GridView.builder(
padding: EdgeInsets.zero, // Remove default GridView padding
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, // Always 3 columns to match HTML
childAspectRatio: 1.0,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
// Determine grid columns based on item count
// If 2 items: 2 columns (no scroll, rectangular aspect ratio)
// If 3 items: 3 columns (no scroll)
// If more than 3: 3 columns (scrollable horizontally)
final int crossAxisCount = actions.length == 2 ? 2 : 3;
final bool isScrollable = actions.length > 3;
// Use rectangular aspect ratio for 2 items to reduce height
// 1.5 means width is 1.5x the height (more rectangular/wider)
final double aspectRatio = actions.length == 2 ? 1.5 : 0.85;
if (!isScrollable) {
// Non-scrollable grid for 2 or 3 items
return GridView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
childAspectRatio: aspectRatio,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: actions.length,
itemBuilder: (context, index) {
final action = actions[index];
return QuickActionItem(
icon: action.icon,
label: action.label,
badge: action.badge,
onTap: action.onTap,
);
},
);
}
// Scrollable horizontal grid for more than 3 items
// Calculate grid height based on number of rows needed
final int rows = (actions.length / crossAxisCount).ceil();
const double itemHeight = 100; // Approximate height of each item
final double gridHeight = (rows * itemHeight) + ((rows - 1) * 8);
return SizedBox(
height: gridHeight,
child: GridView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
childAspectRatio: 1.0,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: actions.length,
itemBuilder: (context, index) {
final action = actions[index];
return QuickActionItem(
icon: action.icon,
label: action.label,
badge: action.badge,
onTap: action.onTap,
);
},
),
itemCount: actions.length,
itemBuilder: (context, index) {
final action = actions[index];
return QuickActionItem(
icon: action.icon,
label: action.label,
badge: action.badge,
onTap: action.onTap,
);
},
);
}
}