import 'package:flutter/material.dart'; import 'package:supplier_new/common/settings.dart'; class SetRatesScreen extends StatefulWidget { const SetRatesScreen({super.key}); @override State createState() => _SetRatesScreenState(); } class _SetRatesScreenState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final Map controllers = {}; // Define categories + tankers final Map> tankerGroups = {}; final Map deliveryControllers = {}; /*delivery fee controllers*/ final TextEditingController pumpFeeController = TextEditingController(); final List> data = [ {"category": "DRINKING WATER", "size": "5,000L", "price": "12"}, {"category": "DRINKING WATER", "size": "15,000L", "price": "18"}, {"category": "DRINKING WATER", "size": "20,000L", "price": "20"}, {"category": "BORE WATER", "size": "5,000L", "price": "10"}, {"category": "BORE WATER", "size": "10,000L", "price": "14"}, {"category": "BORE WATER", "size": "15,000L", "price": "16"}, {"category": "BORE WATER", "size": "25,000L", "price": null}, ]; @override void initState() { super.initState(); _tabController = TabController(length: 3, vsync: this); // Group data by category and initialize controllers for WaterCharges for (final item in data) { final category = item['category'] as String; final size = item['size'] as String; final price = item['price']?.toString() ?? ""; // default to empty if null if (!tankerGroups.containsKey(category)) { tankerGroups[category] = []; } tankerGroups[category]!.add(size); // Pre-fill controller with price or empty controllers.putIfAbsent("$category-$size", () => TextEditingController(text: price)); } // Initialize controllers for unique capacities for DeliveryFee final capacities = data.map((item) => item['size'] as String).toSet(); for (final cap in capacities) { // Take first price for this capacity, default to empty if null final price = data.firstWhere( (d) => d['size'] == cap, orElse: () => {'price': ''}, )['price']?.toString() ?? ""; deliveryControllers.putIfAbsent(cap, () => TextEditingController(text: price)); } } @override void dispose() { // Dispose all controllers for (final controller in controllers.values) { controller.dispose(); } for (final controller in deliveryControllers.values) { controller.dispose(); } super.dispose(); } Widget buildTextField(String label, TextEditingController controller) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: TextField( controller: controller, cursorColor: primaryColor, readOnly: false, keyboardType: TextInputType.number, decoration: InputDecoration( counterText: '', filled: false, fillColor: Colors.white, prefixIconConstraints: BoxConstraints( minWidth: 24, minHeight: 24, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide( color: Color(0XFFC3C4C4), width: 1, )), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide( color: Color(0XFF8270DB), width: 1, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide(color: Color(0XFFC3C4C4)), ), hintText: label, hintStyle: fontTextStyle(14, Color(0XFF939495), FontWeight.w400), /* TextStyle(color: greyColor, fontWeight: FontWeight.bold //<-- SEE HERE ),*/ ), style: fontTextStyle(14, Color(0XFF515253), FontWeight.w500), )); } Widget labelText(String label) { return Text( label, style: fontTextStyle(12, const Color(0XFF515253), FontWeight.w500), ); } Widget WaterCharges() { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ for (final entry in tankerGroups.entries) ...[ Text( entry.key, style: fontTextStyle(10, Color(0XFF2D2E30), FontWeight.w600), ), const SizedBox(height: 8), for (final size in entry.value) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ labelText("$size (in ₹)*"), const SizedBox(height: 4), buildTextField("₹500", controllers["${entry.key}-$size"]!), const SizedBox(height: 12), ], ), const SizedBox(height: 10), ], SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0XFF8270DB), foregroundColor: Color(0XFFFFFFFF), padding: EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), // <-- set your radius here ), ), onPressed: () { final Map> grouped = {}; tankerGroups.forEach((category, sizes) { grouped[category] = {}; for (final size in sizes) { grouped[category]![size] = controllers["$category-$size"]!.text; } }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Rates saved successfully")), ); print(grouped); // Debug: print entered rates }, child: Text( "Save", style: fontTextStyle(14, const Color(0XFFFFFFFF), FontWeight.w600), ), ), ) ], ), ); } Widget DeliveryFee() { // Extract unique capacities final capacities = data.map((item) => item['size'] as String).toSet().toList(); return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "ADDITIONAL RATES", style: fontTextStyle(10, const Color(0xFF2D2E30), FontWeight.w600), ), SizedBox(height: MediaQuery.of(context).size.height * .004), Text( "Add your price per Kilometer for every tanker capacity", style: fontTextStyle(12, const Color(0xFF939495), FontWeight.w400), ), SizedBox(height: MediaQuery.of(context).size.height * .020), // 🔹 Dynamic textfields for (final cap in capacities) ...[ labelText('$cap tanker (per KM)*'), SizedBox(height: MediaQuery.of(context).size.height * .004), buildTextField("+ ₹12", deliveryControllers[cap]!), const SizedBox(height: 12), ], const SizedBox(height: 10), SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0XFF8270DB), foregroundColor: Color(0XFFFFFFFF), padding: EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), // <-- set your radius here ), ), onPressed: () { final Map fees = {}; deliveryControllers.forEach((cap, controller) { fees[cap] = controller.text; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Rates saved successfully")), ); print(fees); }, child: Text( "Save", style: fontTextStyle(14, const Color(0XFFFFFFFF), FontWeight.w600), ), ), ) ], ), ); } Widget PumpFee() { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "TANKER TYPE", style: fontTextStyle(10, Color(0XFF2D2E30), FontWeight.w600), ), SizedBox(height: MediaQuery.of(context).size.height * .004), Text( "Add your price addition for tankers with pump", style: fontTextStyle(12, Color(0XFF939495), FontWeight.w400), ), SizedBox(height: MediaQuery.of(context).size.height * .024), labelText('Tanker with pump*'), SizedBox(height: MediaQuery.of(context).size.height * .004), buildTextField("+ ₹50 ", pumpFeeController), SizedBox(height: MediaQuery.of(context).size.height * .024), SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0XFF8270DB), foregroundColor: Color(0XFFFFFFFF), padding: EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), // <-- set your radius here ), ), onPressed: () { // Handle save logic ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Rates saved successfully")), ); }, child: Text( "Save", style: fontTextStyle(14, const Color(0XFFFFFFFF), FontWeight.w600), ), ), ) ]), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0XFFFFFFFF), appBar: AppSettings.supplierAppBarWithActionsText('Set Rates', context), body: Column( children: [ Container( width: double.infinity, decoration: const BoxDecoration( color: Color(0XFFF3F1FB), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24), ), ), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), child: Column( children: [ SizedBox(height: MediaQuery.of(context).size.height * .096), const CircleAvatar(radius: 50, backgroundColor: Color(0XFFC9C2F0)), SizedBox(height: MediaQuery.of(context).size.height * .016), Text( "What’s today’s water price?", style: fontTextStyle(20, Color(0XFF343637), FontWeight.w600), ), SizedBox(height: MediaQuery.of(context).size.height * .008), Text( "Set your daily rate so customers know what to expect", style: fontTextStyle(12, Color(0XFF343637), FontWeight.w400), textAlign: TextAlign.center, ), ], ), ), const SizedBox(height: 20), Container( height: 30, margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: AnimatedBuilder( animation: _tabController, builder: (context, _) { return TabBar( controller: _tabController, indicatorColor: Colors.transparent, // remove underline dividerColor: Colors.transparent, isScrollable: false, overlayColor: MaterialStateProperty.all(Colors.transparent),// equal width tabs: List.generate(3, (index) { final labels = ['Water Type', 'Delivery Fee','Pump']; final isSelected = _tabController.index == index; return Container( decoration: BoxDecoration( color: isSelected ? const Color(0XFFF1F1F1) : Colors.transparent, borderRadius: BorderRadius.circular(27), ), alignment: Alignment.center, child: Text( labels[index], style: isSelected ?fontTextStyle( 12, const Color(0XFF101214), FontWeight.w600, ):fontTextStyle( 12, const Color(0XFF646464), FontWeight.w600, ), ), ); }), ); }, ), ), Expanded( child: TabBarView( controller: _tabController, children: [ // Water Type Tab WaterCharges(), // Delivery Fee Tab DeliveryFee(), // Pump Tab PumpFee() ], ), ), ], ), ); } }