diff --git a/lib/presentation/pages/finance/finance_page.dart b/lib/presentation/pages/finance/finance_page.dart new file mode 100644 index 0000000..8acbf22 --- /dev/null +++ b/lib/presentation/pages/finance/finance_page.dart @@ -0,0 +1,454 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:line_icons/line_icons.dart'; + +import '../../../common/theme/theme.dart'; +import 'widgets/appbar.dart'; +import 'widgets/cash_flow.dart'; +import 'widgets/category.dart'; +import 'widgets/profit_loss.dart'; +import 'widgets/summary_card.dart'; + +@RoutePage() +class FinancePage extends StatefulWidget { + const FinancePage({super.key}); + + @override + State createState() => _FinancePageState(); +} + +class _FinancePageState extends State + with TickerProviderStateMixin { + late AnimationController _slideController; + late AnimationController _fadeController; + late AnimationController _scaleController; + late AnimationController _rotationController; + late AnimationController _floatingController; + + late Animation _slideAnimation; + late Animation _fadeAnimation; + late Animation _scaleAnimation; + late Animation rotationAnimation; + late Animation floatingAnimation; + + String selectedPeriod = 'Hari ini'; + final List periods = [ + 'Hari ini', + 'Minggu ini', + 'Bulan ini', + 'Tahun ini', + ]; + + @override + void initState() { + super.initState(); + + rotationAnimation = AnimationController( + duration: const Duration(seconds: 20), + vsync: this, + )..repeat(); + + floatingAnimation = AnimationController( + duration: const Duration(seconds: 3), + vsync: this, + )..repeat(reverse: true); + + _slideController = AnimationController( + duration: const Duration(milliseconds: 800), + vsync: this, + ); + + _fadeController = AnimationController( + duration: const Duration(milliseconds: 1000), + vsync: this, + ); + + _scaleController = AnimationController( + duration: const Duration(milliseconds: 600), + vsync: this, + ); + + _slideAnimation = + Tween(begin: const Offset(0, 0.3), end: Offset.zero).animate( + CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic), + ); + + _fadeAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation(parent: _fadeController, curve: Curves.easeIn)); + + _scaleAnimation = Tween(begin: 0.8, end: 1.0).animate( + CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut), + ); + + // Start animations + _fadeController.forward(); + Future.delayed(const Duration(milliseconds: 200), () { + _slideController.forward(); + }); + Future.delayed(const Duration(milliseconds: 400), () { + _scaleController.forward(); + }); + } + + @override + void dispose() { + _slideController.dispose(); + _fadeController.dispose(); + _scaleController.dispose(); + _rotationController.dispose(); + _floatingController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColor.background, + body: CustomScrollView( + slivers: [ + // SliverAppBar with animated background + SliverAppBar( + expandedHeight: 120, + floating: false, + pinned: true, + backgroundColor: AppColor.primary, + elevation: 0, + flexibleSpace: FinanceAppbar( + rotationAnimation: rotationAnimation, + floatingAnimation: floatingAnimation, + ), + ), + + // Header dengan filter periode + SliverToBoxAdapter( + child: FadeTransition( + opacity: _fadeAnimation, + child: _buildPeriodSelector(), + ), + ), + + // Summary Cards + SliverToBoxAdapter( + child: SlideTransition( + position: _slideAnimation, + child: _buildSummaryCards(), + ), + ), + + // Cash Flow Analysis + SliverToBoxAdapter( + child: ScaleTransition( + scale: _scaleAnimation, + child: FinanceCashFlow(), + ), + ), + + // Profit Loss Detail + SliverToBoxAdapter( + child: FadeTransition( + opacity: _fadeAnimation, + child: FinanceProfitLoss(), + ), + ), + + // Transaction Categories + SliverToBoxAdapter( + child: SlideTransition( + position: _slideAnimation, + child: FinanceCategory(), + ), + ), + + // Monthly Comparison + SliverToBoxAdapter( + child: ScaleTransition( + scale: _scaleAnimation, + child: _buildMonthlyComparison(), + ), + ), + + // Bottom spacing + const SliverToBoxAdapter(child: SizedBox(height: 100)), + ], + ), + ); + } + + Widget _buildPeriodSelector() { + return Container( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: selectedPeriod, + isExpanded: true, + icon: const Icon( + LineIcons.angleDown, + color: AppColor.primary, + ), + style: AppStyle.md, + items: periods.map((String period) { + return DropdownMenuItem( + value: period, + child: Text(period), + ); + }).toList(), + onChanged: (String? newValue) { + setState(() { + selectedPeriod = newValue!; + }); + }, + ), + ), + ), + ), + const SizedBox(width: 12), + Container( + decoration: BoxDecoration( + color: AppColor.primary, + borderRadius: BorderRadius.circular(12), + ), + child: IconButton( + onPressed: () {}, + icon: const Icon(LineIcons.calendar, color: AppColor.white), + ), + ), + ], + ), + ); + } + + Widget _buildSummaryCards() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: FinanceSummaryCard( + title: 'Total Pendapatan', + amount: 'Rp 25.840.000', + icon: LineIcons.arrowUp, + color: AppColor.success, + change: '+12.5%', + isPositive: true, + ), + ), + const SizedBox(width: 12), + Expanded( + child: FinanceSummaryCard( + title: 'Total Pengeluaran', + amount: 'Rp 18.320.000', + icon: LineIcons.arrowDown, + color: AppColor.error, + change: '+8.2%', + isPositive: false, + ), + ), + ], + ), + const SizedBox(height: 12), + Row( + children: [ + Expanded( + child: FinanceSummaryCard( + title: 'Keuntungan Bersih', + amount: 'Rp 7.520.000', + icon: LineIcons.lineChart, + color: AppColor.info, + change: '+15.3%', + isPositive: true, + ), + ), + const SizedBox(width: 12), + Expanded( + child: FinanceSummaryCard( + title: 'Margin Profit', + amount: '29.1%', + icon: LineIcons.percent, + color: AppColor.warning, + change: '+2.1%', + isPositive: true, + ), + ), + ], + ), + ], + ), + ); + } + + Widget _buildMonthlyComparison() { + return Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.textLight.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppColor.warning.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + LineIcons.calendarCheck, + color: AppColor.warning, + size: 20, + ), + ), + const SizedBox(width: 12), + Text( + 'Perbandingan Bulanan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + const SizedBox(height: 20), + + Row( + children: [ + Expanded( + child: _buildComparisonCard( + 'Bulan Ini', + 'Rp 7.52M', + '+15.3%', + true, + AppColor.primary, + ), + ), + const SizedBox(width: 12), + Expanded( + child: _buildComparisonCard( + 'Bulan Lalu', + 'Rp 6.53M', + '-2.1%', + false, + AppColor.textSecondary, + ), + ), + ], + ), + const SizedBox(height: 16), + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.success.withOpacity(0.05), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.success.withOpacity(0.2)), + ), + child: Row( + children: [ + const Icon( + LineIcons.thumbsUp, + color: AppColor.success, + size: 20, + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Performa Bagus!', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.success, + ), + ), + Text( + 'Keuntungan meningkat 15.3% dari bulan lalu', + style: AppStyle.sm.copyWith( + color: AppColor.textSecondary, + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildComparisonCard( + String period, + String amount, + String change, + bool isPositive, + Color color, + ) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: color.withOpacity(0.05), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: color.withOpacity(0.2)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + period, + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + const SizedBox(height: 8), + Text( + amount, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), + ), + const SizedBox(height: 4), + Row( + children: [ + Icon( + isPositive ? LineIcons.arrowUp : LineIcons.arrowDown, + size: 14, + color: isPositive ? AppColor.success : AppColor.error, + ), + const SizedBox(width: 4), + Text( + change, + style: AppStyle.xs.copyWith( + color: isPositive ? AppColor.success : AppColor.error, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/finance/widgets/appbar.dart b/lib/presentation/pages/finance/widgets/appbar.dart new file mode 100644 index 0000000..f37030f --- /dev/null +++ b/lib/presentation/pages/finance/widgets/appbar.dart @@ -0,0 +1,201 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; + +class FinanceAppbar extends StatelessWidget { + const FinanceAppbar({ + super.key, + required this.rotationAnimation, + required this.floatingAnimation, + }); + + final Animation rotationAnimation; + final Animation floatingAnimation; + + @override + Widget build(BuildContext context) { + return FlexibleSpaceBar( + titlePadding: const EdgeInsets.only(left: 50, bottom: 16), + title: Text( + 'Keuangan', + style: AppStyle.xl.copyWith( + color: AppColor.textWhite, + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + background: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: AppColor.primaryGradient, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: Stack( + children: [ + // Animated geometric shapes + Positioned( + right: -20, + top: -20, + child: AnimatedBuilder( + animation: Listenable.merge([ + rotationAnimation, + floatingAnimation, + ]), + builder: (context, child) { + return Transform.translate( + offset: Offset( + floatingAnimation.value * 10, + floatingAnimation.value * 15, + ), + child: Transform.rotate( + angle: rotationAnimation.value * 2 * 3.14159, + child: Container( + width: 120, + height: 120, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient( + colors: [ + AppColor.white.withOpacity(0.15), + AppColor.white.withOpacity(0.05), + ], + ), + boxShadow: [ + BoxShadow( + color: AppColor.white.withOpacity(0.1), + blurRadius: 20, + spreadRadius: 5, + ), + ], + ), + ), + ), + ); + }, + ), + ), + Positioned( + left: -30, + bottom: -30, + child: AnimatedBuilder( + animation: Listenable.merge([ + rotationAnimation, + floatingAnimation, + ]), + builder: (context, child) { + return Transform.translate( + offset: Offset( + -floatingAnimation.value * 8, + -floatingAnimation.value * 12, + ), + child: Transform.rotate( + angle: -rotationAnimation.value * 0.5 * 3.14159, + child: Container( + width: 100, + height: 100, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient( + colors: [ + AppColor.white.withOpacity(0.1), + AppColor.white.withOpacity(0.02), + ], + ), + ), + ), + ), + ); + }, + ), + ), + Positioned( + right: 80, + bottom: 30, + child: AnimatedBuilder( + animation: Listenable.merge([ + rotationAnimation, + floatingAnimation, + ]), + builder: (context, child) { + return Transform.translate( + offset: Offset( + floatingAnimation.value * 5, + -floatingAnimation.value * 8, + ), + child: Transform.rotate( + angle: -rotationAnimation.value * 0.3 * 3.14159, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + gradient: LinearGradient( + colors: [ + AppColor.white.withOpacity(0.12), + AppColor.white.withOpacity(0.04), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + ), + ), + ); + }, + ), + ), + // Additional floating elements + Positioned( + left: 60, + top: 80, + child: AnimatedBuilder( + animation: floatingAnimation, + builder: (context, child) { + return Transform.translate( + offset: Offset( + floatingAnimation.value * 3, + floatingAnimation.value * 6, + ), + child: Container( + width: 30, + height: 30, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.08), + ), + ), + ); + }, + ), + ), + Positioned( + right: 40, + top: 120, + child: AnimatedBuilder( + animation: floatingAnimation, + builder: (context, child) { + return Transform.translate( + offset: Offset( + -floatingAnimation.value * 4, + floatingAnimation.value * 7, + ), + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: AppColor.white.withOpacity(0.06), + ), + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/presentation/pages/finance/widgets/cash_flow.dart b/lib/presentation/pages/finance/widgets/cash_flow.dart new file mode 100644 index 0000000..5c45492 --- /dev/null +++ b/lib/presentation/pages/finance/widgets/cash_flow.dart @@ -0,0 +1,397 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:line_icons/line_icons.dart'; + +import '../../../../common/theme/theme.dart'; + +class FinanceCashFlow extends StatelessWidget { + const FinanceCashFlow({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.textLight.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: AppColor.primaryGradient, + ), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + LineIcons.areaChart, + color: AppColor.white, + size: 20, + ), + ), + const SizedBox(width: 12), + Text( + 'Analisis Cash Flow', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + IconButton( + onPressed: () {}, + icon: const Icon( + LineIcons.alternateExternalLink, + color: AppColor.primary, + ), + ), + ], + ), + const SizedBox(height: 20), + + // Cash Flow Indicators + Row( + children: [ + Expanded( + child: _buildCashFlowIndicator( + 'Cash In', + 'Rp 28.5M', + LineIcons.arrowUp, + AppColor.success, + ), + ), + const SizedBox(width: 16), + Expanded( + child: _buildCashFlowIndicator( + 'Cash Out', + 'Rp 21.2M', + LineIcons.arrowDown, + AppColor.error, + ), + ), + const SizedBox(width: 16), + Expanded( + child: _buildCashFlowIndicator( + 'Net Flow', + 'Rp 7.3M', + LineIcons.equals, + AppColor.info, + ), + ), + ], + ), + const SizedBox(height: 20), + + // FL Chart Implementation + Container( + height: 200, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.borderLight), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Grafik Cash Flow 7 Hari Terakhir', + style: AppStyle.sm.copyWith( + color: AppColor.textSecondary, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 16), + Expanded( + child: LineChart( + LineChartData( + gridData: FlGridData( + show: true, + drawVerticalLine: false, + horizontalInterval: 5000000, // 5M interval + getDrawingHorizontalLine: (value) { + return FlLine( + color: AppColor.borderLight, + strokeWidth: 1, + ); + }, + ), + titlesData: FlTitlesData( + show: true, + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 30, + interval: 1, + getTitlesWidget: (double value, TitleMeta meta) { + const style = TextStyle( + color: AppColor.textSecondary, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + Widget text; + switch (value.toInt()) { + case 0: + text = const Text('Sen', style: style); + break; + case 1: + text = const Text('Sel', style: style); + break; + case 2: + text = const Text('Rab', style: style); + break; + case 3: + text = const Text('Kam', style: style); + break; + case 4: + text = const Text('Jum', style: style); + break; + case 5: + text = const Text('Sab', style: style); + break; + case 6: + text = const Text('Min', style: style); + break; + default: + text = const Text('', style: style); + break; + } + return SideTitleWidget(meta: meta, child: text); + }, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: 10000000, // 10M interval + reservedSize: 42, + getTitlesWidget: (double value, TitleMeta meta) { + return Text( + '${(value / 1000000).toInt()}M', + style: const TextStyle( + color: AppColor.textSecondary, + fontWeight: FontWeight.w500, + fontSize: 10, + ), + textAlign: TextAlign.left, + ); + }, + ), + ), + ), + borderData: FlBorderData( + show: true, + border: Border.all(color: AppColor.borderLight), + ), + minX: 0, + maxX: 6, + minY: -5000000, + maxY: 30000000, + lineBarsData: [ + // Cash In Line + LineChartBarData( + spots: const [ + FlSpot(0, 25000000), // Monday + FlSpot(1, 22000000), // Tuesday + FlSpot(2, 28000000), // Wednesday + FlSpot(3, 24000000), // Thursday + FlSpot(4, 30000000), // Friday + FlSpot(5, 18000000), // Saturday + FlSpot(6, 26000000), // Sunday + ], + isCurved: true, + gradient: LinearGradient( + colors: [ + AppColor.success.withOpacity(0.8), + AppColor.success, + ], + ), + barWidth: 3, + isStrokeCapRound: true, + dotData: FlDotData( + show: true, + getDotPainter: (spot, percent, barData, index) { + return FlDotCirclePainter( + radius: 4, + color: AppColor.success, + strokeWidth: 2, + strokeColor: AppColor.white, + ); + }, + ), + belowBarData: BarAreaData( + show: true, + gradient: LinearGradient( + colors: [ + AppColor.success.withOpacity(0.1), + AppColor.success.withOpacity(0.0), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + ), + // Cash Out Line + LineChartBarData( + spots: const [ + FlSpot(0, 20000000), // Monday + FlSpot(1, 18000000), // Tuesday + FlSpot(2, 23000000), // Wednesday + FlSpot(3, 19000000), // Thursday + FlSpot(4, 25000000), // Friday + FlSpot(5, 15000000), // Saturday + FlSpot(6, 21000000), // Sunday + ], + isCurved: true, + gradient: LinearGradient( + colors: [ + AppColor.error.withOpacity(0.8), + AppColor.error, + ], + ), + barWidth: 3, + isStrokeCapRound: true, + dotData: FlDotData( + show: true, + getDotPainter: (spot, percent, barData, index) { + return FlDotCirclePainter( + radius: 4, + color: AppColor.error, + strokeWidth: 2, + strokeColor: AppColor.white, + ); + }, + ), + ), + // Net Flow Line + LineChartBarData( + spots: const [ + FlSpot(0, 5000000), // Monday + FlSpot(1, 4000000), // Tuesday + FlSpot(2, 5000000), // Wednesday + FlSpot(3, 5000000), // Thursday + FlSpot(4, 5000000), // Friday + FlSpot(5, 3000000), // Saturday + FlSpot(6, 5000000), // Sunday + ], + isCurved: true, + gradient: LinearGradient( + colors: [ + AppColor.info.withOpacity(0.8), + AppColor.info, + ], + ), + barWidth: 3, + isStrokeCapRound: true, + dotData: FlDotData( + show: true, + getDotPainter: (spot, percent, barData, index) { + return FlDotCirclePainter( + radius: 4, + color: AppColor.info, + strokeWidth: 2, + strokeColor: AppColor.white, + ); + }, + ), + ), + ], + ), + ), + ), + const SizedBox(height: 12), + // Legend + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildChartLegend('Cash In', AppColor.success), + const SizedBox(width: 20), + _buildChartLegend('Cash Out', AppColor.error), + const SizedBox(width: 20), + _buildChartLegend('Net Flow', AppColor.info), + ], + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildChartLegend(String label, Color color) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration(color: color, shape: BoxShape.circle), + ), + const SizedBox(width: 6), + Text( + label, + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontWeight: FontWeight.w500, + ), + ), + ], + ); + } + + Widget _buildCashFlowIndicator( + String label, + String amount, + IconData icon, + Color color, + ) { + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: color.withOpacity(0.05), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: color.withOpacity(0.2)), + ), + child: Column( + children: [ + Icon(icon, color: color, size: 20), + const SizedBox(height: 8), + Text( + label, + style: AppStyle.xs.copyWith(color: AppColor.textSecondary), + ), + const SizedBox(height: 4), + Text( + amount, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/finance/widgets/category.dart b/lib/presentation/pages/finance/widgets/category.dart new file mode 100644 index 0000000..7c18f38 --- /dev/null +++ b/lib/presentation/pages/finance/widgets/category.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:line_icons/line_icons.dart'; + +import '../../../../common/theme/theme.dart'; + +class FinanceCategory extends StatelessWidget { + const FinanceCategory({super.key}); + + @override + Widget build(BuildContext context) { + final categories = [ + { + 'name': 'Makanan & Minuman', + 'amount': 'Rp 18.5M', + 'percentage': 72, + 'color': AppColor.primary, + }, + { + 'name': 'Produk Retail', + 'amount': 'Rp 4.2M', + 'percentage': 16, + 'color': AppColor.secondary, + }, + { + 'name': 'Jasa & Lainnya', + 'amount': 'Rp 3.1M', + 'percentage': 12, + 'color': AppColor.info, + }, + ]; + + return Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.textLight.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppColor.secondary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + LineIcons.pieChart, + color: AppColor.secondary, + size: 20, + ), + ), + const SizedBox(width: 12), + Text( + 'Kategori Penjualan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + const SizedBox(height: 20), + + ...categories + .map( + (category) => _buildCategoryItem( + category['name'] as String, + category['amount'] as String, + category['percentage'] as int, + category['color'] as Color, + ), + ) + .toList(), + ], + ), + ); + } + + Widget _buildCategoryItem( + String name, + String amount, + int percentage, + Color color, + ) { + return Container( + margin: const EdgeInsets.only(bottom: 16), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(6), + ), + ), + const SizedBox(width: 12), + Text( + name, + style: AppStyle.md.copyWith(fontWeight: FontWeight.w600), + ), + ], + ), + Text( + amount, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), + ), + ], + ), + const SizedBox(height: 8), + LinearProgressIndicator( + value: percentage / 100, + backgroundColor: AppColor.borderLight, + valueColor: AlwaysStoppedAnimation(color), + minHeight: 6, + ), + const SizedBox(height: 4), + Align( + alignment: Alignment.centerRight, + child: Text( + '$percentage%', + style: AppStyle.xs.copyWith(color: AppColor.textSecondary), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/finance/widgets/profit_loss.dart b/lib/presentation/pages/finance/widgets/profit_loss.dart new file mode 100644 index 0000000..a3fa885 --- /dev/null +++ b/lib/presentation/pages/finance/widgets/profit_loss.dart @@ -0,0 +1,158 @@ +import 'package:flutter/material.dart'; +import 'package:line_icons/line_icons.dart'; + +import '../../../../common/theme/theme.dart'; + +class FinanceProfitLoss extends StatelessWidget { + const FinanceProfitLoss({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.textLight.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppColor.info.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + LineIcons.calculator, + color: AppColor.info, + size: 20, + ), + ), + const SizedBox(width: 12), + Text( + 'Detail Profit & Loss', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + const SizedBox(height: 20), + + _buildPLItem( + 'Penjualan Kotor', + 'Rp 25.840.000', + AppColor.success, + true, + ), + _buildPLItem('Diskon & Retur', '- Rp 560.000', AppColor.error, false), + const Divider(height: 24), + _buildPLItem( + 'Penjualan Bersih', + 'Rp 25.280.000', + AppColor.textPrimary, + true, + isHeader: true, + ), + const SizedBox(height: 12), + _buildPLItem( + 'HPP (Harga Pokok Penjualan)', + '- Rp 15.120.000', + AppColor.error, + false, + ), + const Divider(height: 24), + _buildPLItem( + 'Laba Kotor', + 'Rp 10.160.000', + AppColor.success, + true, + isHeader: true, + ), + const SizedBox(height: 12), + _buildPLItem( + 'Biaya Operasional', + '- Rp 2.640.000', + AppColor.error, + false, + ), + const Divider(height: 24), + _buildPLItem( + 'Laba Bersih', + 'Rp 7.520.000', + AppColor.primary, + true, + isHeader: true, + showPercentage: true, + percentage: '29.8%', + ), + ], + ), + ); + } + + Widget _buildPLItem( + String title, + String amount, + Color color, + bool isPositive, { + bool isHeader = false, + bool showPercentage = false, + String? percentage, + }) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + title, + style: isHeader + ? AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: color, + ) + : AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + amount, + style: isHeader + ? AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: color, + ) + : AppStyle.md.copyWith( + color: color, + fontWeight: FontWeight.w600, + ), + ), + if (showPercentage && percentage != null) + Text( + percentage, + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontStyle: FontStyle.italic, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/finance/widgets/summary_card.dart b/lib/presentation/pages/finance/widgets/summary_card.dart new file mode 100644 index 0000000..94689d3 --- /dev/null +++ b/lib/presentation/pages/finance/widgets/summary_card.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; + +class FinanceSummaryCard extends StatelessWidget { + const FinanceSummaryCard({ + super.key, + required this.title, + required this.amount, + required this.icon, + required this.color, + required this.change, + required this.isPositive, + }); + + final String title; + final String amount; + final IconData icon; + final Color color; + final String change; + final bool isPositive; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.textLight.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, color: color, size: 20), + ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: isPositive + ? AppColor.success.withOpacity(0.1) + : AppColor.error.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + change, + style: AppStyle.xs.copyWith( + color: isPositive ? AppColor.success : AppColor.error, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + const SizedBox(height: 12), + Text( + title, + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + const SizedBox(height: 4), + Text( + amount, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/home/widgets/feature.dart b/lib/presentation/pages/home/widgets/feature.dart index 0df4dcd..4d4f998 100644 --- a/lib/presentation/pages/home/widgets/feature.dart +++ b/lib/presentation/pages/home/widgets/feature.dart @@ -48,10 +48,10 @@ class HomeFeature extends StatelessWidget { onTap: () => context.router.push(PurchaseRoute()), ), HomeFeatureTile( - title: 'Biaya', + title: 'Keuangan', color: const Color(0xFF8BC34A), icon: LineIcons.moneyCheck, - onTap: () {}, + onTap: () => context.router.push(FinanceRoute()), ), HomeFeatureTile( title: 'Produk', diff --git a/lib/presentation/pages/purchase/purchase_page.dart b/lib/presentation/pages/purchase/purchase_page.dart index 5704ee1..d5dbdd8 100644 --- a/lib/presentation/pages/purchase/purchase_page.dart +++ b/lib/presentation/pages/purchase/purchase_page.dart @@ -1,131 +1,16 @@ +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:line_icons/line_icons.dart'; +import '../../../common/theme/theme.dart'; import 'widgets/appbar.dart'; import 'widgets/purchase_tile.dart'; import 'widgets/stat_card.dart'; import 'widgets/status_chip.dart'; -// AppColor class (sesuai dengan yang Anda berikan) -class AppColor { - // Primary Colors - static const Color primary = Color(0xFF36175e); - static const Color primaryLight = Color(0xFF5a2d85); - static const Color primaryDark = Color(0xFF1e0d35); - - // Secondary Colors - static const Color secondary = Color(0xFF4CAF50); - static const Color secondaryLight = Color(0xFF81C784); - static const Color secondaryDark = Color(0xFF388E3C); - - // Background Colors - static const Color background = Color(0xFFF8F9FA); - static const Color backgroundLight = Color(0xFFFFFFFF); - static const Color backgroundDark = Color(0xFF1A1A1A); - static const Color surface = Color(0xFFFFFFFF); - static const Color surfaceDark = Color(0xFF2D2D2D); - - // Text Colors - static const Color textPrimary = Color(0xFF212121); - static const Color textSecondary = Color(0xFF757575); - static const Color textLight = Color(0xFFBDBDBD); - static const Color textWhite = Color(0xFFFFFFFF); - - // Status Colors - static const Color success = Color(0xFF4CAF50); - static const Color error = Color(0xFFE53E3E); - static const Color warning = Color(0xFFFF9800); - static const Color info = Color(0xFF2196F3); - - // Border Colors - static const Color border = Color(0xFFE0E0E0); - static const Color borderLight = Color(0xFFF0F0F0); - static const Color borderDark = Color(0xFFBDBDBD); - - // Basic Color - static const Color white = Color(0xFFFFFFFF); - static const Color black = Color(0xFF000000); - - // Gradient Colors - static const List primaryGradient = [ - Color(0xFF36175e), - Color(0xFF5a2d85), - ]; - - static const List successGradient = [ - Color(0xFF4CAF50), - Color(0xFF81C784), - ]; - - static const List backgroundGradient = [ - Color(0xFFF5F5F5), - Color(0xFFE8E8E8), - ]; - - // Opacity Variations - static Color primaryWithOpacity(double opacity) => - primary.withOpacity(opacity); - static Color successWithOpacity(double opacity) => - success.withOpacity(opacity); - static Color errorWithOpacity(double opacity) => error.withOpacity(opacity); - static Color warningWithOpacity(double opacity) => - warning.withOpacity(opacity); -} - -// AppStyle class (sesuai dengan yang Anda berikan) -class AppStyle { - static TextStyle xs = const TextStyle( - color: AppColor.textPrimary, - fontSize: 11, - ); - static TextStyle sm = const TextStyle( - color: AppColor.textPrimary, - fontSize: 12, - ); - static TextStyle md = const TextStyle( - color: AppColor.textPrimary, - fontSize: 14, - ); - static TextStyle lg = const TextStyle( - color: AppColor.textPrimary, - fontSize: 16, - ); - static TextStyle xl = const TextStyle( - color: AppColor.textPrimary, - fontSize: 18, - ); - static TextStyle xxl = const TextStyle( - color: AppColor.textPrimary, - fontSize: 20, - ); - static TextStyle h6 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 22, - ); - static TextStyle h5 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 24, - ); - static TextStyle h4 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 26, - ); - static TextStyle h3 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 28, - ); - static TextStyle h2 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 30, - ); - static TextStyle h1 = const TextStyle( - color: AppColor.textPrimary, - fontSize: 32, - ); -} - +@RoutePage() class PurchasePage extends StatefulWidget { - const PurchasePage({Key? key}) : super(key: key); + const PurchasePage({super.key}); @override State createState() => _PurchasePageState(); diff --git a/lib/presentation/router/app_router.dart b/lib/presentation/router/app_router.dart index 13d1984..8158193 100644 --- a/lib/presentation/router/app_router.dart +++ b/lib/presentation/router/app_router.dart @@ -45,5 +45,8 @@ class AppRouter extends RootStackRouter { // Purchase page AutoRoute(page: PurchaseRoute.page), + + // Finance page + AutoRoute(page: FinanceRoute.page), ]; } diff --git a/lib/presentation/router/app_router.gr.dart b/lib/presentation/router/app_router.gr.dart index 83010ff..a530708 100644 --- a/lib/presentation/router/app_router.gr.dart +++ b/lib/presentation/router/app_router.gr.dart @@ -10,46 +10,48 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart' - as _i6; + as _i7; import 'package:apskel_owner_flutter/presentation/pages/customer/customer_page.dart' as _i1; +import 'package:apskel_owner_flutter/presentation/pages/finance/finance_page.dart' + as _i3; import 'package:apskel_owner_flutter/presentation/pages/form/daily_task_form_page.dart' as _i2; import 'package:apskel_owner_flutter/presentation/pages/home/home_page.dart' - as _i3; -import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart' as _i4; -import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/inventory/inventory_page.dart' as _i5; +import 'package:apskel_owner_flutter/presentation/pages/language/language_page.dart' + as _i6; import 'package:apskel_owner_flutter/presentation/pages/main/main_page.dart' - as _i7; -import 'package:apskel_owner_flutter/presentation/pages/product/product_page.dart' as _i8; -import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/product/product_page.dart' as _i9; -import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart' as _i10; -import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart' as _i11; -import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart' as _i12; -import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart' as _i13; -import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart' as _i14; -import 'package:apskel_owner_flutter/presentation/pages/transaction/transaction_page.dart' +import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart' as _i15; -import 'package:auto_route/auto_route.dart' as _i16; +import 'package:apskel_owner_flutter/presentation/pages/transaction/transaction_page.dart' + as _i16; +import 'package:auto_route/auto_route.dart' as _i17; /// generated route for /// [_i1.CustomerPage] -class CustomerRoute extends _i16.PageRouteInfo { - const CustomerRoute({List<_i16.PageRouteInfo>? children}) +class CustomerRoute extends _i17.PageRouteInfo { + const CustomerRoute({List<_i17.PageRouteInfo>? children}) : super(CustomerRoute.name, initialChildren: children); static const String name = 'CustomerRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { return const _i1.CustomerPage(); @@ -59,13 +61,13 @@ class CustomerRoute extends _i16.PageRouteInfo { /// generated route for /// [_i2.DailyTasksFormPage] -class DailyTasksFormRoute extends _i16.PageRouteInfo { - const DailyTasksFormRoute({List<_i16.PageRouteInfo>? children}) +class DailyTasksFormRoute extends _i17.PageRouteInfo { + const DailyTasksFormRoute({List<_i17.PageRouteInfo>? children}) : super(DailyTasksFormRoute.name, initialChildren: children); static const String name = 'DailyTasksFormRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { return const _i2.DailyTasksFormPage(); @@ -74,209 +76,225 @@ class DailyTasksFormRoute extends _i16.PageRouteInfo { } /// generated route for -/// [_i3.HomePage] -class HomeRoute extends _i16.PageRouteInfo { - const HomeRoute({List<_i16.PageRouteInfo>? children}) +/// [_i3.FinancePage] +class FinanceRoute extends _i17.PageRouteInfo { + const FinanceRoute({List<_i17.PageRouteInfo>? children}) + : super(FinanceRoute.name, initialChildren: children); + + static const String name = 'FinanceRoute'; + + static _i17.PageInfo page = _i17.PageInfo( + name, + builder: (data) { + return const _i3.FinancePage(); + }, + ); +} + +/// generated route for +/// [_i4.HomePage] +class HomeRoute extends _i17.PageRouteInfo { + const HomeRoute({List<_i17.PageRouteInfo>? children}) : super(HomeRoute.name, initialChildren: children); static const String name = 'HomeRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i3.HomePage(); + return const _i4.HomePage(); }, ); } /// generated route for -/// [_i4.InventoryPage] -class InventoryRoute extends _i16.PageRouteInfo { - const InventoryRoute({List<_i16.PageRouteInfo>? children}) +/// [_i5.InventoryPage] +class InventoryRoute extends _i17.PageRouteInfo { + const InventoryRoute({List<_i17.PageRouteInfo>? children}) : super(InventoryRoute.name, initialChildren: children); static const String name = 'InventoryRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i4.InventoryPage(); + return const _i5.InventoryPage(); }, ); } /// generated route for -/// [_i5.LanguagePage] -class LanguageRoute extends _i16.PageRouteInfo { - const LanguageRoute({List<_i16.PageRouteInfo>? children}) +/// [_i6.LanguagePage] +class LanguageRoute extends _i17.PageRouteInfo { + const LanguageRoute({List<_i17.PageRouteInfo>? children}) : super(LanguageRoute.name, initialChildren: children); static const String name = 'LanguageRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i5.LanguagePage(); + return const _i6.LanguagePage(); }, ); } /// generated route for -/// [_i6.LoginPage] -class LoginRoute extends _i16.PageRouteInfo { - const LoginRoute({List<_i16.PageRouteInfo>? children}) +/// [_i7.LoginPage] +class LoginRoute extends _i17.PageRouteInfo { + const LoginRoute({List<_i17.PageRouteInfo>? children}) : super(LoginRoute.name, initialChildren: children); static const String name = 'LoginRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i6.LoginPage(); + return const _i7.LoginPage(); }, ); } /// generated route for -/// [_i7.MainPage] -class MainRoute extends _i16.PageRouteInfo { - const MainRoute({List<_i16.PageRouteInfo>? children}) +/// [_i8.MainPage] +class MainRoute extends _i17.PageRouteInfo { + const MainRoute({List<_i17.PageRouteInfo>? children}) : super(MainRoute.name, initialChildren: children); static const String name = 'MainRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i7.MainPage(); + return const _i8.MainPage(); }, ); } /// generated route for -/// [_i8.ProductPage] -class ProductRoute extends _i16.PageRouteInfo { - const ProductRoute({List<_i16.PageRouteInfo>? children}) +/// [_i9.ProductPage] +class ProductRoute extends _i17.PageRouteInfo { + const ProductRoute({List<_i17.PageRouteInfo>? children}) : super(ProductRoute.name, initialChildren: children); static const String name = 'ProductRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i8.ProductPage(); + return const _i9.ProductPage(); }, ); } /// generated route for -/// [_i9.ProfilePage] -class ProfileRoute extends _i16.PageRouteInfo { - const ProfileRoute({List<_i16.PageRouteInfo>? children}) +/// [_i10.ProfilePage] +class ProfileRoute extends _i17.PageRouteInfo { + const ProfileRoute({List<_i17.PageRouteInfo>? children}) : super(ProfileRoute.name, initialChildren: children); static const String name = 'ProfileRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i9.ProfilePage(); + return const _i10.ProfilePage(); }, ); } /// generated route for -/// [_i10.PurchasePage] -class PurchaseRoute extends _i16.PageRouteInfo { - const PurchaseRoute({List<_i16.PageRouteInfo>? children}) +/// [_i11.PurchasePage] +class PurchaseRoute extends _i17.PageRouteInfo { + const PurchaseRoute({List<_i17.PageRouteInfo>? children}) : super(PurchaseRoute.name, initialChildren: children); static const String name = 'PurchaseRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i10.PurchasePage(); + return const _i11.PurchasePage(); }, ); } /// generated route for -/// [_i11.ReportPage] -class ReportRoute extends _i16.PageRouteInfo { - const ReportRoute({List<_i16.PageRouteInfo>? children}) +/// [_i12.ReportPage] +class ReportRoute extends _i17.PageRouteInfo { + const ReportRoute({List<_i17.PageRouteInfo>? children}) : super(ReportRoute.name, initialChildren: children); static const String name = 'ReportRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i11.ReportPage(); + return const _i12.ReportPage(); }, ); } /// generated route for -/// [_i12.SalesPage] -class SalesRoute extends _i16.PageRouteInfo { - const SalesRoute({List<_i16.PageRouteInfo>? children}) +/// [_i13.SalesPage] +class SalesRoute extends _i17.PageRouteInfo { + const SalesRoute({List<_i17.PageRouteInfo>? children}) : super(SalesRoute.name, initialChildren: children); static const String name = 'SalesRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i12.SalesPage(); + return const _i13.SalesPage(); }, ); } /// generated route for -/// [_i13.SchedulePage] -class ScheduleRoute extends _i16.PageRouteInfo { - const ScheduleRoute({List<_i16.PageRouteInfo>? children}) +/// [_i14.SchedulePage] +class ScheduleRoute extends _i17.PageRouteInfo { + const ScheduleRoute({List<_i17.PageRouteInfo>? children}) : super(ScheduleRoute.name, initialChildren: children); static const String name = 'ScheduleRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i13.SchedulePage(); + return const _i14.SchedulePage(); }, ); } /// generated route for -/// [_i14.SplashPage] -class SplashRoute extends _i16.PageRouteInfo { - const SplashRoute({List<_i16.PageRouteInfo>? children}) +/// [_i15.SplashPage] +class SplashRoute extends _i17.PageRouteInfo { + const SplashRoute({List<_i17.PageRouteInfo>? children}) : super(SplashRoute.name, initialChildren: children); static const String name = 'SplashRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i14.SplashPage(); + return const _i15.SplashPage(); }, ); } /// generated route for -/// [_i15.TransactionPage] -class TransactionRoute extends _i16.PageRouteInfo { - const TransactionRoute({List<_i16.PageRouteInfo>? children}) +/// [_i16.TransactionPage] +class TransactionRoute extends _i17.PageRouteInfo { + const TransactionRoute({List<_i17.PageRouteInfo>? children}) : super(TransactionRoute.name, initialChildren: children); static const String name = 'TransactionRoute'; - static _i16.PageInfo page = _i16.PageInfo( + static _i17.PageInfo page = _i17.PageInfo( name, builder: (data) { - return const _i15.TransactionPage(); + return const _i16.TransactionPage(); }, ); }