import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:lba/gen/assets.gen.dart'; import 'package:lba/res/colors.dart'; import 'package:lba/screens/product/checkout.dart'; class ReserveBottomSheet extends StatefulWidget { const ReserveBottomSheet({super.key}); @override State createState() => _ReserveBottomSheetState(); } class _ReserveBottomSheetState extends State { int _quantity = 1; final double _pricePerItem = 27.900; final bool _isHotDeal = false; void _incrementQuantity() { if (_isHotDeal) return; setState(() { _quantity++; }); } void _decrementQuantity() { if (_quantity <= 1) return; setState(() { _quantity--; }); } @override Widget build(BuildContext context) { final subtotal = _pricePerItem * _quantity; const salesTax = 0.000; final total = subtotal + salesTax; return Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 40, height: 4, margin: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: AppColors.greyBorder, borderRadius: BorderRadius.circular(10), ), ), Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 20), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), decoration: BoxDecoration( color: AppColors.deliverySelectedButton, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(), const SizedBox(height: 16), Divider(color: AppColors.divider, thickness: 1), const SizedBox(height: 16), _buildPriceDetails(subtotal, salesTax, total), const SizedBox(height: 24), _buildFooter(), ], ), ), ), ], ), ); } Widget _buildHeader() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ SvgPicture.asset(Assets.icons.shop.path, height: 22, color: AppColors.textSecondary), const SizedBox(width: 10), const Text( "Al Rawabi Dairy Company L.L.C", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), ], ), const SizedBox(height: 8), Padding( padding: EdgeInsets.only(left: 4.0), child: Text( "Philadelphia Honey Pecan Cream Cheese Spread,\n7.5 oz Tub", style: TextStyle(fontSize: 14, color: AppColors.textPrimary, height: 1.4), ), ), const SizedBox(height: 6), Padding( padding: EdgeInsets.only(left: 4.0), child: Text( "Pickup Now - 10:00 PM Today", style: TextStyle(fontSize: 13, color: AppColors.textSecondary), ), ), ], ); } Widget _buildPriceDetails(double subtotal, double salesTax, double total) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( "Price Details", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16), ), Text( "$_quantity Item", style: TextStyle(fontSize: 14, color: AppColors.textSecondary), ), ], ), const SizedBox(height: 12), DashedLine(), const SizedBox(height: 12), _priceRow("Subtotal", subtotal.toStringAsFixed(3)), const SizedBox(height: 10), _priceRow("Sales tax", salesTax.toStringAsFixed(3)), const SizedBox(height: 12), DashedLine(), const SizedBox(height: 12), _priceRow("Total", total.toStringAsFixed(3), isTotal: true), ], ); } Widget _buildFooter() { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildQuantitySelector(), ElevatedButton( onPressed: () { Navigator.pop(context); Navigator.of(context).push( PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => const CheckoutPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin = Offset(0.0, 1.0); const end = Offset.zero; const curve = Curves.easeInOut; final tween = Tween(begin: begin, end: end) .chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ), ); }, style: ElevatedButton.styleFrom( backgroundColor: AppColors.offerTimer, foregroundColor: AppColors.surface, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.symmetric(horizontal: 65, vertical: 10), ), child: const Text( 'Reserve', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ], ), if (_isHotDeal) ...[ const SizedBox(height: 16), _buildWarningMessage(), ] ], ); } Widget _priceRow(String label, String amount, {bool isTotal = false}) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: TextStyle( fontSize: 15, fontWeight: isTotal ? FontWeight.bold : FontWeight.normal, color: AppColors.textSecondary, ), ), Text( "AED $amount", style: TextStyle( fontSize: 15, fontWeight: isTotal ? FontWeight.bold : FontWeight.w500, color: AppColors.textPrimary, ), ), ], ); } Widget _buildQuantitySelector() { final bool canDecrement = _quantity > 1; final bool canIncrement = !_isHotDeal; return Container( height: 45, decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(10), ), child: Row( children: [ IconButton( icon: Icon(Icons.remove, color: canDecrement ? AppColors.errorColor : AppColors.textSecondary), onPressed: _decrementQuantity, splashRadius: 20, ), Text( _quantity.toString(), style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), IconButton( icon: Icon(Icons.add, color: canIncrement ? AppColors.errorColor : AppColors.textSecondary), onPressed: _incrementQuantity, splashRadius: 20, ), ], ), ); } Widget _buildWarningMessage() { return Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.error, color: AppColors.offerTimer, size: 20), const SizedBox(width: 10), Expanded( child: RichText( text: TextSpan( style: TextStyle( fontSize: 12.5, color: AppColors.textSecondary, fontFamily: 'Roboto'), children: const [ TextSpan(text: "Due to the "), TextSpan( text: "Hot", style: TextStyle(fontWeight: FontWeight.bold), ), TextSpan( text: " label discount, you can only purchase or reserve one item."), ], ), ), ), ], ); } } class DashedLine extends StatelessWidget { DashedLine({super.key, this.height = 1, Color? color}) : color = color ?? AppColors.divider; final double height; final Color color; @override Widget build(BuildContext context) { return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { final boxWidth = constraints.constrainWidth(); const dashWidth = 5.0; final dashHeight = height; final dashCount = (boxWidth / (2 * dashWidth)).floor(); return Flex( mainAxisAlignment: MainAxisAlignment.spaceBetween, direction: Axis.horizontal, children: List.generate(dashCount, (_) { return SizedBox( width: dashWidth, height: dashHeight, child: DecoratedBox( decoration: BoxDecoration(color: color), ), ); }), ); }, ); } }