Compare commits

..

No commits in common. "37b22fe6629e4c7e300ffe3f2b8a7cb43c55e766" and "dc4fdf5fbf6f35918b37f408c63e66313104a208" have entirely different histories.

2 changed files with 232 additions and 856 deletions

View File

@ -2,6 +2,8 @@ import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
// Import your theme files here
// import 'theme.dart';
@RoutePage()
class PaymentPage extends StatefulWidget {
@ -12,292 +14,125 @@ class PaymentPage extends StatefulWidget {
}
class _PaymentPageState extends State<PaymentPage> {
// Featured payment methods
final List<Map<String, dynamic>> featuredMethods = [
// Sample saved payment methods data
final List<Map<String, dynamic>> savedPaymentMethods = [
{
'id': 'qris',
'name': 'QRIS',
'subtitle': null,
'icon': 'assets/images/qris.png',
'iconColor': AppColor.black,
'badge': 'Baru',
'badgeColor': const Color(0xFFE57373),
},
];
// Main payment categories
final List<Map<String, dynamic>> paymentCategories = [
{
'id': 'credit_card',
'id': '1',
'type': 'credit_card',
'name': 'Kartu Kredit',
'subtitle':
'Minimal pembayaran Rp 10.000 dan mendukung Kartu Berlogo Visa, Mastercard dan JCB',
'details': '**** **** **** 1234',
'cardType': 'Visa',
'expiryDate': '12/26',
'isDefault': true,
'icon': Icons.credit_card,
'iconColor': const Color(0xFF2E7D32),
'hasArrow': false,
},
{
'id': '2',
'type': 'credit_card',
'name': 'Kartu Debit',
'details': '**** **** **** 5678',
'cardType': 'Mastercard',
'expiryDate': '08/27',
'isDefault': false,
'icon': Icons.credit_card,
},
{
'id': '3',
'type': 'ewallet',
'name': 'DANA',
'details': '081234567890',
'cardType': 'E-Wallet',
'expiryDate': null,
'isDefault': false,
'icon': Icons.account_balance_wallet,
},
{
'id': '4',
'type': 'ewallet',
'name': 'GoPay',
'details': '081234567890',
'cardType': 'E-Wallet',
'expiryDate': null,
'isDefault': false,
'icon': Icons.account_balance_wallet,
},
{
'id': '5',
'type': 'bank_account',
'name': 'BCA',
'details': '**** **** 9012',
'cardType': 'Bank Account',
'expiryDate': null,
'isDefault': false,
'icon': Icons.account_balance,
},
];
// Other payment methods
final List<Map<String, dynamic>> otherMethods = [
{
'id': 'gopay',
'name': 'Gopay',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/gopay.png',
'iconColor': const Color(0xFF00AA5B),
'hasArrow': true,
},
{
'id': 'dana',
'name': 'Dana',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/dana.png',
'iconColor': const Color(0xFF118EEA),
'hasArrow': true,
},
{
'id': 'blu',
'name': 'blu',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/blu.png',
'iconColor': const Color(0xFF00D4FF),
'hasArrow': true,
},
{
'id': 'shopeepay',
'name': 'ShopeePay',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/shopeepay.png',
'iconColor': const Color(0xFFEE4D2D),
'hasArrow': true,
},
{
'id': 'ovo',
'name': 'OVO',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/ovo.png',
'iconColor': const Color(0xFF4C3EC9),
'hasArrow': true,
},
];
Widget _buildFeaturedCard(Map<String, dynamic> method) {
Widget _buildPaymentCard(Map<String, dynamic> payment) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.border.withOpacity(0.3)),
border: Border(bottom: BorderSide(color: AppColor.border)),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
// Logo placeholder
Container(
width: 40,
height: 24,
width: 48,
height: 48,
decoration: BoxDecoration(
color: AppColor.black,
borderRadius: BorderRadius.circular(4),
),
child: Center(
child: Text(
method['name'],
style: AppStyle.sm.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w700,
fontSize: 10,
),
),
color: AppColor.background,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.border),
),
child: Icon(payment['icon'], color: AppColor.primary, size: 24),
),
const SizedBox(width: 16),
Text(
method['name'],
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
),
),
const Spacer(),
if (method['badge'] != null)
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: method['badgeColor'],
borderRadius: BorderRadius.circular(12),
),
child: Text(
method['badge'],
style: AppStyle.sm.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
),
),
],
),
);
}
Widget _buildCategoryCard(Map<String, dynamic> category) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.border.withOpacity(0.3)),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: category['iconColor'].withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(
category['icon'],
color: category['iconColor'],
size: 20,
),
),
const SizedBox(width: 16),
Text(
category['name'],
style: AppStyle.lg.copyWith(
payment['name'],
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
),
),
],
),
if (category['subtitle'] != null) ...[
const SizedBox(height: 12),
Text(
category['subtitle'],
style: AppStyle.md.copyWith(
color: const Color(0xFF4CAF50),
height: 1.4,
),
),
],
],
),
);
}
Widget _buildPaymentMethodCard(Map<String, dynamic> method) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
// Handle method selection
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
decoration: const BoxDecoration(
color: AppColor.white,
border: Border(
bottom: BorderSide(color: Color(0xFFF5F5F5), width: 1),
),
),
child: Row(
children: [
// Method logo/icon
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
),
child: method['logo'] != null
? ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.asset(
method['logo'],
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return _buildFallbackIcon(method);
},
),
)
: _buildFallbackIcon(method),
),
const SizedBox(width: 16),
// Method info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
const SizedBox(height: 4),
Row(
children: [
Text(
method['name'],
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
payment['cardType'],
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
),
),
if (method['subtitle'] != null) ...[
const SizedBox(height: 2),
if (payment['expiryDate'] != null) ...[
Text(
method['subtitle'],
style: AppStyle.md.copyWith(color: AppColor.textLight),
' • ',
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
),
),
Text(
'Exp: ${payment['expiryDate']}',
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
),
),
],
],
),
),
// Arrow icon
if (method['hasArrow'] == true)
const Icon(
Icons.chevron_right,
color: AppColor.textLight,
size: 20,
),
],
),
),
),
);
}
Widget _buildFallbackIcon(Map<String, dynamic> method) {
String initial = method['name'][0].toUpperCase();
Color backgroundColor = method['iconColor'] ?? AppColor.primary;
return Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: backgroundColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
initial,
style: AppStyle.md.copyWith(
color: backgroundColor,
fontWeight: FontWeight.w700,
),
),
),
);
}
Widget _buildSectionHeader(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 24, 20, 8),
child: Text(
title,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
],
),
),
);
@ -306,39 +141,77 @@ class _PaymentPageState extends State<PaymentPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFFAFAFA),
backgroundColor: AppColor.background,
appBar: AppBar(title: Text('Metode Pembayaran')),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
body: savedPaymentMethods.isEmpty
? _buildEmptyState()
: Column(
children: [
const SizedBox(height: 16),
// Featured methods
...featuredMethods.map((method) => _buildFeaturedCard(method)),
const SizedBox(height: 16),
// Payment categories
...paymentCategories.map(
(category) => _buildCategoryCard(category),
),
// Section header for other methods
_buildSectionHeader('Metode Pembayaran Lainnya'),
// Other payment methods
Container(
decoration: const BoxDecoration(color: AppColor.white),
child: Column(
children: otherMethods
.map((method) => _buildPaymentMethodCard(method))
.toList(),
Expanded(
child: ListView.builder(
itemCount: savedPaymentMethods.length,
itemBuilder: (context, index) {
return _buildPaymentCard(savedPaymentMethods[index]);
},
),
),
const SizedBox(height: 32),
],
),
);
}
Widget _buildEmptyState() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.payment_outlined, size: 80, color: AppColor.textLight),
const SizedBox(height: 16),
Text(
'Belum Ada Metode Pembayaran',
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textSecondary,
),
),
const SizedBox(height: 8),
Text(
'Tambahkan kartu atau e-wallet untuk\nmemudahkan proses pembayaran',
textAlign: TextAlign.center,
style: AppStyle.md.copyWith(color: AppColor.textLight, height: 1.4),
),
const SizedBox(height: 32),
SizedBox(
width: 220,
height: 48,
child: ElevatedButton(
onPressed: () {
// Navigate to add payment method form
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.primary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.add, color: AppColor.white, size: 20),
const SizedBox(width: 8),
Text(
'Tambah Pembayaran',
style: AppStyle.md.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
],
),
);
}

