import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import '../../../common/theme/theme.dart'; import '../../components/appbar/appbar.dart'; @RoutePage() class DownloadReportPage extends StatefulWidget { const DownloadReportPage({super.key}); @override State createState() => _DownloadReportPageState(); } class _DownloadReportPageState extends State with TickerProviderStateMixin { late AnimationController _fadeController; late AnimationController _slideController; late AnimationController _scaleController; late Animation _fadeAnimation; @override void initState() { super.initState(); // Initialize animation controllers _fadeController = AnimationController( duration: const Duration(milliseconds: 800), vsync: this, ); _slideController = AnimationController( duration: const Duration(milliseconds: 1000), vsync: this, ); _scaleController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); // Initialize animations _fadeAnimation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut), ); // Start animations _fadeController.forward(); _slideController.forward(); _scaleController.forward(); } @override void dispose() { _fadeController.dispose(); _slideController.dispose(); _scaleController.dispose(); super.dispose(); } void _showDateRangePicker(String reportType) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => _DateRangeBottomSheet( reportType: reportType, onDateRangeSelected: (dateRange) { setState(() {}); // Handle download logic here _downloadReport(reportType, dateRange); }, ), ); } void _downloadReport(String reportType, DateTimeRange dateRange) { // Implement download logic here ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Downloading $reportType from ${_formatDate(dateRange.start)} to ${_formatDate(dateRange.end)}', ), backgroundColor: AppColor.success, ), ); } String _formatDate(DateTime date) { return '${date.day}/${date.month}/${date.year}'; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.background, body: CustomScrollView( slivers: [ // SliverAppBar with gradient SliverAppBar( expandedHeight: 120, floating: false, pinned: true, elevation: 0, backgroundColor: AppColor.primary, flexibleSpace: CustomAppBar(title: 'Download Report'), ), // Content SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(20), child: Column( children: [ // Report Options FadeTransition( opacity: _fadeAnimation, child: Column( children: [ // Transaction Report Card _ReportOptionCard( title: 'Transaction Report', subtitle: 'Export all transaction data with detailed analytics', icon: Icons.receipt_long_outlined, gradient: const [ AppColor.primary, AppColor.primaryLight, ], onTap: () => _showDateRangePicker('Transaction Report'), delay: 200, ), const SizedBox(height: 20), // Inventory Report Card _ReportOptionCard( title: 'Inventory Report', subtitle: 'Export inventory and stock data with trends', icon: Icons.inventory_2_outlined, gradient: const [ AppColor.secondary, AppColor.secondaryLight, ], onTap: () => _showDateRangePicker('Inventory Report'), delay: 400, ), const SizedBox(height: 20), // Additional Report Options _ReportOptionCard( title: 'Sales Report', subtitle: 'Export sales performance and revenue data', icon: Icons.trending_up_outlined, gradient: const [AppColor.info, Color(0xFF64B5F6)], onTap: () => _showDateRangePicker('Sales Report'), delay: 600, ), const SizedBox(height: 20), _ReportOptionCard( title: 'Customer Report', subtitle: 'Export customer data and behavior analytics', icon: Icons.people_outline, gradient: const [AppColor.warning, Color(0xFFFFB74D)], onTap: () => _showDateRangePicker('Customer Report'), delay: 800, ), ], ), ), const SizedBox(height: 40), ], ), ), ), ], ), ); } } class _ReportOptionCard extends StatefulWidget { final String title; final String subtitle; final IconData icon; final List gradient; final VoidCallback onTap; final int delay; const _ReportOptionCard({ required this.title, required this.subtitle, required this.icon, required this.gradient, required this.onTap, required this.delay, }); @override State<_ReportOptionCard> createState() => _ReportOptionCardState(); } class _ReportOptionCardState extends State<_ReportOptionCard> with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _scaleAnimation; bool _isPressed = false; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 150), vsync: this, ); _scaleAnimation = Tween(begin: 1.0, end: 0.95).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTapDown: (_) { setState(() => _isPressed = true); _animationController.forward(); }, onTapUp: (_) { setState(() => _isPressed = false); _animationController.reverse(); widget.onTap(); }, onTapCancel: () { setState(() => _isPressed = false); _animationController.reverse(); }, child: ScaleTransition( scale: _scaleAnimation, child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: _isPressed ? widget.gradient.map((c) => c.withOpacity(0.8)).toList() : widget.gradient, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: widget.gradient.first.withOpacity(0.3), blurRadius: _isPressed ? 8 : 15, offset: Offset(0, _isPressed ? 2 : 8), ), ], ), child: Row( children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColor.white.withOpacity(0.2), borderRadius: BorderRadius.circular(16), ), child: Icon(widget.icon, color: AppColor.white, size: 32), ), const SizedBox(width: 20), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.title, style: AppStyle.lg.copyWith( color: AppColor.white, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( widget.subtitle, style: AppStyle.sm.copyWith( color: AppColor.white.withOpacity(0.8), ), ), ], ), ), Icon( Icons.arrow_forward_ios, color: AppColor.white.withOpacity(0.8), size: 20, ), ], ), ), ), ); } } class _DateRangeBottomSheet extends StatefulWidget { final String reportType; final Function(DateTimeRange) onDateRangeSelected; const _DateRangeBottomSheet({ required this.reportType, required this.onDateRangeSelected, }); @override State<_DateRangeBottomSheet> createState() => _DateRangeBottomSheetState(); } class _DateRangeBottomSheetState extends State<_DateRangeBottomSheet> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _animation; DateTime? _startDate; DateTime? _endDate; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _animation = CurvedAnimation( parent: _controller, curve: Curves.easeOutCubic, ); _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } void _selectStartDate() async { final date = await showDatePicker( context: context, initialDate: _startDate ?? DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: const ColorScheme.light(primary: AppColor.primary), ), child: child!, ); }, ); if (date != null) { setState(() => _startDate = date); } } void _selectEndDate() async { final date = await showDatePicker( context: context, initialDate: _endDate ?? DateTime.now(), firstDate: _startDate ?? DateTime(2020), lastDate: DateTime.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: const ColorScheme.light(primary: AppColor.primary), ), child: child!, ); }, ); if (date != null) { setState(() => _endDate = date); } } void _downloadReport() { if (_startDate != null && _endDate != null) { final dateRange = DateTimeRange(start: _startDate!, end: _endDate!); widget.onDateRangeSelected(dateRange); Navigator.pop(context); } } String _formatDate(DateTime? date) { if (date == null) return 'Select Date'; return '${date.day}/${date.month}/${date.year}'; } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _animation, builder: (context, child) { return Transform.translate( offset: Offset(0, (1 - _animation.value) * 300), child: Container( decoration: const BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30), ), ), child: Padding( padding: EdgeInsets.only( left: 20, right: 20, top: 20, bottom: MediaQuery.of(context).viewInsets.bottom + 20, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Handle bar Container( width: 50, height: 4, decoration: BoxDecoration( color: AppColor.border, borderRadius: BorderRadius.circular(2), ), ), const SizedBox(height: 20), // Title Text( widget.reportType, style: AppStyle.h6.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( 'Select date range for your report', style: AppStyle.md.copyWith(color: AppColor.textSecondary), ), const SizedBox(height: 30), // Date Selection Row( children: [ Expanded( child: _DateSelectionCard( title: 'Start Date', date: _formatDate(_startDate), onTap: _selectStartDate, ), ), const SizedBox(width: 16), Expanded( child: _DateSelectionCard( title: 'End Date', date: _formatDate(_endDate), onTap: _selectEndDate, ), ), ], ), const SizedBox(height: 30), // Download Button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _startDate != null && _endDate != null ? _downloadReport : null, style: ElevatedButton.styleFrom( backgroundColor: AppColor.primary, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 0, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.download_rounded, color: AppColor.white, ), const SizedBox(width: 8), Text( 'Download Report', style: AppStyle.lg.copyWith( color: AppColor.white, fontWeight: FontWeight.bold, ), ), ], ), ), ), const SizedBox(height: 10), ], ), ), ), ); }, ); } } class _DateSelectionCard extends StatelessWidget { final String title; final String date; final VoidCallback onTap; const _DateSelectionCard({ required this.title, required this.date, required this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColor.background, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColor.border), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Row( children: [ Expanded( child: Text( date, style: AppStyle.md.copyWith( fontWeight: FontWeight.w600, color: date == 'Select Date' ? AppColor.textLight : AppColor.textPrimary, ), ), ), Icon( Icons.calendar_today_outlined, color: AppColor.primary, size: 18, ), ], ), ], ), ), ); } }