Compare commits
5 Commits
c790d00341
...
06cc7e3781
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06cc7e3781 | ||
|
|
88c3cebd31 | ||
|
|
c13e3c598e | ||
|
|
936875c30a | ||
|
|
0afb683045 |
@ -16,19 +16,6 @@ class ThemeApp {
|
|||||||
fontFamily: FontFamily.quicksand,
|
fontFamily: FontFamily.quicksand,
|
||||||
primaryColor: AppColor.primary,
|
primaryColor: AppColor.primary,
|
||||||
scaffoldBackgroundColor: AppColor.white,
|
scaffoldBackgroundColor: AppColor.white,
|
||||||
textTheme: TextTheme(
|
|
||||||
bodySmall: AppStyle.xs,
|
|
||||||
bodyMedium: AppStyle.md,
|
|
||||||
bodyLarge: AppStyle.lg,
|
|
||||||
labelSmall: AppStyle.sm,
|
|
||||||
labelLarge: AppStyle.xl,
|
|
||||||
headlineSmall: AppStyle.h6,
|
|
||||||
headlineMedium: AppStyle.h5,
|
|
||||||
headlineLarge: AppStyle.h4,
|
|
||||||
displaySmall: AppStyle.h3,
|
|
||||||
displayMedium: AppStyle.h2,
|
|
||||||
displayLarge: AppStyle.h1,
|
|
||||||
),
|
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
backgroundColor: AppColor.white,
|
backgroundColor: AppColor.white,
|
||||||
foregroundColor: AppColor.textPrimary,
|
foregroundColor: AppColor.textPrimary,
|
||||||
|
|||||||
@ -107,10 +107,6 @@ class _DrawPageState extends State<DrawPage> {
|
|||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isUserEntered(String drawId) {
|
|
||||||
return userEntries.any((entry) => entry.drawId == drawId);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _getTimeRemaining(DateTime targetDate) {
|
String _getTimeRemaining(DateTime targetDate) {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final difference = targetDate.difference(now);
|
final difference = targetDate.difference(now);
|
||||||
@ -218,389 +214,82 @@ class _DrawPageState extends State<DrawPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSimpleDrawCard(DrawEvent draw) {
|
Widget _buildSimpleDrawCard(DrawEvent draw) {
|
||||||
_isUserEntered(draw.id);
|
|
||||||
final timeRemaining = _getTimeRemaining(draw.drawDate);
|
final timeRemaining = _getTimeRemaining(draw.drawDate);
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => context.router.push(DrawDetailRoute(drawEvent: draw)),
|
onTap: () => context.router.push(DrawDetailRoute(drawEvent: draw)),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(bottom: 16),
|
margin: EdgeInsets.only(bottom: 8),
|
||||||
decoration: BoxDecoration(
|
padding: EdgeInsets.all(12),
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.black.withOpacity(0.08),
|
|
||||||
blurRadius: 12,
|
|
||||||
offset: Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// Header with gradient background
|
|
||||||
Container(
|
|
||||||
height: 160,
|
|
||||||
width: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [draw.primaryColor, draw.primaryColor.withOpacity(0.8)],
|
||||||
draw.primaryColor,
|
|
||||||
draw.primaryColor.withOpacity(0.8),
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
|
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
// Background pattern (coins and gold bar)
|
|
||||||
Positioned(
|
|
||||||
right: 20,
|
|
||||||
top: 20,
|
|
||||||
child: Opacity(
|
|
||||||
opacity: 0.3,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
_buildCoin(),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
_buildCoin(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
_buildGoldBar(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Content
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
if (draw.isActive)
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 8,
|
|
||||||
vertical: 4,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.success,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
"AKTIF",
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
"MAKAN\nDAPAT",
|
|
||||||
style: AppStyle.h5.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
height: 0.9,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
draw.description,
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Card content
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// Prize info
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(draw.icon, style: AppStyle.h5),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
draw.prize,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Stats row
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"-",
|
|
||||||
style: AppStyle.h5.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"Peserta",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"${draw.hadiah}",
|
|
||||||
style: AppStyle.h5.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"Hadiah",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"0",
|
|
||||||
style: AppStyle.h5.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"Voucher Anda",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
// Timer
|
|
||||||
if (draw.isActive)
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.access_time,
|
|
||||||
color: AppColor.error,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
"Berakhir dalam:",
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Spacer(),
|
|
||||||
Text(
|
|
||||||
timeRemaining,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 12),
|
|
||||||
|
|
||||||
// Spending requirement
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => _showSpendingInfo(draw),
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
vertical: 12,
|
|
||||||
horizontal: 16,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.backgroundLight,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
border: Border.all(
|
boxShadow: [
|
||||||
color: AppColor.borderLight,
|
BoxShadow(
|
||||||
width: 1,
|
color: AppColor.black.withOpacity(0.08),
|
||||||
|
blurRadius: 8,
|
||||||
|
offset: Offset(0, 2),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Column(
|
||||||
"Belanja min. Rp ${_formatCurrency(draw.minSpending)} untuk berpartisipasi",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.chevron_right,
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCoin() {
|
|
||||||
return Container(
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.warning,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(color: Colors.yellow, width: 1),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
"₹",
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: Colors.orange[800],
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildGoldBar() {
|
|
||||||
return Container(
|
|
||||||
width: 30,
|
|
||||||
height: 15,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.warning,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
border: Border.all(color: Colors.yellow, width: 1),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
"GOLD",
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.orange[800],
|
|
||||||
fontSize: 6,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatCurrency(int amount) {
|
|
||||||
return amount.toString().replaceAllMapped(
|
|
||||||
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
|
|
||||||
(Match m) => '${m[1]}.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showSpendingInfo(DrawEvent draw) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => AlertDialog(
|
|
||||||
backgroundColor: AppColor.surface,
|
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
|
||||||
title: Text(
|
|
||||||
"Syarat Partisipasi",
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
content: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
// Name
|
||||||
Text(
|
Text(
|
||||||
"Untuk mengikuti undian ${draw.name}, Anda perlu:",
|
draw.name,
|
||||||
style: AppStyle.md.copyWith(color: AppColor.textPrimary),
|
style: AppStyle.md.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: AppColor.textWhite,
|
||||||
),
|
),
|
||||||
SizedBox(height: 12),
|
),
|
||||||
Row(
|
SizedBox(height: 4),
|
||||||
|
// Description
|
||||||
|
Text(
|
||||||
|
draw.description,
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.textWhite.withOpacity(0.9),
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
SizedBox(height: 6),
|
||||||
|
// Date
|
||||||
|
Text(
|
||||||
|
draw.isActive ? "Berakhir: $timeRemaining" : "Selesai",
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.textWhite.withOpacity(0.8),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Price
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.shopping_cart, color: draw.primaryColor, size: 20),
|
Text(draw.icon, style: AppStyle.lg),
|
||||||
SizedBox(width: 8),
|
SizedBox(height: 2),
|
||||||
Expanded(
|
Text(
|
||||||
child: Text(
|
draw.prize,
|
||||||
"Belanja minimum Rp ${_formatCurrency(draw.minSpending)}",
|
style: AppStyle.sm.copyWith(
|
||||||
style: AppStyle.md.copyWith(
|
fontWeight: FontWeight.bold,
|
||||||
fontWeight: FontWeight.w600,
|
color: AppColor.textWhite,
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.schedule, color: draw.primaryColor, size: 20),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
"Sebelum ${_formatDateTime(draw.drawDate)}",
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
child: Text(
|
|
||||||
"Mengerti",
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.primary,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _formatDateTime(DateTime date) {
|
|
||||||
return "${date.day}/${date.month}/${date.year} ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
_buildHeaderSection(),
|
_buildHeaderSection(),
|
||||||
const SizedBox(height: 70),
|
const SizedBox(height: 70),
|
||||||
HomeFeatureSection(),
|
HomeFeatureSection(),
|
||||||
HomeLotteryBanner(),
|
HomeLotteryBanner(onTap: () => context.router.push(DrawRoute())),
|
||||||
HomePopularMerchantSection(),
|
HomePopularMerchantSection(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -8,7 +8,7 @@ class HomeLotteryBanner extends StatefulWidget {
|
|||||||
this.title = "🎰 UNDIAN BERHADIAH",
|
this.title = "🎰 UNDIAN BERHADIAH",
|
||||||
this.subtitle = "Kumpulkan voucher untuk menang hadiah menarik!",
|
this.subtitle = "Kumpulkan voucher untuk menang hadiah menarik!",
|
||||||
this.showAnimation = true,
|
this.showAnimation = true,
|
||||||
this.actionText = "MAIN SEKARANG",
|
this.actionText = "IKUTI SEKARANG",
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
|||||||
@ -144,7 +144,6 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColor.background,
|
|
||||||
appBar: _buildAppBar(),
|
appBar: _buildAppBar(),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -161,6 +160,7 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
|
|||||||
return AppBar(
|
return AppBar(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
backgroundColor: AppColor.white,
|
backgroundColor: AppColor.white,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
title: Text('Pesanan'),
|
title: Text('Pesanan'),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
|
|||||||
@ -15,64 +15,32 @@ class OrderCard extends StatelessWidget {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => context.router.push(OrderDetailRoute(order: order)),
|
onTap: () => context.router.push(OrderDetailRoute(order: order)),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.only(bottom: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColor.white,
|
border: Border(
|
||||||
borderRadius: BorderRadius.circular(16),
|
bottom: BorderSide(
|
||||||
boxShadow: [
|
color: AppColor.border.withOpacity(0.3),
|
||||||
BoxShadow(
|
width: 1,
|
||||||
color: AppColor.black.withOpacity(0.06),
|
|
||||||
blurRadius: 16,
|
|
||||||
offset: const Offset(0, 3),
|
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.all(18),
|
child: Row(
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
_buildHeader(),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
_buildContent(),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
_buildFooter(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildHeader() {
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
|
// Left side - Order info
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
// Order ID
|
||||||
children: [
|
Text(
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8,
|
|
||||||
vertical: 4,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.primary.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
order.id,
|
order.id,
|
||||||
style: AppStyle.sm.copyWith(
|
style: AppStyle.md.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: AppColor.primary,
|
color: AppColor.textPrimary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 4),
|
||||||
],
|
// Order Date
|
||||||
),
|
|
||||||
const SizedBox(height: 6),
|
|
||||||
Text(
|
Text(
|
||||||
DateFormat('dd MMM yyyy • HH:mm').format(order.orderDate),
|
DateFormat('dd MMM yyyy • HH:mm').format(order.orderDate),
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||||
@ -80,206 +48,47 @@ class OrderCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_buildStatusChip(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildStatusChip() {
|
// Right side - Status and Total
|
||||||
return Container(
|
Column(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
// Status
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _getStatusColor().withOpacity(0.1),
|
color: _getStatusColor().withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(color: _getStatusColor().withOpacity(0.2), width: 1),
|
border: Border.all(
|
||||||
|
color: _getStatusColor().withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
),
|
),
|
||||||
child: Row(
|
),
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Text(
|
||||||
children: [
|
|
||||||
Icon(_getStatusIcon(), size: 12, color: _getStatusColor()),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Text(
|
|
||||||
_getStatusText(),
|
_getStatusText(),
|
||||||
style: AppStyle.sm.copyWith(
|
style: AppStyle.xs.copyWith(
|
||||||
color: _getStatusColor(),
|
color: _getStatusColor(),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildContent() {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(14),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.background,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.restaurant_menu_outlined,
|
|
||||||
size: 16,
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Text(
|
|
||||||
'${order.items.length} item pesanan',
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
...order.items
|
|
||||||
.take(3)
|
|
||||||
.map(
|
|
||||||
(item) => Container(
|
|
||||||
margin: const EdgeInsets.only(bottom: 6),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.primary.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
'${item.quantity}',
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
item.name,
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'Rp ${_formatCurrency(item.price * item.quantity)}',
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (order.items.length > 3) ...[
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.only(top: 4),
|
|
||||||
child: Text(
|
|
||||||
'+${order.items.length - 3} item lainnya',
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
fontStyle: FontStyle.italic,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
if (order.notes != null) ...[
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(10),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.warning.withOpacity(0.05),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(color: AppColor.warning.withOpacity(0.2)),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.sticky_note_2_outlined,
|
|
||||||
size: 14,
|
|
||||||
color: AppColor.warning,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
order.notes!,
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
height: 1.3,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildFooter() {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: 1,
|
|
||||||
width: double.infinity,
|
|
||||||
color: AppColor.border.withOpacity(0.3),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
order.address != null
|
|
||||||
? Icons.location_on_outlined
|
|
||||||
: Icons.store_outlined,
|
|
||||||
size: 16,
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
order.address ?? 'Ambil di tempat',
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Total',
|
|
||||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
// Total Amount
|
||||||
Text(
|
Text(
|
||||||
'Rp ${_formatCurrency(order.totalAmount)}',
|
'Rp ${_formatCurrency(order.totalAmount)}',
|
||||||
style: AppStyle.lg.copyWith(
|
style: AppStyle.md.copyWith(
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: AppColor.primary,
|
color: AppColor.textPrimary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,19 +118,6 @@ class OrderCard extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IconData _getStatusIcon() {
|
|
||||||
switch (order.status) {
|
|
||||||
case OrderStatus.pending:
|
|
||||||
return Icons.schedule;
|
|
||||||
case OrderStatus.processing:
|
|
||||||
return Icons.hourglass_empty;
|
|
||||||
case OrderStatus.completed:
|
|
||||||
return Icons.check_circle;
|
|
||||||
case OrderStatus.cancelled:
|
|
||||||
return Icons.cancel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatCurrency(double amount) {
|
String _formatCurrency(double amount) {
|
||||||
final formatter = NumberFormat('#,###');
|
final formatter = NumberFormat('#,###');
|
||||||
return formatter.format(amount);
|
return formatter.format(amount);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
import '../../../../../common/theme/theme.dart';
|
import '../../../../../common/theme/theme.dart';
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ class ProfilePage extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColor.background,
|
backgroundColor: AppColor.background,
|
||||||
appBar: AppBar(title: Text('Akun')),
|
appBar: AppBar(title: Text('Profil'), automaticallyImplyLeading: false),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -165,61 +164,6 @@ class ProfilePage extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
|
||||||
// Share the Sip Card
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.backgroundLight,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.borderLight),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
// Share Icon
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.success.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
Icons.share,
|
|
||||||
color: AppColor.success,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
// Share Info
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Share the Sip',
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'Bagikan kode referral, dapatkan hadiah',
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios,
|
|
||||||
color: AppColor.textSecondary,
|
|
||||||
size: 14,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -280,52 +224,6 @@ class ProfilePage extends StatelessWidget {
|
|||||||
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// Social Media Section
|
|
||||||
Container(
|
|
||||||
color: AppColor.white,
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Media Sosial',
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
_buildSocialButton(
|
|
||||||
icon: Icons.camera_alt,
|
|
||||||
color: Colors.purple,
|
|
||||||
onTap: () => _launchSocialMedia('instagram'),
|
|
||||||
),
|
|
||||||
_buildSocialButton(
|
|
||||||
icon: Icons.facebook,
|
|
||||||
color: Colors.blue,
|
|
||||||
onTap: () => _launchSocialMedia('facebook'),
|
|
||||||
),
|
|
||||||
_buildSocialButton(
|
|
||||||
icon: Icons.play_arrow,
|
|
||||||
color: Colors.red,
|
|
||||||
onTap: () => _launchSocialMedia('youtube'),
|
|
||||||
),
|
|
||||||
_buildSocialButton(
|
|
||||||
icon: Icons.close,
|
|
||||||
color: Colors.black,
|
|
||||||
onTap: () => _launchSocialMedia('twitter'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
|
|
||||||
// Customer Service Section
|
// Customer Service Section
|
||||||
Container(
|
Container(
|
||||||
color: AppColor.white,
|
color: AppColor.white,
|
||||||
@ -467,49 +365,12 @@ class ProfilePage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSocialButton({
|
|
||||||
required IconData icon,
|
|
||||||
required Color color,
|
|
||||||
required VoidCallback onTap,
|
|
||||||
}) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Container(
|
|
||||||
width: 48,
|
|
||||||
height: 48,
|
|
||||||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
|
||||||
child: Icon(icon, color: AppColor.white, size: 24),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _launchSocialMedia(String platform) async {
|
|
||||||
String url = '';
|
|
||||||
switch (platform) {
|
|
||||||
case 'instagram':
|
|
||||||
url = 'https://instagram.com/';
|
|
||||||
break;
|
|
||||||
case 'facebook':
|
|
||||||
url = 'https://facebook.com/';
|
|
||||||
break;
|
|
||||||
case 'youtube':
|
|
||||||
url = 'https://youtube.com/';
|
|
||||||
break;
|
|
||||||
case 'twitter':
|
|
||||||
url = 'https://twitter.com/';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await canLaunch(url)) {
|
|
||||||
await launch(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showLogoutDialog(BuildContext context) {
|
void _showLogoutDialog(BuildContext context) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
|
backgroundColor: AppColor.white,
|
||||||
title: Text(
|
title: Text(
|
||||||
'Logout',
|
'Logout',
|
||||||
style: AppStyle.lg.copyWith(fontWeight: FontWeight.w600),
|
style: AppStyle.lg.copyWith(fontWeight: FontWeight.w600),
|
||||||
|
|||||||
@ -19,11 +19,14 @@ class _MerchantPageState extends State<MerchantPage> {
|
|||||||
final TextEditingController _searchController = TextEditingController();
|
final TextEditingController _searchController = TextEditingController();
|
||||||
final List<MerchantModel> _allMerchants = _generateMockMerchants();
|
final List<MerchantModel> _allMerchants = _generateMockMerchants();
|
||||||
List<MerchantModel> _filteredMerchants = [];
|
List<MerchantModel> _filteredMerchants = [];
|
||||||
|
String? _selectedCategory;
|
||||||
|
late List<String> _categories;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_filteredMerchants = _allMerchants;
|
_filteredMerchants = _allMerchants;
|
||||||
|
_categories = _getAllCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -32,12 +35,29 @@ class _MerchantPageState extends State<MerchantPage> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _getAllCategories() {
|
||||||
|
final categories = _allMerchants
|
||||||
|
.map((merchant) => merchant.category)
|
||||||
|
.toSet()
|
||||||
|
.toList();
|
||||||
|
categories.sort();
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
void _filterMerchants(String query) {
|
void _filterMerchants(String query) {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (query.isEmpty) {
|
var merchants = _allMerchants;
|
||||||
_filteredMerchants = _allMerchants;
|
|
||||||
} else {
|
// Filter by category first
|
||||||
_filteredMerchants = _allMerchants
|
if (_selectedCategory != null) {
|
||||||
|
merchants = merchants
|
||||||
|
.where((merchant) => merchant.category == _selectedCategory)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then filter by search query
|
||||||
|
if (query.isNotEmpty) {
|
||||||
|
merchants = merchants
|
||||||
.where(
|
.where(
|
||||||
(merchant) =>
|
(merchant) =>
|
||||||
merchant.name.toLowerCase().contains(query.toLowerCase()) ||
|
merchant.name.toLowerCase().contains(query.toLowerCase()) ||
|
||||||
@ -45,26 +65,98 @@ class _MerchantPageState extends State<MerchantPage> {
|
|||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_filteredMerchants = merchants;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onCategorySelected(String? category) {
|
||||||
|
setState(() {
|
||||||
|
_selectedCategory = category;
|
||||||
|
});
|
||||||
|
_filterMerchants(_searchController.text);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColor.background,
|
backgroundColor: AppColor.background,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Merchants'),
|
title: const Text('Merchants'),
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: const Size.fromHeight(70),
|
preferredSize: const Size.fromHeight(
|
||||||
child: SearchTextField(
|
130,
|
||||||
|
), // Increased height for filter chips
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Search Field
|
||||||
|
SearchTextField(
|
||||||
hintText: 'Search merchants...',
|
hintText: 'Search merchants...',
|
||||||
prefixIcon: Icons.search,
|
prefixIcon: Icons.search,
|
||||||
controller: _searchController,
|
controller: _searchController,
|
||||||
|
// onChanged: _filterMerchants,
|
||||||
onClear: () {
|
onClear: () {
|
||||||
_searchController.clear();
|
_searchController.clear();
|
||||||
_filterMerchants('');
|
_filterMerchants('');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
// Category Filter Chips
|
||||||
|
// Category Filter Chips - Updated with AppColor and opacity 1
|
||||||
|
Container(
|
||||||
|
height: 40,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: ListView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
children: [
|
||||||
|
// "All" filter chip
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: FilterChip(
|
||||||
|
label: const Text('All'),
|
||||||
|
selected: _selectedCategory == null,
|
||||||
|
onSelected: (selected) {
|
||||||
|
_onCategorySelected(null);
|
||||||
|
},
|
||||||
|
selectedColor: AppColor.primary,
|
||||||
|
backgroundColor: AppColor.white,
|
||||||
|
checkmarkColor: AppColor.white,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: _selectedCategory == null
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.primary,
|
||||||
|
),
|
||||||
|
side: BorderSide(color: AppColor.primary, width: 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Category filter chips
|
||||||
|
..._categories.map(
|
||||||
|
(category) => Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: FilterChip(
|
||||||
|
label: Text(category),
|
||||||
|
selected: _selectedCategory == category,
|
||||||
|
onSelected: (selected) {
|
||||||
|
_onCategorySelected(selected ? category : null);
|
||||||
|
},
|
||||||
|
selectedColor: AppColor.primary,
|
||||||
|
backgroundColor: AppColor.white,
|
||||||
|
checkmarkColor: AppColor.white,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: _selectedCategory == category
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.primary,
|
||||||
|
),
|
||||||
|
side: BorderSide(color: AppColor.primary, width: 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: _filteredMerchants.isEmpty
|
body: _filteredMerchants.isEmpty
|
||||||
|
|||||||
@ -47,19 +47,7 @@ class _OrderDetailPageState extends State<OrderDetailPage> {
|
|||||||
|
|
||||||
PreferredSizeWidget _buildAppBar() {
|
PreferredSizeWidget _buildAppBar() {
|
||||||
return AppBar(
|
return AppBar(
|
||||||
elevation: 0,
|
title: Text('Detail Pesanan'),
|
||||||
backgroundColor: AppColor.white,
|
|
||||||
leading: IconButton(
|
|
||||||
onPressed: () => context.router.back(),
|
|
||||||
icon: const Icon(Icons.arrow_back, color: AppColor.textPrimary),
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
'Detail Pesanan',
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: _shareOrder,
|
onPressed: _shareOrder,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user