2025-08-29 20:50:03 +07:00

397 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../../../common/theme/theme.dart';
class HomeLotteryBanner extends StatefulWidget {
const HomeLotteryBanner({
super.key,
this.onTap,
this.title = "🎰 UNDIAN BERHADIAH",
this.subtitle = "Kumpulkan voucher untuk menang hadiah menarik!",
this.showAnimation = true,
this.actionText = "IKUTI SEKARANG",
});
final VoidCallback? onTap;
final String title;
final String subtitle;
final bool showAnimation;
final String actionText;
@override
State<HomeLotteryBanner> createState() => _HomeLotteryBannerState();
}
class _HomeLotteryBannerState extends State<HomeLotteryBanner>
with TickerProviderStateMixin {
late AnimationController _pulseController;
late AnimationController _shimmerController;
late AnimationController _floatingController;
late Animation<double> _pulseAnimation;
late Animation<double> _shimmerAnimation;
late Animation<double> _floatingAnimation;
@override
void initState() {
super.initState();
if (widget.showAnimation) {
// Pulse animation for the whole banner
_pulseController = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
// Shimmer effect for the gradient
_shimmerController = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
// Floating animation for the icon
_floatingController = AnimationController(
duration: const Duration(seconds: 4),
vsync: this,
);
_pulseAnimation = Tween<double>(begin: 1.0, end: 1.02).animate(
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
);
_shimmerAnimation = Tween<double>(begin: -2.0, end: 2.0).animate(
CurvedAnimation(parent: _shimmerController, curve: Curves.easeInOut),
);
_floatingAnimation = Tween<double>(begin: -5.0, end: 5.0).animate(
CurvedAnimation(parent: _floatingController, curve: Curves.easeInOut),
);
_pulseController.repeat(reverse: true);
_shimmerController.repeat(reverse: true);
_floatingController.repeat(reverse: true);
}
}
@override
void dispose() {
if (widget.showAnimation) {
_pulseController.dispose();
_shimmerController.dispose();
_floatingController.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
Widget banner = Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: AppColor.primary.withOpacity(0.4),
blurRadius: 20,
offset: const Offset(0, 8),
spreadRadius: 0,
),
BoxShadow(
color: Colors.orange.withOpacity(0.2),
blurRadius: 40,
offset: const Offset(0, 16),
spreadRadius: 0,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
// Main gradient background
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColor.primary,
Colors.orange.shade600,
Colors.red.shade500,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: const [0.0, 0.6, 1.0],
),
),
child: Column(
children: [
// Top section with icon and text
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Animated floating icon with multiple effects
widget.showAnimation
? AnimatedBuilder(
animation: _floatingAnimation,
builder: (context, child) {
return Transform.translate(
offset: Offset(0, _floatingAnimation.value),
child: _buildIcon(),
);
},
)
: _buildIcon(),
const SizedBox(width: 20),
// Enhanced text section - now expanded fully
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w900,
color: Colors.white,
letterSpacing: 0.5,
shadows: [
Shadow(
offset: Offset(0, 2),
blurRadius: 4,
color: Colors.black26,
),
],
),
),
const SizedBox(height: 4),
Text(
widget.subtitle,
style: TextStyle(
fontSize: 13,
color: Colors.white.withOpacity(0.95),
height: 1.2,
fontWeight: FontWeight.w500,
),
),
],
),
),
],
),
const SizedBox(height: 16),
// Bottom action button - full width
_buildActionButton(),
],
),
),
// Shimmer overlay effect
if (widget.showAnimation)
AnimatedBuilder(
animation: _shimmerAnimation,
builder: (context, child) {
return Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.transparent,
Colors.white.withOpacity(0.1),
Colors.transparent,
],
stops: const [0.0, 0.5, 1.0],
begin: Alignment(_shimmerAnimation.value, -1),
end: Alignment(_shimmerAnimation.value + 0.5, 1),
),
),
),
);
},
),
// Decorative dots pattern
Positioned(
top: -20,
right: -20,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white.withOpacity(0.05),
),
),
),
Positioned(
bottom: -10,
left: -30,
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.orange.withOpacity(0.1),
),
),
),
],
),
),
);
// Wrap with gesture detector and animations
if (widget.onTap != null) {
banner = GestureDetector(onTap: widget.onTap, child: banner);
}
if (widget.showAnimation) {
return AnimatedBuilder(
animation: _pulseAnimation,
builder: (context, child) {
return Transform.scale(scale: _pulseAnimation.value, child: banner);
},
);
}
return banner;
}
Widget _buildIcon() {
return Container(
width: 64,
height: 64,
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [
Colors.yellow.shade300,
Colors.orange.shade400,
Colors.red.shade500,
],
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.orange.withOpacity(0.6),
blurRadius: 12,
spreadRadius: 2,
),
BoxShadow(
color: Colors.yellow.withOpacity(0.3),
blurRadius: 20,
spreadRadius: 4,
),
],
),
child: Stack(
children: [
const Center(
child: Icon(
Icons.casino,
color: Colors.white,
size: 32,
shadows: [
Shadow(
offset: Offset(0, 2),
blurRadius: 4,
color: Colors.black26,
),
],
),
),
// Sparkle effects
Positioned(
top: 8,
right: 8,
child: Container(
width: 8,
height: 8,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.white,
blurRadius: 4,
spreadRadius: 1,
),
],
),
),
),
Positioned(
bottom: 10,
left: 10,
child: Container(
width: 4,
height: 4,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white70,
),
),
),
],
),
);
}
Widget _buildActionButton() {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.white, Colors.yellow.shade100],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderRadius: BorderRadius.circular(25),
border: Border.all(color: Colors.white.withOpacity(0.3), width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
BoxShadow(
color: Colors.white.withOpacity(0.5),
blurRadius: 4,
offset: const Offset(0, -1),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.actionText,
style: TextStyle(
color: AppColor.primary,
fontSize: 14,
fontWeight: FontWeight.w800,
letterSpacing: 0.5,
),
),
const SizedBox(width: 8),
Container(
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColor.primary.withOpacity(0.1),
),
child: Icon(
Icons.arrow_forward_rounded,
color: AppColor.primary,
size: 16,
),
),
],
),
);
}
}