menu page

This commit is contained in:
Efril
2026-01-16 13:27:09 +07:00
parent 82e1f93cce
commit 44d48d41d4
17 changed files with 1090 additions and 316 deletions
@@ -0,0 +1,134 @@
import 'package:flutter/material.dart';
import '../../../../common/constant/app_constant.dart';
import '../../../../common/data/service_data.dart';
import '../../../../common/theme/theme.dart';
class MenuHeader extends StatelessWidget {
final Service service;
const MenuHeader({super.key, required this.service});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [AppColor.primary, AppColor.primary.withOpacity(0.8)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Stack(
children: [
// Background decoration
Positioned(
right: 20,
top: 60,
child: Opacity(
opacity: 0.1,
child: Icon(Icons.store, size: 100, color: AppColor.textWhite),
),
),
// Content
Positioned(
left: 20,
right: 20,
bottom: 20,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Service
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
service.name,
style: AppStyle.lg.copyWith(
color: AppColor.white,
fontWeight: FontWeight.bold,
),
),
Text(
service.description,
style: AppStyle.md.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w500,
),
),
],
),
SizedBox(height: 16),
// Merchant
Row(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: AppColor.surface,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: AppColor.black.withOpacity(0.2),
blurRadius: 8,
offset: Offset(0, 4),
),
],
),
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(merchant.imageUrl),
),
),
),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
merchant.name,
style: AppStyle.h6.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.bold,
),
),
Text(
merchant.category,
style: AppStyle.md.copyWith(
color: AppColor.textWhite.withOpacity(0.9),
),
),
Row(children: [SizedBox(width: 12)]),
],
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: merchant.isOpen
? AppColor.success
: AppColor.error,
borderRadius: BorderRadius.circular(6),
),
child: Text(
merchant.isOpen ? "BUKA" : "TUTUP",
style: AppStyle.xs.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.bold,
),
),
),
],
),
],
),
),
],
),
);
}
}
@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../../sample/product_sample_data.dart';
import '../../../components/card/product_card.dart';
import '../../../components/card/product_empty_card.dart';
class MenuProductSection extends StatelessWidget {
final ProductCategory category;
final List<Product> categoryProducts;
const MenuProductSection({
super.key,
required this.category,
required this.categoryProducts,
});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Section header
Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Row(
children: [
Text(category.icon, style: AppStyle.h5),
SizedBox(width: 8),
Text(
category.name,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.textPrimary,
),
),
SizedBox(width: 8),
Text(
"(${categoryProducts.length})",
style: AppStyle.md.copyWith(color: AppColor.textSecondary),
),
],
),
),
// Products grid
if (categoryProducts.isEmpty)
ProductEmptyCard()
else
GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: 16),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
childAspectRatio: 0.75,
),
itemCount: categoryProducts.length,
itemBuilder: (context, index) {
return ProductCard(product: categoryProducts[index]);
},
),
],
),
);
}
}