import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_dimens.dart'; import '../../../core/utils/formatters.dart'; import '../../../core/widgets/primary_button.dart'; import '../../../domain/entities/cart.dart'; import '../providers/cart_controller.dart'; Future showLineDiscountSheet( BuildContext context, WidgetRef ref, CartLine line, ) { return _show( context: context, title: line.product.name, subtitle: 'Line value ${Formatters.money(line.grossAmount)}', current: line.discount, onApply: (d) => ref .read(cartControllerProvider.notifier) .applyLineDiscount(line.product.id, d), ); } Future showBillDiscountSheet(BuildContext context, WidgetRef ref) { final cart = ref.read(cartControllerProvider); return _show( context: context, title: 'Bill discount', subtitle: 'Subtotal ${Formatters.money(cart.subtotal)}', current: cart.billDiscount, onApply: (d) => ref.read(cartControllerProvider.notifier).applyBillDiscount(d), ); } Future _show({ required BuildContext context, required String title, required String subtitle, required Discount current, required ValueChanged onApply, }) { return showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => _DiscountSheet( title: title, subtitle: subtitle, current: current, onApply: onApply, ), ); } class _DiscountSheet extends StatefulWidget { const _DiscountSheet({ required this.title, required this.subtitle, required this.current, required this.onApply, }); final String title; final String subtitle; final Discount current; final ValueChanged onApply; @override State<_DiscountSheet> createState() => _DiscountSheetState(); } class _DiscountSheetState extends State<_DiscountSheet> { late DiscountType _type = widget.current.type == DiscountType.none ? DiscountType.percentage : widget.current.type; late final TextEditingController _value = TextEditingController( text: widget.current.isActive ? widget.current.value.toStringAsFixed(0) : '', ); @override void dispose() { _value.dispose(); super.dispose(); } void _apply() { final v = double.tryParse(_value.text.trim()) ?? 0; widget.onApply( v <= 0 ? Discount.none : Discount(type: _type, value: v), ); Navigator.of(context).pop(); } @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.only( bottom: MediaQuery.viewInsetsOf(context).bottom, ), child: Container( padding: const EdgeInsets.all(AppSpacing.xxl), decoration: const BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.vertical(top: Radius.circular(AppRadius.xxl)), ), child: Column(mainAxisSize: MainAxisSize.min, children: [ Container( width: 40, height: 4, decoration: const BoxDecoration( color: AppColors.border, borderRadius: AppRadius.brPill, ), ), const SizedBox(height: AppSpacing.xl), Text(widget.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),), const SizedBox(height: 2), Text(widget.subtitle, style: const TextStyle( fontSize: 13, color: AppColors.textSecondary, ),), const SizedBox(height: AppSpacing.xxl), SegmentedButton( segments: const [ ButtonSegment( value: DiscountType.percentage, label: Text('Percent'), icon: Icon(Icons.percent_rounded, size: 17), ), ButtonSegment( value: DiscountType.flat, label: Text('Flat'), icon: Icon(Icons.currency_rupee_rounded, size: 17), ), ], selected: {_type}, onSelectionChanged: (s) => setState(() => _type = s.first), ), const SizedBox(height: AppSpacing.xl), TextField( controller: _value, autofocus: true, keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')), ], style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w700), textAlign: TextAlign.center, decoration: InputDecoration( hintText: '0', prefixText: _type == DiscountType.flat ? '₹ ' : null, suffixText: _type == DiscountType.percentage ? '%' : null, ), onSubmitted: (_) => _apply(), ), const SizedBox(height: AppSpacing.lg), Wrap( spacing: AppSpacing.sm, children: (_type == DiscountType.percentage ? const [5, 10, 15, 20, 25] : const [10, 20, 50, 100, 200]) .map((v) => ActionChip( label: Text(_type == DiscountType.percentage ? '$v%' : '₹$v',), onPressed: () => setState(() => _value.text = v.toString()), ),) .toList(), ), const SizedBox(height: AppSpacing.xxl), Row(children: [ Expanded( child: PrimaryButton( label: 'Remove', tone: ButtonTone.neutral, onPressed: () { widget.onApply(Discount.none); Navigator.of(context).pop(); }, ), ), const SizedBox(width: AppSpacing.md), Expanded( flex: 2, child: PrimaryButton( label: 'Apply discount', icon: Icons.check_rounded, onPressed: _apply, ), ), ],), ],), ), ); } }