View File

@ -1,4 +1,3 @@
import 'dart:math' show cos, sin;
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
@ -18,27 +17,16 @@ class _DrawTodayPageState extends State<DrawTodayPage>
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;
// Lottery Logic
String globalNumber = '849302';
String userNumber = '849302'; // Change this to test winner/loser
bool isWinner = false;
bool hasCheckedResult = false;
@override
void initState() {
super.initState();
// Check if user is winner
isWinner = userNumber == globalNumber;
_fadeController = AnimationController(
duration: Duration(milliseconds: 1200),
vsync: this,
@ -59,11 +47,6 @@ class _DrawTodayPageState extends State<DrawTodayPage>
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),
);
@ -81,10 +64,6 @@ class _DrawTodayPageState extends State<DrawTodayPage>
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
);
_celebrationAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _celebrationController, curve: Curves.elasticOut),
);
_startAnimations();
}
@ -98,11 +77,6 @@ class _DrawTodayPageState extends State<DrawTodayPage>
await Future.delayed(Duration(milliseconds: 300));
_scaleController.forward();
if (isWinner) {
await Future.delayed(Duration(milliseconds: 600));
_celebrationController.forward();
}
await Future.delayed(Duration(milliseconds: 800));
_pulseController.repeat(reverse: true);
}
@ -113,348 +87,9 @@ class _DrawTodayPageState extends State<DrawTodayPage>
_slideController.dispose();
_scaleController.dispose();
_pulseController.dispose();
_celebrationController.dispose();
super.dispose();
}
void _checkMyNumber() {
setState(() {
hasCheckedResult = true;
});
if (isWinner) {
_showWinnerDialog();
} else {
_showLoserDialog();
}
}
void _showWinnerDialog() {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [AppColor.warning, AppColor.warning.withOpacity(0.8)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: AppColor.warning.withOpacity(0.5),
blurRadius: 30,
spreadRadius: 5,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Animated Trophy
TweenAnimationBuilder<double>(
tween: Tween(begin: 0.0, end: 1.0),
duration: Duration(milliseconds: 1000),
curve: Curves.elasticOut,
builder: (context, value, child) {
return Transform.scale(
scale: value,
child: Transform.rotate(
angle: (1 - value) * 0.5,
child: Icon(
Icons.emoji_events_rounded,
color: AppColor.white,
size: 80,
),
),
);
},
),
SizedBox(height: 20),
Text(
'SELAMAT!',
style: AppStyle.h2.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w900,
letterSpacing: 2,
),
),
SizedBox(height: 8),
Text(
'Kamu Pemenang Hari Ini!',
style: AppStyle.lg.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
),
SizedBox(height: 16),
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColor.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(16),
),
child: Column(
children: [
Text(
'Nomor Pemenang',
style: AppStyle.sm.copyWith(
color: AppColor.white.withOpacity(0.8),
fontWeight: FontWeight.w600,
),
),
SizedBox(height: 8),
Text(
globalNumber,
style: TextStyle(
color: AppColor.white,
fontSize: 32,
fontWeight: FontWeight.w900,
letterSpacing: 8,
),
),
],
),
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.primary,
borderRadius: BorderRadius.circular(12),
),
child: Text(
'🏆 Hadiah: 3KG Emas Batangan 🏆',
style: AppStyle.md.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w700,
),
),
),
SizedBox(height: 24),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.white,
foregroundColor: AppColor.primary,
padding: EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
'Tutup',
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
),
),
),
),
SizedBox(width: 12),
Expanded(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Tim kami akan menghubungimu segera!',
),
backgroundColor: AppColor.success,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
behavior: SnackBarBehavior.floating,
),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.primary,
foregroundColor: AppColor.white,
padding: EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
'Klaim Hadiah',
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
),
),
),
),
],
),
],
),
),
);
},
);
}
void _showLoserDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: AppColor.black.withOpacity(0.1),
blurRadius: 20,
spreadRadius: 0,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(
Icons.close_rounded,
color: AppColor.primary,
size: 40,
),
),
SizedBox(height: 16),
Text(
'Belum Beruntung',
style: AppStyle.lg.copyWith(
color: AppColor.primary,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 8),
Text(
'Jangan menyerah! Coba lagi besok ya',
textAlign: TextAlign.center,
style: AppStyle.md.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 16),
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.05),
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Nomor Global:',
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
Text(
globalNumber,
style: AppStyle.sm.copyWith(
color: AppColor.primary,
fontWeight: FontWeight.w700,
letterSpacing: 2,
),
),
],
),
SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Nomor Kamu:',
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w500,
),
),
Text(
userNumber,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
letterSpacing: 2,
),
),
],
),
],
),
),
SizedBox(height: 20),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.primary,
foregroundColor: AppColor.white,
padding: EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
'Oke, Sampai Jumpa Besok!',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
),
),
),
],
),
),
);
},
);
}
Widget _buildTitle() {
return SlideTransition(
position: _slideAnimation,
@ -495,33 +130,14 @@ class _DrawTodayPageState extends State<DrawTodayPage>
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: isWinner
? AppColor.warning.withOpacity(0.3)
: AppColor.black.withOpacity(0.08),
color: AppColor.black.withOpacity(0.08),
blurRadius: 30,
spreadRadius: 0,
offset: Offset(0, 15),
),
],
),
child: Stack(
children: [
// Winner celebration overlay
if (isWinner)
Positioned.fill(
child: AnimatedBuilder(
animation: _celebrationAnimation,
builder: (context, child) {
return CustomPaint(
painter: WinnerCelebrationPainter(
_celebrationAnimation.value,
),
);
},
),
),
Padding(
child: Padding(
padding: EdgeInsets.all(24),
child: Column(
children: [
@ -529,15 +145,13 @@ class _DrawTodayPageState extends State<DrawTodayPage>
Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: isWinner
? AppColor.warning.withOpacity(0.15)
: AppColor.primary.withOpacity(0.08),
color: AppColor.primary.withOpacity(0.08),
borderRadius: BorderRadius.circular(20),
),
child: Text(
isWinner ? '🎉 NOMOR PEMENANG 🎉' : 'NOMOR UNDIAN GLOBAL',
'NOMOR UNDIAN GLOBAL',
style: AppStyle.xs.copyWith(
color: isWinner ? AppColor.warning : AppColor.primary,
color: AppColor.primary,
fontWeight: FontWeight.w700,
letterSpacing: 1,
),
@ -553,19 +167,13 @@ class _DrawTodayPageState extends State<DrawTodayPage>
return Transform.scale(
scale: _pulseAnimation.value,
child: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 16,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: isWinner
? [
AppColor.warning.withOpacity(0.1),
AppColor.warning.withOpacity(0.05),
]
: [
colors: [
AppColor.primary.withOpacity(0.05),
AppColor.primary.withOpacity(0.02),
],
@ -574,18 +182,14 @@ class _DrawTodayPageState extends State<DrawTodayPage>
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: isWinner
? AppColor.warning.withOpacity(0.3)
: AppColor.primary.withOpacity(0.1),
color: AppColor.primary.withOpacity(0.1),
width: 1,
),
),
child: Text(
globalNumber,
'849302',
style: TextStyle(
color: isWinner
? AppColor.warning
: AppColor.primary,
color: AppColor.primary,
fontSize: 42,
fontWeight: FontWeight.w900,
letterSpacing: 12,
@ -599,8 +203,6 @@ class _DrawTodayPageState extends State<DrawTodayPage>
],
),
),
],
),
),
);
}
@ -708,79 +310,6 @@ class _DrawTodayPageState extends State<DrawTodayPage>
padding: EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
// Check My Number Button
Container(
width: double.infinity,
margin: EdgeInsets.only(bottom: 12),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: hasCheckedResult ? null : _checkMyNumber,
borderRadius: BorderRadius.circular(16),
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: hasCheckedResult
? null
: LinearGradient(
colors: [
AppColor.warning.withOpacity(0.8),
AppColor.warning,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
color: hasCheckedResult
? AppColor.black.withOpacity(0.15)
: null,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: hasCheckedResult
? AppColor.white.withOpacity(0.15)
: AppColor.warning.withOpacity(0.3),
width: 1,
),
boxShadow: hasCheckedResult
? null
: [
BoxShadow(
color: AppColor.warning.withOpacity(0.3),
blurRadius: 15,
offset: Offset(0, 5),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
hasCheckedResult
? Icons.check_circle_rounded
: Icons.casino_rounded,
color: hasCheckedResult
? AppColor.white.withOpacity(0.5)
: AppColor.white,
size: 20,
),
SizedBox(width: 8),
Text(
hasCheckedResult
? 'Sudah Dicek'
: 'Cek Nomorku Sekarang!',
style: AppStyle.md.copyWith(
color: hasCheckedResult
? AppColor.white.withOpacity(0.5)
: AppColor.white,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
),
),
// Next Draw Card
Container(
width: double.infinity,
@ -860,7 +389,7 @@ class _DrawTodayPageState extends State<DrawTodayPage>
),
SizedBox(width: 8),
Text(
'Nomormu hari ini: $userNumber',
'Cek tiket undianmu di menu Tiket Saya',
style: AppStyle.xs.copyWith(
color: AppColor.white.withOpacity(0.9),
fontWeight: FontWeight.w500,
@ -921,29 +450,3 @@ class _DrawTodayPageState extends State<DrawTodayPage>
);
}
}
// Custom painter for winner celebration effect
class WinnerCelebrationPainter extends CustomPainter {
final double animationValue;
WinnerCelebrationPainter(this.animationValue);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..style = PaintingStyle.fill;
// Draw floating golden particles
for (int i = 0; i < 12; i++) {
final angle = (i * 30) * (3.14159 / 180);
final radius = animationValue * 50;
final x = size.width / 2 + radius * cos(angle);
final y = size.height / 2 + radius * sin(angle);
paint.color = AppColor.warning.withOpacity(0.4 * animationValue);
canvas.drawCircle(Offset(x, y), 3 * animationValue, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}