feat: update draw detail page
This commit is contained in:
parent
0d1e516686
commit
dc4fdf5fbf
@ -217,7 +217,7 @@ class _DrawPageState extends State<DrawPage> {
|
|||||||
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()),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(bottom: 8),
|
margin: EdgeInsets.only(bottom: 8),
|
||||||
padding: EdgeInsets.all(12),
|
padding: EdgeInsets.all(12),
|
||||||
|
|||||||
@ -1,905 +1,31 @@
|
|||||||
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 '../../../../../common/theme/theme.dart';
|
import '../../../../../common/theme/theme.dart';
|
||||||
import '../../draw_page.dart';
|
import '../../../../router/app_router.gr.dart';
|
||||||
|
import 'widgets/bottom_navbar.dart';
|
||||||
// Prize model
|
|
||||||
class Prize {
|
|
||||||
final String id;
|
|
||||||
final String name;
|
|
||||||
final String value;
|
|
||||||
final String icon;
|
|
||||||
final int quantity;
|
|
||||||
final String description;
|
|
||||||
|
|
||||||
Prize({
|
|
||||||
required this.id,
|
|
||||||
required this.name,
|
|
||||||
required this.value,
|
|
||||||
required this.icon,
|
|
||||||
required this.quantity,
|
|
||||||
required this.description,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Voucher model
|
|
||||||
class UserVoucher {
|
|
||||||
final String id;
|
|
||||||
final String drawId;
|
|
||||||
final String voucherNumber;
|
|
||||||
final DateTime createdDate;
|
|
||||||
final String status; // 'active', 'used', 'expired'
|
|
||||||
|
|
||||||
UserVoucher({
|
|
||||||
required this.id,
|
|
||||||
required this.drawId,
|
|
||||||
required this.voucherNumber,
|
|
||||||
required this.createdDate,
|
|
||||||
required this.status,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class DrawDetailPage extends StatefulWidget {
|
class DrawDetailPage extends StatelessWidget {
|
||||||
final DrawEvent drawEvent;
|
const DrawDetailPage({super.key});
|
||||||
|
|
||||||
const DrawDetailPage({super.key, required this.drawEvent});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<DrawDetailPage> createState() => _DrawDetailPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DrawDetailPageState extends State<DrawDetailPage>
|
|
||||||
with TickerProviderStateMixin {
|
|
||||||
late TabController _tabController;
|
|
||||||
|
|
||||||
// Sample data
|
|
||||||
final List<Prize> prizes = [
|
|
||||||
Prize(
|
|
||||||
id: "1",
|
|
||||||
name: "Emas 3 Gram",
|
|
||||||
value: "Rp 2.500.000",
|
|
||||||
icon: "👑",
|
|
||||||
quantity: 1,
|
|
||||||
description:
|
|
||||||
"Emas murni 24 karat seberat 3 gram dari toko emas terpercaya",
|
|
||||||
),
|
|
||||||
Prize(
|
|
||||||
id: "2",
|
|
||||||
name: "Emas 1 Gram",
|
|
||||||
value: "Rp 850.000",
|
|
||||||
icon: "🥇",
|
|
||||||
quantity: 1,
|
|
||||||
description:
|
|
||||||
"Emas murni 24 karat seberat 1 gram dari toko emas terpercaya",
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
final List<UserVoucher> userVouchers = [
|
|
||||||
UserVoucher(
|
|
||||||
id: "1",
|
|
||||||
drawId: "1",
|
|
||||||
voucherNumber: "ENK001234567",
|
|
||||||
createdDate: DateTime.now().subtract(Duration(hours: 2)),
|
|
||||||
status: 'active',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_tabController = TabController(length: 4, vsync: this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_tabController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
String _getTimeRemaining(DateTime targetDate) {
|
|
||||||
final now = DateTime.now();
|
|
||||||
final difference = targetDate.difference(now);
|
|
||||||
|
|
||||||
if (difference.isNegative) return "Sudah berakhir";
|
|
||||||
|
|
||||||
if (difference.inDays > 0) {
|
|
||||||
return "${difference.inDays} hari ${difference.inHours % 24} jam";
|
|
||||||
} else if (difference.inHours > 0) {
|
|
||||||
return "${difference.inHours} jam ${difference.inMinutes % 60} menit";
|
|
||||||
} else if (difference.inMinutes > 0) {
|
|
||||||
return "${difference.inMinutes} menit";
|
|
||||||
} else {
|
|
||||||
return "Berakhir sekarang!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatCurrency(int amount) {
|
|
||||||
return amount.toString().replaceAllMapped(
|
|
||||||
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
|
|
||||||
(Match m) => '${m[1]}.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return AutoTabsRouter.pageView(
|
||||||
backgroundColor: AppColor.background,
|
routes: [
|
||||||
body: CustomScrollView(
|
DrawTodayRoute(),
|
||||||
slivers: [
|
DrawMyNumberRoute(),
|
||||||
// App Bar with gradient
|
DrawWinnerRoute(),
|
||||||
SliverAppBar(
|
DrawInfoRoute(),
|
||||||
expandedHeight: 200,
|
|
||||||
pinned: true,
|
|
||||||
backgroundColor: widget.drawEvent.primaryColor,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: Icon(Icons.arrow_back, color: AppColor.textWhite),
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
),
|
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
|
||||||
background: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
widget.drawEvent.primaryColor,
|
|
||||||
widget.drawEvent.primaryColor.withOpacity(0.8),
|
|
||||||
],
|
],
|
||||||
begin: Alignment.topCenter,
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
end: Alignment.bottomCenter,
|
builder: (context, child, pageController) => Scaffold(
|
||||||
),
|
body: child,
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
// Background decoration
|
|
||||||
Positioned(
|
|
||||||
right: 20,
|
|
||||||
top: 60,
|
|
||||||
child: Opacity(
|
|
||||||
opacity: 0.2,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
_buildCoin(),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
_buildCoin(),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
_buildCoin(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 12),
|
|
||||||
_buildGoldBar(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Content
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(left: 20, right: 20, top: 100),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
if (widget.drawEvent.isActive)
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 12,
|
|
||||||
vertical: 6,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.success,
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
"UNDIAN AKTIF",
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
widget.drawEvent.name,
|
|
||||||
style: AppStyle.h3.copyWith(
|
|
||||||
color: AppColor.textWhite,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.drawEvent.description.split('\n').first,
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.textWhite.withOpacity(0.9),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Tab Bar
|
|
||||||
SliverPersistentHeader(
|
|
||||||
pinned: true,
|
|
||||||
delegate: _SliverTabBarDelegate(
|
|
||||||
TabBar(
|
|
||||||
controller: _tabController,
|
|
||||||
labelColor: AppColor.primary,
|
|
||||||
unselectedLabelColor: AppColor.textSecondary,
|
|
||||||
indicatorColor: AppColor.primary,
|
|
||||||
indicatorWeight: 3,
|
|
||||||
labelStyle: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
|
|
||||||
unselectedLabelStyle: AppStyle.md,
|
|
||||||
tabs: [
|
|
||||||
Tab(text: "Info"),
|
|
||||||
Tab(text: "Hadiah"),
|
|
||||||
Tab(text: "Voucher"),
|
|
||||||
Tab(text: "S&K"),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Tab Content
|
|
||||||
SliverFillRemaining(
|
|
||||||
child: TabBarView(
|
|
||||||
controller: _tabController,
|
|
||||||
children: [
|
|
||||||
_buildInfoTab(),
|
|
||||||
_buildPrizesTab(),
|
|
||||||
_buildVouchersTab(),
|
|
||||||
_buildTermsTab(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoTab() {
|
|
||||||
final timeRemaining = _getTimeRemaining(widget.drawEvent.drawDate);
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
_buildInfoCard(
|
|
||||||
title: "Informasi Undian",
|
|
||||||
children: [
|
|
||||||
_buildInfoRow("Nama Undian", widget.drawEvent.name),
|
|
||||||
_buildInfoRow("Deskripsi", widget.drawEvent.description),
|
|
||||||
_buildInfoRow(
|
|
||||||
"Total Hadiah",
|
|
||||||
"${widget.drawEvent.hadiah} hadiah",
|
|
||||||
),
|
|
||||||
_buildInfoRow("Nilai Hadiah", widget.drawEvent.prizeValue),
|
|
||||||
_buildInfoRow(
|
|
||||||
"Status",
|
|
||||||
widget.drawEvent.isActive ? "Aktif" : "Selesai",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
_buildInfoCard(
|
|
||||||
title: "Waktu Undian",
|
|
||||||
children: [
|
|
||||||
_buildInfoRow(
|
|
||||||
"Tanggal Pengundian",
|
|
||||||
_formatDateTime(widget.drawEvent.drawDate),
|
|
||||||
),
|
|
||||||
_buildInfoRow("Waktu Tersisa", timeRemaining),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
_buildInfoCard(
|
|
||||||
title: "Statistik",
|
|
||||||
children: [
|
|
||||||
_buildInfoRow(
|
|
||||||
"Total Peserta",
|
|
||||||
"${widget.drawEvent.totalParticipants} orang",
|
|
||||||
),
|
|
||||||
_buildInfoRow(
|
|
||||||
"Voucher Anda",
|
|
||||||
"${userVouchers.where((v) => v.drawId == widget.drawEvent.id).length}",
|
|
||||||
),
|
|
||||||
_buildInfoRow(
|
|
||||||
"Minimum Belanja",
|
|
||||||
"Rp ${_formatCurrency(widget.drawEvent.minSpending)}",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildPrizesTab() {
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Daftar Hadiah",
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
...prizes.map((prize) => _buildPrizeCard(prize)).toList(),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
_buildInfoCard(
|
|
||||||
title: "Ketentuan Hadiah",
|
|
||||||
children: [
|
|
||||||
_buildBulletPoint(
|
|
||||||
"Hadiah akan diumumkan setelah pengundian selesai",
|
|
||||||
),
|
|
||||||
_buildBulletPoint(
|
|
||||||
"Pemenang akan dihubungi melalui nomor telepon terdaftar",
|
|
||||||
),
|
|
||||||
_buildBulletPoint("Hadiah harus diambil dalam waktu 30 hari"),
|
|
||||||
_buildBulletPoint(
|
|
||||||
"Hadiah tidak dapat dipindahtangankan atau ditukar uang",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildVouchersTab() {
|
|
||||||
final drawVouchers = userVouchers
|
|
||||||
.where((v) => v.drawId == widget.drawEvent.id)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Voucher Anda",
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
"Total: ${drawVouchers.length} voucher",
|
|
||||||
style: AppStyle.md.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
if (drawVouchers.isEmpty)
|
|
||||||
_buildEmptyVoucherState()
|
|
||||||
else
|
|
||||||
...drawVouchers
|
|
||||||
.map((voucher) => _buildVoucherCard(voucher))
|
|
||||||
.toList(),
|
|
||||||
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
_buildInfoCard(
|
|
||||||
title: "Cara Mendapat Voucher",
|
|
||||||
children: [
|
|
||||||
_buildBulletPoint(
|
|
||||||
"Lakukan pembelian minimum Rp ${_formatCurrency(widget.drawEvent.minSpending)}",
|
|
||||||
),
|
|
||||||
_buildBulletPoint("Voucher otomatis akan masuk ke akun Anda"),
|
|
||||||
_buildBulletPoint(
|
|
||||||
"Semakin banyak voucher, semakin besar peluang menang",
|
|
||||||
),
|
|
||||||
_buildBulletPoint("Voucher berlaku hingga pengundian selesai"),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTermsTab() {
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Syarat dan Ketentuan",
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16),
|
|
||||||
|
|
||||||
_buildTermsSection(
|
|
||||||
title: "Syarat Partisipasi",
|
|
||||||
terms: [
|
|
||||||
"Pengguna harus terdaftar sebagai member Enaklo",
|
|
||||||
"Melakukan pembelian minimum Rp ${_formatCurrency(widget.drawEvent.minSpending)}",
|
|
||||||
"Pembelian harus dilakukan sebelum waktu pengundian",
|
|
||||||
"Satu transaksi pembelian = satu voucher undian",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
_buildTermsSection(
|
|
||||||
title: "Ketentuan Pengundian",
|
|
||||||
terms: [
|
|
||||||
"Pengundian dilakukan secara transparan dan fair",
|
|
||||||
"Pemenang ditentukan secara acak oleh sistem",
|
|
||||||
"Keputusan pengundian bersifat final dan tidak dapat diganggu gugat",
|
|
||||||
"Pengumuman pemenang akan dilakukan maksimal 3 hari setelah pengundian",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
_buildTermsSection(
|
|
||||||
title: "Ketentuan Hadiah",
|
|
||||||
terms: [
|
|
||||||
"Hadiah harus diambil dalam waktu 30 hari setelah pengumuman",
|
|
||||||
"Hadiah yang tidak diambil dalam batas waktu dianggap hangus",
|
|
||||||
"Hadiah tidak dapat ditukar dengan uang tunai",
|
|
||||||
"Pajak hadiah (jika ada) menjadi tanggung jawab pemenang",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
_buildTermsSection(
|
|
||||||
title: "Ketentuan Lainnya",
|
|
||||||
terms: [
|
|
||||||
"Enaklo berhak membatalkan undian jika terjadi kecurangan",
|
|
||||||
"Peserta bertanggung jawab atas kebenaran data yang diberikan",
|
|
||||||
"Enaklo tidak bertanggung jawab atas kerugian akibat kesalahan peserta",
|
|
||||||
"Syarat dan ketentuan dapat berubah sewaktu-waktu tanpa pemberitahuan",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoCard({
|
|
||||||
required String title,
|
|
||||||
required List<Widget> children,
|
|
||||||
}) {
|
|
||||||
return Container(
|
|
||||||
width: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.black.withOpacity(0.05),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 12),
|
|
||||||
...children,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoRow(String label, String value) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 120,
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
": ",
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
value,
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildPrizeCard(Prize prize) {
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(bottom: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.borderLight),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.black.withOpacity(0.05),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: widget.drawEvent.primaryColor.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(30),
|
|
||||||
),
|
|
||||||
child: Center(child: Text(prize.icon, style: AppStyle.h4)),
|
|
||||||
),
|
|
||||||
SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
prize.name,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
prize.value,
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
color: AppColor.primary,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
prize.description,
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.primary.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
"${prize.quantity}x",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: AppColor.primary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildVoucherCard(UserVoucher voucher) {
|
|
||||||
Color statusColor;
|
|
||||||
String statusText;
|
|
||||||
|
|
||||||
switch (voucher.status) {
|
|
||||||
case 'active':
|
|
||||||
statusColor = AppColor.success;
|
|
||||||
statusText = "Aktif";
|
|
||||||
break;
|
|
||||||
case 'used':
|
|
||||||
statusColor = AppColor.textSecondary;
|
|
||||||
statusText = "Terpakai";
|
|
||||||
break;
|
|
||||||
case 'expired':
|
|
||||||
statusColor = AppColor.error;
|
|
||||||
statusText = "Kadaluarsa";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
statusColor = AppColor.textSecondary;
|
|
||||||
statusText = "Tidak Diketahui";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(bottom: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(
|
|
||||||
color: voucher.status == 'active'
|
|
||||||
? AppColor.primary.withOpacity(0.3)
|
|
||||||
: AppColor.borderLight,
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.black.withOpacity(0.05),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Voucher Undian",
|
|
||||||
style: AppStyle.md.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: statusColor.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
statusText,
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: statusColor,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.backgroundLight,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(color: AppColor.borderLight),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
voucher.voucherNumber,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
letterSpacing: 1.2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
"Diperoleh: ${_formatDateTime(voucher.createdDate)}",
|
|
||||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildEmptyVoucherState() {
|
|
||||||
return Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: EdgeInsets.all(32),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: AppColor.borderLight),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.receipt_outlined, size: 64, color: AppColor.textLight),
|
|
||||||
SizedBox(height: 16),
|
|
||||||
Text(
|
|
||||||
"Belum Ada Voucher",
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
"Lakukan pembelian untuk mendapatkan voucher undian",
|
|
||||||
style: AppStyle.md.copyWith(color: AppColor.textSecondary),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
SizedBox(height: 16),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
// Navigate to shop or show purchase dialog
|
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: AppColor.primary,
|
backgroundColor: AppColor.primary,
|
||||||
foregroundColor: AppColor.textWhite,
|
bottomNavigationBar: DrawDetailBottomNavbar(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
tabsRouter: AutoTabsRouter.of(context),
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
"Belanja Sekarang",
|
|
||||||
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTermsSection({
|
|
||||||
required String title,
|
|
||||||
required List<String> terms,
|
|
||||||
}) {
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(bottom: 24),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.surface,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.black.withOpacity(0.05),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: AppStyle.lg.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColor.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 12),
|
|
||||||
...terms.map((term) => _buildBulletPoint(term)).toList(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBulletPoint(String text) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 6),
|
|
||||||
width: 4,
|
|
||||||
height: 4,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.primary,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
style: AppStyle.md.copyWith(color: AppColor.textPrimary),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCoin() {
|
|
||||||
return Container(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.warning,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(color: Colors.yellow, width: 1),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
"₹",
|
|
||||||
style: AppStyle.sm.copyWith(
|
|
||||||
color: Colors.orange[800],
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildGoldBar() {
|
|
||||||
return Container(
|
|
||||||
width: 40,
|
|
||||||
height: 20,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColor.warning,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
border: Border.all(color: Colors.yellow, width: 1),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
"GOLD",
|
|
||||||
style: AppStyle.xs.copyWith(
|
|
||||||
color: Colors.orange[800],
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatDateTime(DateTime date) {
|
|
||||||
return "${date.day}/${date.month}/${date.year} ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom SliverTabBarDelegate
|
|
||||||
class _SliverTabBarDelegate extends SliverPersistentHeaderDelegate {
|
|
||||||
final TabBar _tabBar;
|
|
||||||
|
|
||||||
_SliverTabBarDelegate(this._tabBar);
|
|
||||||
|
|
||||||
@override
|
|
||||||
double get minExtent => _tabBar.preferredSize.height;
|
|
||||||
@override
|
|
||||||
double get maxExtent => _tabBar.preferredSize.height;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(
|
|
||||||
BuildContext context,
|
|
||||||
double shrinkOffset,
|
|
||||||
bool overlapsContent,
|
|
||||||
) {
|
|
||||||
return Container(color: AppColor.surface, child: _tabBar);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldRebuild(_SliverTabBarDelegate oldDelegate) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,685 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../../../../common/theme/theme.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class DrawInfoPage extends StatefulWidget {
|
||||||
|
const DrawInfoPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DrawInfoPage> createState() => _DrawInfoPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DrawInfoPageState extends State<DrawInfoPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
bool showHadiah = true;
|
||||||
|
|
||||||
|
late AnimationController _fadeController;
|
||||||
|
late AnimationController _slideController;
|
||||||
|
late AnimationController _scaleController;
|
||||||
|
late AnimationController _tabController;
|
||||||
|
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
late Animation<Offset> _slideAnimation;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_fadeController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 800),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_tabController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideAnimation = Tween<Offset>(begin: Offset(0, 0.3), end: Offset.zero)
|
||||||
|
.animate(
|
||||||
|
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_startAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startAnimations() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
_fadeController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
_slideController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 300));
|
||||||
|
_scaleController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_fadeController.dispose();
|
||||||
|
_slideController.dispose();
|
||||||
|
_scaleController.dispose();
|
||||||
|
_tabController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTitle() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: _slideAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 3,
|
||||||
|
height: 28,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
'Hadiah & Info',
|
||||||
|
style: AppStyle.h3.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: -0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTabButtons() {
|
||||||
|
return ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() => showHadiah = true);
|
||||||
|
_tabController.forward();
|
||||||
|
},
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: showHadiah
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.white.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: showHadiah
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.white.withOpacity(0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: showHadiah
|
||||||
|
? [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.1),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 5),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.card_giftcard_rounded,
|
||||||
|
color: showHadiah
|
||||||
|
? AppColor.primary
|
||||||
|
: AppColor.white.withOpacity(0.8),
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
'Hadiah',
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: showHadiah
|
||||||
|
? AppColor.primary
|
||||||
|
: AppColor.white.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() => showHadiah = false);
|
||||||
|
_tabController.forward();
|
||||||
|
},
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: !showHadiah
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.white.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: !showHadiah
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.white.withOpacity(0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: !showHadiah
|
||||||
|
? [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.1),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 5),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.info_outline_rounded,
|
||||||
|
color: !showHadiah
|
||||||
|
? AppColor.primary
|
||||||
|
: AppColor.white.withOpacity(0.8),
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
'Info Undian',
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: !showHadiah
|
||||||
|
? AppColor.primary
|
||||||
|
: AppColor.white.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHadiahContent() {
|
||||||
|
return ListView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
_buildPrizeCard(
|
||||||
|
'Emas Batangan 3KG',
|
||||||
|
'Hadiah utama untuk pemenang harian',
|
||||||
|
Icons.stars_rounded,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
_buildPrizeCard(
|
||||||
|
'Motor Yamaha NMAX',
|
||||||
|
'Hadiah mingguan untuk 1 pemenang',
|
||||||
|
Icons.two_wheeler_rounded,
|
||||||
|
false,
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
_buildPrizeCard(
|
||||||
|
'Voucher Belanja 1 Juta',
|
||||||
|
'Hadiah bulanan untuk 5 pemenang',
|
||||||
|
Icons.card_giftcard_rounded,
|
||||||
|
false,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
_buildPrizeCard(
|
||||||
|
'Smartphone Samsung',
|
||||||
|
'Hadiah khusus acara tertentu',
|
||||||
|
Icons.smartphone_rounded,
|
||||||
|
false,
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
_buildContactButton(),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoContent() {
|
||||||
|
return ListView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
_buildInfoSection(
|
||||||
|
'Cara Bermain',
|
||||||
|
[
|
||||||
|
'Setiap hari kamu akan mendapat 1 nomor undian otomatis',
|
||||||
|
'Nomor undian global diumumkan setiap hari jam 8 malam',
|
||||||
|
'Jika nomormu sama dengan nomor global, kamu menang!',
|
||||||
|
'Pemenang akan dihubungi melalui kontak yang terdaftar',
|
||||||
|
],
|
||||||
|
Icons.play_circle_outline_rounded,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
_buildInfoSection(
|
||||||
|
'Syarat & Ketentuan',
|
||||||
|
[
|
||||||
|
'Peserta minimal berusia 18 tahun',
|
||||||
|
'Satu akun per nomor telepon',
|
||||||
|
'Hadiah wajib diambil dalam 30 hari',
|
||||||
|
'Keputusan panitia tidak dapat diganggu gugat',
|
||||||
|
],
|
||||||
|
Icons.gavel_rounded,
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
_buildInfoSection(
|
||||||
|
'FAQ',
|
||||||
|
[
|
||||||
|
'Q: Apakah gratis? A: Ya, sepenuhnya gratis',
|
||||||
|
'Q: Berapa lama menunggu hasil? A: Maksimal 1 jam setelah pengumuman',
|
||||||
|
'Q: Bisa ganti nomor? A: Tidak, nomor otomatis dari sistem',
|
||||||
|
'Q: Pajak hadiah? A: Ditanggung penyelenggara',
|
||||||
|
],
|
||||||
|
Icons.help_outline_rounded,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
_buildContactButton(),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPrizeCard(
|
||||||
|
String title,
|
||||||
|
String description,
|
||||||
|
IconData icon,
|
||||||
|
bool isGold,
|
||||||
|
int index,
|
||||||
|
) {
|
||||||
|
return TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 800 + (index * 200)),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.translate(
|
||||||
|
offset: Offset(0, 30 * (1 - value)),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(bottom: 16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isGold
|
||||||
|
? AppColor.white
|
||||||
|
: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: isGold
|
||||||
|
? AppColor.warning.withOpacity(0.3)
|
||||||
|
: AppColor.white.withOpacity(0.2),
|
||||||
|
width: isGold ? 2 : 1,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: isGold
|
||||||
|
? AppColor.warning.withOpacity(0.3)
|
||||||
|
: AppColor.black.withOpacity(0.05),
|
||||||
|
blurRadius: isGold ? 20 : 10,
|
||||||
|
offset: Offset(0, isGold ? 8 : 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: isGold
|
||||||
|
? LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.warning,
|
||||||
|
AppColor.warning.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
)
|
||||||
|
: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: isGold
|
||||||
|
? AppColor.warning.withOpacity(0.3)
|
||||||
|
: AppColor.primary.withOpacity(0.3),
|
||||||
|
blurRadius: 12,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Icon(icon, color: AppColor.white, size: 24),
|
||||||
|
),
|
||||||
|
SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: isGold ? AppColor.primary : AppColor.white,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
description,
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: isGold
|
||||||
|
? AppColor.textSecondary
|
||||||
|
: AppColor.white.withOpacity(0.8),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (isGold)
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'TOP',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoSection(
|
||||||
|
String title,
|
||||||
|
List<String> items,
|
||||||
|
IconData icon,
|
||||||
|
int index,
|
||||||
|
) {
|
||||||
|
return TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 800 + (index * 200)),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.translate(
|
||||||
|
offset: Offset(0, 30 * (1 - value)),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(bottom: 16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.05),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Icon(icon, color: AppColor.white, size: 18),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
...items
|
||||||
|
.map(
|
||||||
|
(item) => Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 8),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 4,
|
||||||
|
height: 4,
|
||||||
|
margin: EdgeInsets.only(top: 8, right: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.warning,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
item,
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildContactButton() {
|
||||||
|
return TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
curve: Curves.elasticOut,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: value,
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Menghubungi layanan pelanggan...',
|
||||||
|
style: AppStyle.sm.copyWith(color: AppColor.white),
|
||||||
|
),
|
||||||
|
backgroundColor: AppColor.primary,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.support_agent_rounded,
|
||||||
|
color: AppColor.white,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Hubungi Layanan Pelanggan',
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Title
|
||||||
|
_buildTitle(),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Tab Buttons
|
||||||
|
_buildTabButtons(),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Content
|
||||||
|
Expanded(
|
||||||
|
child: AnimatedSwitcher(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
transitionBuilder:
|
||||||
|
(Widget child, Animation<double> animation) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: Offset(0.0, 0.1),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: showHadiah
|
||||||
|
? _buildHadiahContent()
|
||||||
|
: _buildInfoContent(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,478 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../../../../common/theme/theme.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class DrawMyNumberPage extends StatefulWidget {
|
||||||
|
const DrawMyNumberPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DrawMyNumberPage> createState() => _DrawMyNumberPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DrawMyNumberPageState extends State<DrawMyNumberPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late AnimationController _fadeController;
|
||||||
|
late AnimationController _slideController;
|
||||||
|
late AnimationController _scaleController;
|
||||||
|
late AnimationController _pulseController;
|
||||||
|
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
late Animation<Offset> _slideAnimation;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
late Animation<double> _pulseAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_fadeController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 800),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 2500),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideAnimation = Tween<Offset>(begin: Offset(0, 0.3), end: Offset.zero)
|
||||||
|
.animate(
|
||||||
|
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseAnimation = Tween<double>(begin: 1.0, end: 1.03).animate(
|
||||||
|
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_startAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startAnimations() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
_fadeController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
_slideController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 300));
|
||||||
|
_scaleController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 800));
|
||||||
|
_pulseController.repeat(reverse: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_fadeController.dispose();
|
||||||
|
_slideController.dispose();
|
||||||
|
_scaleController.dispose();
|
||||||
|
_pulseController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTitle() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: _slideAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 3,
|
||||||
|
height: 28,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
'Nomorku',
|
||||||
|
style: AppStyle.h3.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: -0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildMyNumberCard() {
|
||||||
|
return ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.08),
|
||||||
|
blurRadius: 30,
|
||||||
|
spreadRadius: 0,
|
||||||
|
offset: Offset(0, 15),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(24),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Label
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.primary.withOpacity(0.08),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'NOMOR UNDIANMU HARI INI',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Animated Number
|
||||||
|
AnimatedBuilder(
|
||||||
|
animation: _pulseAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: _pulseAnimation.value,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 16,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.primary.withOpacity(0.05),
|
||||||
|
AppColor.primary.withOpacity(0.02),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.primary.withOpacity(0.1),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'123123',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontSize: 42,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
letterSpacing: 12,
|
||||||
|
height: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Status Badge
|
||||||
|
TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
curve: Curves.elasticOut,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: value,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.primary.withOpacity(0.3),
|
||||||
|
blurRadius: 12,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Menunggu Hasil',
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildShareButton() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(begin: Offset(0, 0.5), end: Offset.zero).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _slideController,
|
||||||
|
curve: Interval(0.3, 1.0, curve: Curves.easeOutCubic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Membagikan nomormu: 123123',
|
||||||
|
style: AppStyle.sm.copyWith(color: AppColor.white),
|
||||||
|
),
|
||||||
|
backgroundColor: AppColor.primary,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.share_rounded, color: AppColor.white, size: 20),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Bagikan Nomorku',
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHistorySection() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(begin: Offset(0, 0.8), end: Offset.zero).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _slideController,
|
||||||
|
curve: Interval(0.5, 1.0, curve: Curves.easeOutCubic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Riwayat Nomorku',
|
||||||
|
style: AppStyle.lg.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 12),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHistoryCard(
|
||||||
|
String number,
|
||||||
|
String date,
|
||||||
|
String result,
|
||||||
|
int index,
|
||||||
|
) {
|
||||||
|
return TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 800 + (index * 200)),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.translate(
|
||||||
|
offset: Offset(0, 30 * (1 - value)),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 6),
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.15),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.05),
|
||||||
|
blurRadius: 10,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// Number and Date
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
number,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
date,
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.7),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Result Badge
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.error.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.error.withOpacity(0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
result,
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.error.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: ListView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Title
|
||||||
|
_buildTitle(),
|
||||||
|
|
||||||
|
SizedBox(height: 24),
|
||||||
|
|
||||||
|
// My Number Card
|
||||||
|
_buildMyNumberCard(),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Share Button
|
||||||
|
_buildShareButton(),
|
||||||
|
|
||||||
|
SizedBox(height: 24),
|
||||||
|
|
||||||
|
// History Section Title
|
||||||
|
_buildHistorySection(),
|
||||||
|
|
||||||
|
// History Cards
|
||||||
|
_buildHistoryCard('138472', 'Kemarin', 'Kalah 😔', 0),
|
||||||
|
_buildHistoryCard('928374', '2 hari lalu', 'Kalah 😔', 1),
|
||||||
|
_buildHistoryCard('475829', '3 hari lalu', 'Kalah 😔', 2),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,452 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../../../../common/theme/theme.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class DrawTodayPage extends StatefulWidget {
|
||||||
|
const DrawTodayPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DrawTodayPage> createState() => _DrawTodayPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DrawTodayPageState extends State<DrawTodayPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late AnimationController _fadeController;
|
||||||
|
late AnimationController _slideController;
|
||||||
|
late AnimationController _scaleController;
|
||||||
|
late AnimationController _pulseController;
|
||||||
|
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
late Animation<Offset> _slideAnimation;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
late Animation<double> _pulseAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_fadeController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 800),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 2000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideAnimation = Tween<Offset>(begin: Offset(0, 0.3), end: Offset.zero)
|
||||||
|
.animate(
|
||||||
|
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseAnimation = Tween<double>(begin: 1.0, end: 1.02).animate(
|
||||||
|
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_startAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startAnimations() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
_fadeController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
_slideController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 300));
|
||||||
|
_scaleController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 800));
|
||||||
|
_pulseController.repeat(reverse: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_fadeController.dispose();
|
||||||
|
_slideController.dispose();
|
||||||
|
_scaleController.dispose();
|
||||||
|
_pulseController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTitle() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: _slideAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 3,
|
||||||
|
height: 28,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
'Undian Hari Ini',
|
||||||
|
style: AppStyle.h3.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: -0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLotteryCard() {
|
||||||
|
return ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.08),
|
||||||
|
blurRadius: 30,
|
||||||
|
spreadRadius: 0,
|
||||||
|
offset: Offset(0, 15),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(24),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Label
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.primary.withOpacity(0.08),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'NOMOR UNDIAN GLOBAL',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Animated Number
|
||||||
|
AnimatedBuilder(
|
||||||
|
animation: _pulseAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: _pulseAnimation.value,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 16,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.primary.withOpacity(0.05),
|
||||||
|
AppColor.primary.withOpacity(0.02),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.primary.withOpacity(0.1),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'849302',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontSize: 42,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
letterSpacing: 12,
|
||||||
|
height: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPrizeCard() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(begin: Offset(0, 0.5), end: Offset.zero).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _slideController,
|
||||||
|
curve: Interval(0.3, 1.0, curve: Curves.easeOutCubic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(color: AppColor.white.withOpacity(0.2), width: 1),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.05),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Animated Icon
|
||||||
|
TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 1500),
|
||||||
|
curve: Curves.elasticOut,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: value,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.warning,
|
||||||
|
AppColor.warning.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.warning.withOpacity(0.3),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 6),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.stars_rounded,
|
||||||
|
color: AppColor.white,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'HADIAH UTAMA',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.7),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: 1.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 6),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'Jika nomor undianmu sama,\nkamu pemenang 3KG Emas!',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
height: 1.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoCards() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(begin: Offset(0, 0.8), end: Offset.zero).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _slideController,
|
||||||
|
curve: Interval(0.5, 1.0, curve: Curves.easeOutCubic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Next Draw Card
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.black.withOpacity(0.15),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.15),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.schedule_rounded,
|
||||||
|
color: AppColor.white,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(width: 12),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Undian Berikutnya',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.7),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
'Diumumkan jam 8 malam',
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 12),
|
||||||
|
|
||||||
|
// Check Ticket Card
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.all(14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.08),
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.confirmation_number_outlined,
|
||||||
|
color: AppColor.white.withOpacity(0.8),
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Cek tiket undianmu di menu Tiket Saya',
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: ListView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Title
|
||||||
|
_buildTitle(),
|
||||||
|
|
||||||
|
SizedBox(height: 24),
|
||||||
|
|
||||||
|
// Lottery Card
|
||||||
|
_buildLotteryCard(),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Prize Card
|
||||||
|
_buildPrizeCard(),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Info Cards
|
||||||
|
_buildInfoCards(),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,536 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'dart:math' show cos, sin;
|
||||||
|
|
||||||
|
import '../../../../../../common/theme/theme.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class DrawWinnerPage extends StatefulWidget {
|
||||||
|
const DrawWinnerPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DrawWinnerPage> createState() => _DrawWinnerPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DrawWinnerPageState extends State<DrawWinnerPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late AnimationController _fadeController;
|
||||||
|
late AnimationController _slideController;
|
||||||
|
late AnimationController _scaleController;
|
||||||
|
late AnimationController _pulseController;
|
||||||
|
late AnimationController _celebrationController;
|
||||||
|
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
late Animation<Offset> _slideAnimation;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
late Animation<double> _pulseAnimation;
|
||||||
|
late Animation<double> _celebrationAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_fadeController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1200),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 800),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 2000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_celebrationController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 3000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_slideAnimation = Tween<Offset>(begin: Offset(0, 0.3), end: Offset.zero)
|
||||||
|
.animate(
|
||||||
|
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_pulseAnimation = Tween<double>(begin: 1.0, end: 1.05).animate(
|
||||||
|
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_celebrationAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(parent: _celebrationController, curve: Curves.elasticOut),
|
||||||
|
);
|
||||||
|
|
||||||
|
_startAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startAnimations() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
_fadeController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
_slideController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 300));
|
||||||
|
_scaleController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 600));
|
||||||
|
_celebrationController.forward();
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 800));
|
||||||
|
_pulseController.repeat(reverse: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_fadeController.dispose();
|
||||||
|
_slideController.dispose();
|
||||||
|
_scaleController.dispose();
|
||||||
|
_pulseController.dispose();
|
||||||
|
_celebrationController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTitle() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: _slideAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 3,
|
||||||
|
height: 28,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
'Pemenang',
|
||||||
|
style: AppStyle.h3.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
letterSpacing: -0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTodayWinnerBanner() {
|
||||||
|
return ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white,
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.warning.withOpacity(0.3),
|
||||||
|
blurRadius: 30,
|
||||||
|
spreadRadius: 0,
|
||||||
|
offset: Offset(0, 15),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
// Celebration Particles Effect
|
||||||
|
Positioned.fill(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: _celebrationAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return CustomPaint(
|
||||||
|
painter: CelebrationPainter(_celebrationAnimation.value),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Main Content
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(24),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Trophy Icon with Animation
|
||||||
|
AnimatedBuilder(
|
||||||
|
animation: _celebrationAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: _celebrationAnimation.value,
|
||||||
|
child: Transform.rotate(
|
||||||
|
angle: _celebrationAnimation.value * 0.1,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.warning,
|
||||||
|
AppColor.warning.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.warning.withOpacity(0.4),
|
||||||
|
blurRadius: 20,
|
||||||
|
offset: Offset(0, 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.emoji_events_rounded,
|
||||||
|
color: AppColor.white,
|
||||||
|
size: 32,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Title with Emoji
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Pemenang Hari Ini',
|
||||||
|
style: AppStyle.lg.copyWith(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 1500),
|
||||||
|
curve: Curves.elasticOut,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: value,
|
||||||
|
child: Text('🎉', style: TextStyle(fontSize: 20)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Winning Number
|
||||||
|
AnimatedBuilder(
|
||||||
|
animation: _pulseAnimation,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Transform.scale(
|
||||||
|
scale: _pulseAnimation.value,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 16,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.primary.withOpacity(0.05),
|
||||||
|
AppColor.primary.withOpacity(0.02),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.primary.withOpacity(0.1),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'849302',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColor.primary,
|
||||||
|
fontSize: 36,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
letterSpacing: 8,
|
||||||
|
height: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Winner Name
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.primary.withOpacity(0.3),
|
||||||
|
blurRadius: 12,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Selamat untuk Andi***',
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHistorySection() {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(begin: Offset(0, 0.5), end: Offset.zero).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _slideController,
|
||||||
|
curve: Interval(0.3, 1.0, curve: Curves.easeOutCubic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Pemenang Kemarin',
|
||||||
|
style: AppStyle.lg.copyWith(
|
||||||
|
color: AppColor.textWhite,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 12),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildWinnerCard(String number, String name, String date, int index) {
|
||||||
|
return TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(milliseconds: 800 + (index * 200)),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Transform.translate(
|
||||||
|
offset: Offset(0, 30 * (1 - value)),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 6),
|
||||||
|
padding: EdgeInsets.all(18),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.white.withOpacity(0.12),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.white.withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.black.withOpacity(0.05),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// Trophy Icon
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColor.warning,
|
||||||
|
AppColor.warning.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.warning.withOpacity(0.3),
|
||||||
|
blurRadius: 12,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.emoji_events_rounded,
|
||||||
|
color: AppColor.white,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(width: 16),
|
||||||
|
|
||||||
|
// Winner Info
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
number,
|
||||||
|
style: AppStyle.md.copyWith(
|
||||||
|
color: AppColor.white,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
name,
|
||||||
|
style: AppStyle.sm.copyWith(
|
||||||
|
color: AppColor.warning,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
date,
|
||||||
|
style: AppStyle.xs.copyWith(
|
||||||
|
color: AppColor.white.withOpacity(0.7),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Winner Badge
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.success.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.success.withOpacity(0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text('🏆', style: TextStyle(fontSize: 12)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: AppColor.primaryGradient,
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: ListView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Title
|
||||||
|
_buildTitle(),
|
||||||
|
|
||||||
|
SizedBox(height: 24),
|
||||||
|
|
||||||
|
// Today's Winner Banner
|
||||||
|
_buildTodayWinnerBanner(),
|
||||||
|
|
||||||
|
SizedBox(height: 24),
|
||||||
|
|
||||||
|
// History Section Title
|
||||||
|
_buildHistorySection(),
|
||||||
|
|
||||||
|
// Winner History Cards
|
||||||
|
_buildWinnerCard('138472', 'Budi***', 'Kemarin', 0),
|
||||||
|
_buildWinnerCard('928374', 'Sari***', '2 hari lalu', 1),
|
||||||
|
_buildWinnerCard('475829', 'Dono***', '3 hari lalu', 2),
|
||||||
|
_buildWinnerCard('629384', 'Lisa***', '4 hari lalu', 3),
|
||||||
|
|
||||||
|
SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom painter for celebration particles effect
|
||||||
|
class CelebrationPainter extends CustomPainter {
|
||||||
|
final double animationValue;
|
||||||
|
|
||||||
|
CelebrationPainter(this.animationValue);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final paint = Paint()..style = PaintingStyle.fill;
|
||||||
|
|
||||||
|
// Draw floating particles
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
final angle = (i * 45) * (3.14159 / 180);
|
||||||
|
final radius = animationValue * 40;
|
||||||
|
final x = size.width / 2 + radius * cos(angle);
|
||||||
|
final y = size.height / 2 + radius * sin(angle);
|
||||||
|
|
||||||
|
paint.color = AppColor.warning.withOpacity(0.3 * animationValue);
|
||||||
|
canvas.drawCircle(Offset(x, y), 2 * animationValue, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DrawDetailBottomNavbar extends StatelessWidget {
|
||||||
|
final TabsRouter tabsRouter;
|
||||||
|
const DrawDetailBottomNavbar({super.key, required this.tabsRouter});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BottomNavigationBar(
|
||||||
|
currentIndex: tabsRouter.activeIndex,
|
||||||
|
onTap: (index) {
|
||||||
|
tabsRouter.setActiveIndex(index);
|
||||||
|
},
|
||||||
|
items: const [
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.today),
|
||||||
|
label: 'Hari Ini',
|
||||||
|
tooltip: 'Hari Ini',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.confirmation_number),
|
||||||
|
label: 'Nomorku',
|
||||||
|
tooltip: 'Nomorku',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.emoji_events),
|
||||||
|
label: 'Pemenang',
|
||||||
|
tooltip: 'Pemenang',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.info),
|
||||||
|
label: 'Hadiah & Info',
|
||||||
|
tooltip: 'Hadiah & Info',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -41,7 +41,15 @@ class AppRouter extends RootStackRouter {
|
|||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
AutoRoute(page: DrawRoute.page),
|
AutoRoute(page: DrawRoute.page),
|
||||||
AutoRoute(page: DrawDetailRoute.page),
|
AutoRoute(
|
||||||
|
page: DrawDetailRoute.page,
|
||||||
|
children: [
|
||||||
|
AutoRoute(page: DrawTodayRoute.page),
|
||||||
|
AutoRoute(page: DrawMyNumberRoute.page),
|
||||||
|
AutoRoute(page: DrawWinnerRoute.page),
|
||||||
|
AutoRoute(page: DrawInfoRoute.page),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
// Voucher
|
// Voucher
|
||||||
AutoRoute(page: VoucherDetailRoute.page),
|
AutoRoute(page: VoucherDetailRoute.page),
|
||||||
|
|||||||
@ -9,66 +9,74 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
|
|
||||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
import 'package:auto_route/auto_route.dart' as _i29;
|
import 'package:auto_route/auto_route.dart' as _i33;
|
||||||
import 'package:enaklo/presentation/pages/account/account_my/account_my_page.dart'
|
import 'package:enaklo/presentation/pages/account/account_my/account_my_page.dart'
|
||||||
as _i1;
|
as _i1;
|
||||||
import 'package:enaklo/presentation/pages/account/address/address_page.dart'
|
import 'package:enaklo/presentation/pages/account/address/address_page.dart'
|
||||||
as _i2;
|
as _i2;
|
||||||
import 'package:enaklo/presentation/pages/account/payment/payment_page.dart'
|
import 'package:enaklo/presentation/pages/account/payment/payment_page.dart'
|
||||||
as _i18;
|
as _i22;
|
||||||
import 'package:enaklo/presentation/pages/auth/create_password/create_password_page.dart'
|
import 'package:enaklo/presentation/pages/auth/create_password/create_password_page.dart'
|
||||||
as _i3;
|
as _i3;
|
||||||
import 'package:enaklo/presentation/pages/auth/login/login_page.dart' as _i8;
|
import 'package:enaklo/presentation/pages/auth/login/login_page.dart' as _i12;
|
||||||
import 'package:enaklo/presentation/pages/auth/otp/otp_page.dart' as _i16;
|
import 'package:enaklo/presentation/pages/auth/otp/otp_page.dart' as _i20;
|
||||||
import 'package:enaklo/presentation/pages/auth/password/password_page.dart'
|
import 'package:enaklo/presentation/pages/auth/password/password_page.dart'
|
||||||
as _i17;
|
as _i21;
|
||||||
import 'package:enaklo/presentation/pages/auth/pin/pin_page.dart' as _i19;
|
import 'package:enaklo/presentation/pages/auth/pin/pin_page.dart' as _i23;
|
||||||
import 'package:enaklo/presentation/pages/auth/register/register_page.dart'
|
import 'package:enaklo/presentation/pages/auth/register/register_page.dart'
|
||||||
as _i24;
|
as _i28;
|
||||||
import 'package:enaklo/presentation/pages/draw/draw_page.dart' as _i5;
|
import 'package:enaklo/presentation/pages/draw/draw_page.dart' as _i7;
|
||||||
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/draw_detail_page.dart'
|
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/draw_detail_page.dart'
|
||||||
as _i4;
|
as _i4;
|
||||||
import 'package:enaklo/presentation/pages/main/main_page.dart' as _i9;
|
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/pages/draw_info_page.dart'
|
||||||
import 'package:enaklo/presentation/pages/main/pages/home/home_page.dart'
|
as _i5;
|
||||||
as _i7;
|
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/pages/draw_my_number_page.dart'
|
||||||
import 'package:enaklo/presentation/pages/main/pages/order/order_page.dart'
|
|
||||||
as _i15;
|
|
||||||
import 'package:enaklo/presentation/pages/main/pages/profile/profile_page.dart'
|
|
||||||
as _i23;
|
|
||||||
import 'package:enaklo/presentation/pages/main/pages/voucher/voucher_page.dart'
|
|
||||||
as _i28;
|
|
||||||
import 'package:enaklo/presentation/pages/merchant/merchant_page.dart' as _i11;
|
|
||||||
import 'package:enaklo/presentation/pages/merchant/pages/merchant_detail/merchant_detail_page.dart'
|
|
||||||
as _i10;
|
|
||||||
import 'package:enaklo/presentation/pages/mini_games/ferris_wheel/ferris_wheel_page.dart'
|
|
||||||
as _i6;
|
as _i6;
|
||||||
import 'package:enaklo/presentation/pages/notification/notification_page.dart'
|
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/pages/draw_today_page.dart'
|
||||||
as _i12;
|
as _i8;
|
||||||
import 'package:enaklo/presentation/pages/onboarding/onboarding_page.dart'
|
import 'package:enaklo/presentation/pages/draw/pages/draw_detail/pages/draw_winner_page.dart'
|
||||||
as _i13;
|
as _i9;
|
||||||
import 'package:enaklo/presentation/pages/order/order_detail/order_detail_page.dart'
|
import 'package:enaklo/presentation/pages/main/main_page.dart' as _i13;
|
||||||
as _i14;
|
import 'package:enaklo/presentation/pages/main/pages/home/home_page.dart'
|
||||||
import 'package:enaklo/presentation/pages/poin/pages/poin_history_page.dart'
|
as _i11;
|
||||||
as _i20;
|
import 'package:enaklo/presentation/pages/main/pages/order/order_page.dart'
|
||||||
import 'package:enaklo/presentation/pages/poin/pages/product_redeem/product_redeem_page.dart'
|
as _i19;
|
||||||
as _i22;
|
import 'package:enaklo/presentation/pages/main/pages/profile/profile_page.dart'
|
||||||
import 'package:enaklo/presentation/pages/poin/poin_page.dart' as _i21;
|
|
||||||
import 'package:enaklo/presentation/pages/reward/reward_page.dart' as _i25;
|
|
||||||
import 'package:enaklo/presentation/pages/splash/splash_page.dart' as _i26;
|
|
||||||
import 'package:enaklo/presentation/pages/voucher/voucher_detail/voucher_detail_page.dart'
|
|
||||||
as _i27;
|
as _i27;
|
||||||
import 'package:enaklo/sample/sample_data.dart' as _i31;
|
import 'package:enaklo/presentation/pages/main/pages/voucher/voucher_page.dart'
|
||||||
import 'package:flutter/material.dart' as _i30;
|
as _i32;
|
||||||
|
import 'package:enaklo/presentation/pages/merchant/merchant_page.dart' as _i15;
|
||||||
|
import 'package:enaklo/presentation/pages/merchant/pages/merchant_detail/merchant_detail_page.dart'
|
||||||
|
as _i14;
|
||||||
|
import 'package:enaklo/presentation/pages/mini_games/ferris_wheel/ferris_wheel_page.dart'
|
||||||
|
as _i10;
|
||||||
|
import 'package:enaklo/presentation/pages/notification/notification_page.dart'
|
||||||
|
as _i16;
|
||||||
|
import 'package:enaklo/presentation/pages/onboarding/onboarding_page.dart'
|
||||||
|
as _i17;
|
||||||
|
import 'package:enaklo/presentation/pages/order/order_detail/order_detail_page.dart'
|
||||||
|
as _i18;
|
||||||
|
import 'package:enaklo/presentation/pages/poin/pages/poin_history_page.dart'
|
||||||
|
as _i24;
|
||||||
|
import 'package:enaklo/presentation/pages/poin/pages/product_redeem/product_redeem_page.dart'
|
||||||
|
as _i26;
|
||||||
|
import 'package:enaklo/presentation/pages/poin/poin_page.dart' as _i25;
|
||||||
|
import 'package:enaklo/presentation/pages/reward/reward_page.dart' as _i29;
|
||||||
|
import 'package:enaklo/presentation/pages/splash/splash_page.dart' as _i30;
|
||||||
|
import 'package:enaklo/presentation/pages/voucher/voucher_detail/voucher_detail_page.dart'
|
||||||
|
as _i31;
|
||||||
|
import 'package:enaklo/sample/sample_data.dart' as _i35;
|
||||||
|
import 'package:flutter/material.dart' as _i34;
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i1.AccountMyPage]
|
/// [_i1.AccountMyPage]
|
||||||
class AccountMyRoute extends _i29.PageRouteInfo<void> {
|
class AccountMyRoute extends _i33.PageRouteInfo<void> {
|
||||||
const AccountMyRoute({List<_i29.PageRouteInfo>? children})
|
const AccountMyRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(AccountMyRoute.name, initialChildren: children);
|
: super(AccountMyRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'AccountMyRoute';
|
static const String name = 'AccountMyRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i1.AccountMyPage();
|
return const _i1.AccountMyPage();
|
||||||
@ -78,13 +86,13 @@ class AccountMyRoute extends _i29.PageRouteInfo<void> {
|
|||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i2.AddressPage]
|
/// [_i2.AddressPage]
|
||||||
class AddressRoute extends _i29.PageRouteInfo<void> {
|
class AddressRoute extends _i33.PageRouteInfo<void> {
|
||||||
const AddressRoute({List<_i29.PageRouteInfo>? children})
|
const AddressRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(AddressRoute.name, initialChildren: children);
|
: super(AddressRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'AddressRoute';
|
static const String name = 'AddressRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i2.AddressPage();
|
return const _i2.AddressPage();
|
||||||
@ -94,13 +102,13 @@ class AddressRoute extends _i29.PageRouteInfo<void> {
|
|||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i3.CreatePasswordPage]
|
/// [_i3.CreatePasswordPage]
|
||||||
class CreatePasswordRoute extends _i29.PageRouteInfo<void> {
|
class CreatePasswordRoute extends _i33.PageRouteInfo<void> {
|
||||||
const CreatePasswordRoute({List<_i29.PageRouteInfo>? children})
|
const CreatePasswordRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(CreatePasswordRoute.name, initialChildren: children);
|
: super(CreatePasswordRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'CreatePasswordRoute';
|
static const String name = 'CreatePasswordRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i3.CreatePasswordPage();
|
return const _i3.CreatePasswordPage();
|
||||||
@ -110,128 +118,171 @@ class CreatePasswordRoute extends _i29.PageRouteInfo<void> {
|
|||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i4.DrawDetailPage]
|
/// [_i4.DrawDetailPage]
|
||||||
class DrawDetailRoute extends _i29.PageRouteInfo<DrawDetailRouteArgs> {
|
class DrawDetailRoute extends _i33.PageRouteInfo<void> {
|
||||||
DrawDetailRoute({
|
const DrawDetailRoute({List<_i33.PageRouteInfo>? children})
|
||||||
_i30.Key? key,
|
: super(DrawDetailRoute.name, initialChildren: children);
|
||||||
required _i5.DrawEvent drawEvent,
|
|
||||||
List<_i29.PageRouteInfo>? children,
|
|
||||||
}) : super(
|
|
||||||
DrawDetailRoute.name,
|
|
||||||
args: DrawDetailRouteArgs(key: key, drawEvent: drawEvent),
|
|
||||||
initialChildren: children,
|
|
||||||
);
|
|
||||||
|
|
||||||
static const String name = 'DrawDetailRoute';
|
static const String name = 'DrawDetailRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<DrawDetailRouteArgs>();
|
return const _i4.DrawDetailPage();
|
||||||
return _i4.DrawDetailPage(key: args.key, drawEvent: args.drawEvent);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DrawDetailRouteArgs {
|
/// generated route for
|
||||||
const DrawDetailRouteArgs({this.key, required this.drawEvent});
|
/// [_i5.DrawInfoPage]
|
||||||
|
class DrawInfoRoute extends _i33.PageRouteInfo<void> {
|
||||||
|
const DrawInfoRoute({List<_i33.PageRouteInfo>? children})
|
||||||
|
: super(DrawInfoRoute.name, initialChildren: children);
|
||||||
|
|
||||||
final _i30.Key? key;
|
static const String name = 'DrawInfoRoute';
|
||||||
|
|
||||||
final _i5.DrawEvent drawEvent;
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
|
name,
|
||||||
@override
|
builder: (data) {
|
||||||
String toString() {
|
return const _i5.DrawInfoPage();
|
||||||
return 'DrawDetailRouteArgs{key: $key, drawEvent: $drawEvent}';
|
},
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i5.DrawPage]
|
/// [_i6.DrawMyNumberPage]
|
||||||
class DrawRoute extends _i29.PageRouteInfo<void> {
|
class DrawMyNumberRoute extends _i33.PageRouteInfo<void> {
|
||||||
const DrawRoute({List<_i29.PageRouteInfo>? children})
|
const DrawMyNumberRoute({List<_i33.PageRouteInfo>? children})
|
||||||
|
: super(DrawMyNumberRoute.name, initialChildren: children);
|
||||||
|
|
||||||
|
static const String name = 'DrawMyNumberRoute';
|
||||||
|
|
||||||
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const _i6.DrawMyNumberPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i7.DrawPage]
|
||||||
|
class DrawRoute extends _i33.PageRouteInfo<void> {
|
||||||
|
const DrawRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(DrawRoute.name, initialChildren: children);
|
: super(DrawRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'DrawRoute';
|
static const String name = 'DrawRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i5.DrawPage();
|
return const _i7.DrawPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i6.FerrisWheelPage]
|
/// [_i8.DrawTodayPage]
|
||||||
class FerrisWheelRoute extends _i29.PageRouteInfo<void> {
|
class DrawTodayRoute extends _i33.PageRouteInfo<void> {
|
||||||
const FerrisWheelRoute({List<_i29.PageRouteInfo>? children})
|
const DrawTodayRoute({List<_i33.PageRouteInfo>? children})
|
||||||
|
: super(DrawTodayRoute.name, initialChildren: children);
|
||||||
|
|
||||||
|
static const String name = 'DrawTodayRoute';
|
||||||
|
|
||||||
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const _i8.DrawTodayPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i9.DrawWinnerPage]
|
||||||
|
class DrawWinnerRoute extends _i33.PageRouteInfo<void> {
|
||||||
|
const DrawWinnerRoute({List<_i33.PageRouteInfo>? children})
|
||||||
|
: super(DrawWinnerRoute.name, initialChildren: children);
|
||||||
|
|
||||||
|
static const String name = 'DrawWinnerRoute';
|
||||||
|
|
||||||
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const _i9.DrawWinnerPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [_i10.FerrisWheelPage]
|
||||||
|
class FerrisWheelRoute extends _i33.PageRouteInfo<void> {
|
||||||
|
const FerrisWheelRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(FerrisWheelRoute.name, initialChildren: children);
|
: super(FerrisWheelRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'FerrisWheelRoute';
|
static const String name = 'FerrisWheelRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i6.FerrisWheelPage();
|
return const _i10.FerrisWheelPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i7.HomePage]
|
/// [_i11.HomePage]
|
||||||
class HomeRoute extends _i29.PageRouteInfo<void> {
|
class HomeRoute extends _i33.PageRouteInfo<void> {
|
||||||
const HomeRoute({List<_i29.PageRouteInfo>? children})
|
const HomeRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(HomeRoute.name, initialChildren: children);
|
: super(HomeRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'HomeRoute';
|
static const String name = 'HomeRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i7.HomePage();
|
return const _i11.HomePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i8.LoginPage]
|
/// [_i12.LoginPage]
|
||||||
class LoginRoute extends _i29.PageRouteInfo<void> {
|
class LoginRoute extends _i33.PageRouteInfo<void> {
|
||||||
const LoginRoute({List<_i29.PageRouteInfo>? children})
|
const LoginRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(LoginRoute.name, initialChildren: children);
|
: super(LoginRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'LoginRoute';
|
static const String name = 'LoginRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i8.LoginPage();
|
return const _i12.LoginPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i9.MainPage]
|
/// [_i13.MainPage]
|
||||||
class MainRoute extends _i29.PageRouteInfo<void> {
|
class MainRoute extends _i33.PageRouteInfo<void> {
|
||||||
const MainRoute({List<_i29.PageRouteInfo>? children})
|
const MainRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(MainRoute.name, initialChildren: children);
|
: super(MainRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'MainRoute';
|
static const String name = 'MainRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i9.MainPage();
|
return const _i13.MainPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i10.MerchantDetailPage]
|
/// [_i14.MerchantDetailPage]
|
||||||
class MerchantDetailRoute extends _i29.PageRouteInfo<MerchantDetailRouteArgs> {
|
class MerchantDetailRoute extends _i33.PageRouteInfo<MerchantDetailRouteArgs> {
|
||||||
MerchantDetailRoute({
|
MerchantDetailRoute({
|
||||||
_i30.Key? key,
|
_i34.Key? key,
|
||||||
required _i31.MerchantModel merchant,
|
required _i35.MerchantModel merchant,
|
||||||
List<_i29.PageRouteInfo>? children,
|
List<_i33.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
MerchantDetailRoute.name,
|
MerchantDetailRoute.name,
|
||||||
args: MerchantDetailRouteArgs(key: key, merchant: merchant),
|
args: MerchantDetailRouteArgs(key: key, merchant: merchant),
|
||||||
@ -240,11 +291,11 @@ class MerchantDetailRoute extends _i29.PageRouteInfo<MerchantDetailRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'MerchantDetailRoute';
|
static const String name = 'MerchantDetailRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<MerchantDetailRouteArgs>();
|
final args = data.argsAs<MerchantDetailRouteArgs>();
|
||||||
return _i10.MerchantDetailPage(key: args.key, merchant: args.merchant);
|
return _i14.MerchantDetailPage(key: args.key, merchant: args.merchant);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -252,9 +303,9 @@ class MerchantDetailRoute extends _i29.PageRouteInfo<MerchantDetailRouteArgs> {
|
|||||||
class MerchantDetailRouteArgs {
|
class MerchantDetailRouteArgs {
|
||||||
const MerchantDetailRouteArgs({this.key, required this.merchant});
|
const MerchantDetailRouteArgs({this.key, required this.merchant});
|
||||||
|
|
||||||
final _i30.Key? key;
|
final _i34.Key? key;
|
||||||
|
|
||||||
final _i31.MerchantModel merchant;
|
final _i35.MerchantModel merchant;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -263,60 +314,60 @@ class MerchantDetailRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i11.MerchantPage]
|
/// [_i15.MerchantPage]
|
||||||
class MerchantRoute extends _i29.PageRouteInfo<void> {
|
class MerchantRoute extends _i33.PageRouteInfo<void> {
|
||||||
const MerchantRoute({List<_i29.PageRouteInfo>? children})
|
const MerchantRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(MerchantRoute.name, initialChildren: children);
|
: super(MerchantRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'MerchantRoute';
|
static const String name = 'MerchantRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i11.MerchantPage();
|
return const _i15.MerchantPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i12.NotificationPage]
|
/// [_i16.NotificationPage]
|
||||||
class NotificationRoute extends _i29.PageRouteInfo<void> {
|
class NotificationRoute extends _i33.PageRouteInfo<void> {
|
||||||
const NotificationRoute({List<_i29.PageRouteInfo>? children})
|
const NotificationRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(NotificationRoute.name, initialChildren: children);
|
: super(NotificationRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'NotificationRoute';
|
static const String name = 'NotificationRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i12.NotificationPage();
|
return const _i16.NotificationPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i13.OnboardingPage]
|
/// [_i17.OnboardingPage]
|
||||||
class OnboardingRoute extends _i29.PageRouteInfo<void> {
|
class OnboardingRoute extends _i33.PageRouteInfo<void> {
|
||||||
const OnboardingRoute({List<_i29.PageRouteInfo>? children})
|
const OnboardingRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(OnboardingRoute.name, initialChildren: children);
|
: super(OnboardingRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'OnboardingRoute';
|
static const String name = 'OnboardingRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i13.OnboardingPage();
|
return const _i17.OnboardingPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i14.OrderDetailPage]
|
/// [_i18.OrderDetailPage]
|
||||||
class OrderDetailRoute extends _i29.PageRouteInfo<OrderDetailRouteArgs> {
|
class OrderDetailRoute extends _i33.PageRouteInfo<OrderDetailRouteArgs> {
|
||||||
OrderDetailRoute({
|
OrderDetailRoute({
|
||||||
_i30.Key? key,
|
_i34.Key? key,
|
||||||
required _i15.Order order,
|
required _i19.Order order,
|
||||||
List<_i29.PageRouteInfo>? children,
|
List<_i33.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
OrderDetailRoute.name,
|
OrderDetailRoute.name,
|
||||||
args: OrderDetailRouteArgs(key: key, order: order),
|
args: OrderDetailRouteArgs(key: key, order: order),
|
||||||
@ -325,11 +376,11 @@ class OrderDetailRoute extends _i29.PageRouteInfo<OrderDetailRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'OrderDetailRoute';
|
static const String name = 'OrderDetailRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<OrderDetailRouteArgs>();
|
final args = data.argsAs<OrderDetailRouteArgs>();
|
||||||
return _i14.OrderDetailPage(key: args.key, order: args.order);
|
return _i18.OrderDetailPage(key: args.key, order: args.order);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -337,9 +388,9 @@ class OrderDetailRoute extends _i29.PageRouteInfo<OrderDetailRouteArgs> {
|
|||||||
class OrderDetailRouteArgs {
|
class OrderDetailRouteArgs {
|
||||||
const OrderDetailRouteArgs({this.key, required this.order});
|
const OrderDetailRouteArgs({this.key, required this.order});
|
||||||
|
|
||||||
final _i30.Key? key;
|
final _i34.Key? key;
|
||||||
|
|
||||||
final _i15.Order order;
|
final _i19.Order order;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -348,77 +399,77 @@ class OrderDetailRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i15.OrderPage]
|
/// [_i19.OrderPage]
|
||||||
class OrderRoute extends _i29.PageRouteInfo<void> {
|
class OrderRoute extends _i33.PageRouteInfo<void> {
|
||||||
const OrderRoute({List<_i29.PageRouteInfo>? children})
|
const OrderRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(OrderRoute.name, initialChildren: children);
|
: super(OrderRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'OrderRoute';
|
static const String name = 'OrderRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i15.OrderPage();
|
return const _i19.OrderPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i16.OtpPage]
|
/// [_i20.OtpPage]
|
||||||
class OtpRoute extends _i29.PageRouteInfo<void> {
|
class OtpRoute extends _i33.PageRouteInfo<void> {
|
||||||
const OtpRoute({List<_i29.PageRouteInfo>? children})
|
const OtpRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(OtpRoute.name, initialChildren: children);
|
: super(OtpRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'OtpRoute';
|
static const String name = 'OtpRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i16.OtpPage();
|
return const _i20.OtpPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i17.PasswordPage]
|
/// [_i21.PasswordPage]
|
||||||
class PasswordRoute extends _i29.PageRouteInfo<void> {
|
class PasswordRoute extends _i33.PageRouteInfo<void> {
|
||||||
const PasswordRoute({List<_i29.PageRouteInfo>? children})
|
const PasswordRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(PasswordRoute.name, initialChildren: children);
|
: super(PasswordRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'PasswordRoute';
|
static const String name = 'PasswordRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i17.PasswordPage();
|
return const _i21.PasswordPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i18.PaymentPage]
|
/// [_i22.PaymentPage]
|
||||||
class PaymentRoute extends _i29.PageRouteInfo<void> {
|
class PaymentRoute extends _i33.PageRouteInfo<void> {
|
||||||
const PaymentRoute({List<_i29.PageRouteInfo>? children})
|
const PaymentRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(PaymentRoute.name, initialChildren: children);
|
: super(PaymentRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'PaymentRoute';
|
static const String name = 'PaymentRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i18.PaymentPage();
|
return const _i22.PaymentPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i19.PinPage]
|
/// [_i23.PinPage]
|
||||||
class PinRoute extends _i29.PageRouteInfo<PinRouteArgs> {
|
class PinRoute extends _i33.PageRouteInfo<PinRouteArgs> {
|
||||||
PinRoute({
|
PinRoute({
|
||||||
_i30.Key? key,
|
_i34.Key? key,
|
||||||
bool isCreatePin = true,
|
bool isCreatePin = true,
|
||||||
String? title,
|
String? title,
|
||||||
List<_i29.PageRouteInfo>? children,
|
List<_i33.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
PinRoute.name,
|
PinRoute.name,
|
||||||
args: PinRouteArgs(key: key, isCreatePin: isCreatePin, title: title),
|
args: PinRouteArgs(key: key, isCreatePin: isCreatePin, title: title),
|
||||||
@ -427,13 +478,13 @@ class PinRoute extends _i29.PageRouteInfo<PinRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'PinRoute';
|
static const String name = 'PinRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<PinRouteArgs>(
|
final args = data.argsAs<PinRouteArgs>(
|
||||||
orElse: () => const PinRouteArgs(),
|
orElse: () => const PinRouteArgs(),
|
||||||
);
|
);
|
||||||
return _i19.PinPage(
|
return _i23.PinPage(
|
||||||
key: args.key,
|
key: args.key,
|
||||||
isCreatePin: args.isCreatePin,
|
isCreatePin: args.isCreatePin,
|
||||||
title: args.title,
|
title: args.title,
|
||||||
@ -445,7 +496,7 @@ class PinRoute extends _i29.PageRouteInfo<PinRouteArgs> {
|
|||||||
class PinRouteArgs {
|
class PinRouteArgs {
|
||||||
const PinRouteArgs({this.key, this.isCreatePin = true, this.title});
|
const PinRouteArgs({this.key, this.isCreatePin = true, this.title});
|
||||||
|
|
||||||
final _i30.Key? key;
|
final _i34.Key? key;
|
||||||
|
|
||||||
final bool isCreatePin;
|
final bool isCreatePin;
|
||||||
|
|
||||||
@ -458,45 +509,45 @@ class PinRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i20.PoinHistoryPage]
|
/// [_i24.PoinHistoryPage]
|
||||||
class PoinHistoryRoute extends _i29.PageRouteInfo<void> {
|
class PoinHistoryRoute extends _i33.PageRouteInfo<void> {
|
||||||
const PoinHistoryRoute({List<_i29.PageRouteInfo>? children})
|
const PoinHistoryRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(PoinHistoryRoute.name, initialChildren: children);
|
: super(PoinHistoryRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'PoinHistoryRoute';
|
static const String name = 'PoinHistoryRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i20.PoinHistoryPage();
|
return const _i24.PoinHistoryPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i21.PoinPage]
|
/// [_i25.PoinPage]
|
||||||
class PoinRoute extends _i29.PageRouteInfo<void> {
|
class PoinRoute extends _i33.PageRouteInfo<void> {
|
||||||
const PoinRoute({List<_i29.PageRouteInfo>? children})
|
const PoinRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(PoinRoute.name, initialChildren: children);
|
: super(PoinRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'PoinRoute';
|
static const String name = 'PoinRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i21.PoinPage();
|
return const _i25.PoinPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i22.ProductRedeemPage]
|
/// [_i26.ProductRedeemPage]
|
||||||
class ProductRedeemRoute extends _i29.PageRouteInfo<ProductRedeemRouteArgs> {
|
class ProductRedeemRoute extends _i33.PageRouteInfo<ProductRedeemRouteArgs> {
|
||||||
ProductRedeemRoute({
|
ProductRedeemRoute({
|
||||||
_i30.Key? key,
|
_i34.Key? key,
|
||||||
required _i21.Product product,
|
required _i25.Product product,
|
||||||
required _i21.PointCard pointCard,
|
required _i25.PointCard pointCard,
|
||||||
List<_i29.PageRouteInfo>? children,
|
List<_i33.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
ProductRedeemRoute.name,
|
ProductRedeemRoute.name,
|
||||||
args: ProductRedeemRouteArgs(
|
args: ProductRedeemRouteArgs(
|
||||||
@ -509,11 +560,11 @@ class ProductRedeemRoute extends _i29.PageRouteInfo<ProductRedeemRouteArgs> {
|
|||||||
|
|
||||||
static const String name = 'ProductRedeemRoute';
|
static const String name = 'ProductRedeemRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<ProductRedeemRouteArgs>();
|
final args = data.argsAs<ProductRedeemRouteArgs>();
|
||||||
return _i22.ProductRedeemPage(
|
return _i26.ProductRedeemPage(
|
||||||
key: args.key,
|
key: args.key,
|
||||||
product: args.product,
|
product: args.product,
|
||||||
pointCard: args.pointCard,
|
pointCard: args.pointCard,
|
||||||
@ -529,11 +580,11 @@ class ProductRedeemRouteArgs {
|
|||||||
required this.pointCard,
|
required this.pointCard,
|
||||||
});
|
});
|
||||||
|
|
||||||
final _i30.Key? key;
|
final _i34.Key? key;
|
||||||
|
|
||||||
final _i21.Product product;
|
final _i25.Product product;
|
||||||
|
|
||||||
final _i21.PointCard pointCard;
|
final _i25.PointCard pointCard;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -542,97 +593,97 @@ class ProductRedeemRouteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i23.ProfilePage]
|
/// [_i27.ProfilePage]
|
||||||
class ProfileRoute extends _i29.PageRouteInfo<void> {
|
class ProfileRoute extends _i33.PageRouteInfo<void> {
|
||||||
const ProfileRoute({List<_i29.PageRouteInfo>? children})
|
const ProfileRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(ProfileRoute.name, initialChildren: children);
|
: super(ProfileRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'ProfileRoute';
|
static const String name = 'ProfileRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i23.ProfilePage();
|
return const _i27.ProfilePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i24.RegisterPage]
|
/// [_i28.RegisterPage]
|
||||||
class RegisterRoute extends _i29.PageRouteInfo<void> {
|
class RegisterRoute extends _i33.PageRouteInfo<void> {
|
||||||
const RegisterRoute({List<_i29.PageRouteInfo>? children})
|
const RegisterRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(RegisterRoute.name, initialChildren: children);
|
: super(RegisterRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'RegisterRoute';
|
static const String name = 'RegisterRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i24.RegisterPage();
|
return const _i28.RegisterPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i25.RewardPage]
|
/// [_i29.RewardPage]
|
||||||
class RewardRoute extends _i29.PageRouteInfo<void> {
|
class RewardRoute extends _i33.PageRouteInfo<void> {
|
||||||
const RewardRoute({List<_i29.PageRouteInfo>? children})
|
const RewardRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(RewardRoute.name, initialChildren: children);
|
: super(RewardRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'RewardRoute';
|
static const String name = 'RewardRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i25.RewardPage();
|
return const _i29.RewardPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i26.SplashPage]
|
/// [_i30.SplashPage]
|
||||||
class SplashRoute extends _i29.PageRouteInfo<void> {
|
class SplashRoute extends _i33.PageRouteInfo<void> {
|
||||||
const SplashRoute({List<_i29.PageRouteInfo>? children})
|
const SplashRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(SplashRoute.name, initialChildren: children);
|
: super(SplashRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'SplashRoute';
|
static const String name = 'SplashRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i26.SplashPage();
|
return const _i30.SplashPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i27.VoucherDetailPage]
|
/// [_i31.VoucherDetailPage]
|
||||||
class VoucherDetailRoute extends _i29.PageRouteInfo<void> {
|
class VoucherDetailRoute extends _i33.PageRouteInfo<void> {
|
||||||
const VoucherDetailRoute({List<_i29.PageRouteInfo>? children})
|
const VoucherDetailRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(VoucherDetailRoute.name, initialChildren: children);
|
: super(VoucherDetailRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'VoucherDetailRoute';
|
static const String name = 'VoucherDetailRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i27.VoucherDetailPage();
|
return const _i31.VoucherDetailPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [_i28.VoucherPage]
|
/// [_i32.VoucherPage]
|
||||||
class VoucherRoute extends _i29.PageRouteInfo<void> {
|
class VoucherRoute extends _i33.PageRouteInfo<void> {
|
||||||
const VoucherRoute({List<_i29.PageRouteInfo>? children})
|
const VoucherRoute({List<_i33.PageRouteInfo>? children})
|
||||||
: super(VoucherRoute.name, initialChildren: children);
|
: super(VoucherRoute.name, initialChildren: children);
|
||||||
|
|
||||||
static const String name = 'VoucherRoute';
|
static const String name = 'VoucherRoute';
|
||||||
|
|
||||||
static _i29.PageInfo page = _i29.PageInfo(
|
static _i33.PageInfo page = _i33.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i28.VoucherPage();
|
return const _i32.VoucherPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user