import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:supplier_new/common/settings.dart'; import '../resources/resources_drivers.dart'; import 'employees.dart'; class FleetStep1Page extends StatefulWidget { const FleetStep1Page({super.key}); @override State createState() => _FleetStep1PageState(); } class _FleetStep1PageState extends State { bool isLoading = false; List tankersList = []; String search = ''; int currentStep = 1; // 1..5 @override void initState() { super.initState(); _fetchTankers(); } Future _fetchTankers() async { setState(() => isLoading = true); try { final response = await AppSettings.getTankers(); final data = jsonDecode(response)['data'] as List; if (!mounted) return; setState(() { tankersList = data; isLoading = false; }); } catch (e) { debugPrint("⚠️ Error fetching tankers: $e"); setState(() => isLoading = false); } } void _openAddTankerSheet() { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Color(0xFFFFFFFF), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(24)), ), builder: (context) => const AddTankerForm(), ).then((value) { if (value == true) { _fetchTankers(); } }); } @override Widget build(BuildContext context) { final filtered = tankersList.where((it) { final q = search.trim().toLowerCase(); if (q.isEmpty) return true; return it['tankerName'].toString().toLowerCase().contains(q); }).toList(); return Scaffold( backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.white, surfaceTintColor: Colors.transparent, elevation: 0, title: const Text("Complete Profile"), actions: [ IconButton( splashRadius: 20, padding: EdgeInsets.zero, icon: const Image( image: AssetImage('images/calendar_appbar.png'), width: 22, height: 22, ), onPressed: () {}, ), IconButton( splashRadius: 20, padding: EdgeInsets.zero, icon: Image.asset('images/notification_appbar.png', width: 22, height: 22), onPressed: () {}, ), ], ), body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Padding( padding: const EdgeInsets.fromLTRB(20, 10, 20, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Step 1/5", style: fontTextStyle(16, Color(0xFFC3C4C4), FontWeight.w500)), const SizedBox(height: 16), Row( children: List.generate(5, (index) { return Expanded( child: Container( margin: const EdgeInsets.symmetric(horizontal: 2), height: 5, decoration: BoxDecoration( color: index < 5 ? const Color(0xFFC3C4C4) : Colors.grey, borderRadius: BorderRadius.circular(2), ), ), ); }), ), const SizedBox(height: 16), Text("FLEET", style: fontTextStyle(20, Color(0xFF515253), FontWeight.w600)), const SizedBox(height: 8), Image.asset('images/truck.png', width: 24, height: 24), const SizedBox(height: 6), Text( "Details about your water tanker fleet", style: fontTextStyle(14, Color(0xFF939495), FontWeight.w500), ), const SizedBox(height: 16), ], ), ), // Tanker list Expanded( child: isLoading ? const Center(child: CircularProgressIndicator()) : tankersList.isEmpty ? Center( child: Text("No tankers added yet.", style: fontTextStyle(14, Color(0xFF939495), FontWeight.w400), ), ) : ListView.separated( padding: const EdgeInsets.fromLTRB(8, 2, 8, 4), itemCount: filtered.length, separatorBuilder: (_, __) => const SizedBox(height: 8), itemBuilder: (context, idx) { final it = filtered[idx]; return StatefulBuilder( builder: (context, setLocalState) { bool expanded = false; return StatefulBuilder( builder: (context, setInner) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 0), decoration: BoxDecoration( color: Color(0xFFF1F1F1), // background color border: Border.all(color: Color(0xFFE5E5E5)), borderRadius: BorderRadius.circular(29), ), child: Column( children: [ ListTile( dense: true, // 👈 makes tile shorter contentPadding: EdgeInsets.zero, // 👈 removes default 16px minVerticalPadding: 0, visualDensity: const VisualDensity(vertical: -4, horizontal: 0), // tighten title: Text( it['tankerName'] ?? 'Unnamed', style: fontTextStyle(14, Color(0xFF2D2E30), FontWeight.w600). copyWith(height: 0.1), ), trailing: IconButton( icon: Image.asset( expanded ? 'images/arrow-up.png' : 'images/downarrow.png', width: 16, height: 16, ), onPressed: () => setInner(() => expanded = !expanded), ), ), if (expanded) Align( alignment: Alignment.centerLeft, child: Container( margin: const EdgeInsets.only(left: 10, right: 10, bottom: 6), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( color: Color(0xFFFFFFFF), // 👈 white background border: Border.all(color:Color(0xFFFFFFFF)), // light border borderRadius: BorderRadius.circular(8), // smooth rounded edges ), child: Text( "${it['typeofwater'] ?? ''} : ${it['capacity'] ?? ''} L", textAlign: TextAlign.left, style: fontTextStyle(12, Color(0xFF2A2A2A), FontWeight.w500, ), ), ), ), ], ), ); }, ); }, ); }, ), ), // Add + Continue buttons Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 20), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ OutlinedButton.icon( onPressed: _openAddTankerSheet, icon: Image.asset('images/Add_icon.png', width: 16, height: 16), label: Text( "Add Tanker", style: fontTextStyle(14, Color(0xFF646566), FontWeight.w600), ), ), const SizedBox(height: 12), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF8270DB), foregroundColor: Color(0xFFFFFFFF), padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), ), onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (_) => const FleetEmployees())); }, child: Text( "Continue", style: fontTextStyle(14, Color(0xFFFFFFFF), FontWeight.w400), ), ), ], ), ), ], ), ), ); } } class AddTankerForm extends StatefulWidget { const AddTankerForm({super.key}); @override State createState() => _AddTankerFormState(); } class _AddTankerFormState extends State { final _formKey = GlobalKey(); final _nameCtrl = TextEditingController(); final _capacityCtrl = TextEditingController(); final _plateCtrl = TextEditingController(); final _mfgYearCtrl = TextEditingController(); final _insExpiryCtrl = TextEditingController(); String? selectedType; String? selectedTypeOfWater; final List tankerTypes = [ "Rigid Truck", "Trailer", "Mini Tanker", "Hydraulic", ]; final List typeOfWater = [ "Bore Water", "Drinking Water", ]; Future _pickInsuranceDate() async { final now = DateTime.now(); final date = await showDatePicker( context: context, initialDate: now, firstDate: DateTime(now.year - 1), lastDate: DateTime(now.year + 10), helpText: "Select Insurance Expiry Date", ); if (date != null) { _insExpiryCtrl.text = "${date.day.toString().padLeft(2, '0')}-${date.month.toString().padLeft(2, '0')}-${date.year}"; setState(() {}); } } Future _addTanker() async { if (!(_formKey.currentState?.validate() ?? false)) return; var payload = { "tankerName": _nameCtrl.text.trim(), "capacity": _capacityCtrl.text.trim(), "typeofwater": selectedTypeOfWater, "supplier_address": AppSettings.userAddress, "supplier_name": AppSettings.userName, "phoneNumber": AppSettings.phoneNumber, "tanker_type": selectedType, "license_plate": _plateCtrl.text.trim(), "manufacturing_year": _mfgYearCtrl.text.trim(), "insurance_exp_date": _insExpiryCtrl.text.trim(), }; bool tankStatus = await AppSettings.addTankers(payload); if (tankStatus) { AppSettings.longSuccessToast("Tanker Created Successfully"); Navigator.pop(context, true); } else { AppSettings.longFailedToast("Tanker Creation Failed"); } } String? _required(String? v, {String field = "This field"}) { if (v == null || v.trim().isEmpty) return "$field is required"; return null; } @override Widget build(BuildContext context) { return Padding( padding: MediaQuery.of(context).viewInsets.add(const EdgeInsets.all(20)), child: SingleChildScrollView( child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ Text("Add New Tanker", style: fontTextStyle(18, Color(0xFF2D2E30), FontWeight.w600)), const SizedBox(height: 16), _LabeledField( label: "Tanker Name *", child: TextFormField( controller: _nameCtrl, validator: (v) => _required(v, field: "Tanker Name"), textCapitalization: TextCapitalization.none, inputFormatters: const [ FirstCharUppercaseFormatter(), // << live first-letter caps ], decoration: InputDecoration( hintText: "Enter Tanker Name", hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), border: const OutlineInputBorder(), isDense: true, ), textInputAction: TextInputAction.next, ), ), _LabeledField( label: "Tanker Capacity (in L) *", child: TextFormField( controller: _capacityCtrl, validator: (v) => _required(v, field: "Tanker Capacity"), decoration: InputDecoration( hintText: "10,000", hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), border: const OutlineInputBorder(), isDense: true, ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[0-9,]')), ], textInputAction: TextInputAction.next, ), ), _LabeledField( label: "Tanker Type *", child: DropdownButtonFormField( value: selectedType, items: tankerTypes .map((t) => DropdownMenuItem(value: t, child: Text(t))) .toList(), onChanged: (v) => setState(() => selectedType = v), validator: (v) => v == null || v.isEmpty ? "Tanker Type is required" : null, isExpanded: true, alignment: Alignment.centerLeft, hint: Text( "Select Type", style: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), ), icon: Image.asset('images/downarrow.png', width: 16, height: 16), decoration: const InputDecoration( border: OutlineInputBorder(), isDense: false, contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), ), ), _LabeledField( label: "Type of water *", child: DropdownButtonFormField( value: selectedTypeOfWater, items: typeOfWater .map((t) => DropdownMenuItem(value: t, child: Text(t))) .toList(), onChanged: (v) => setState(() => selectedTypeOfWater = v), validator: (v) => v == null || v.isEmpty ? "Type of water is required" : null, isExpanded: true, alignment: Alignment.centerLeft, hint: Text( "Select type of water", style: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), ), icon: Image.asset('images/downarrow.png', width: 16, height: 16), decoration: const InputDecoration( border: OutlineInputBorder(), isDense: false, contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), ), ), _LabeledField( label: "License Plate *", child: TextFormField( controller: _plateCtrl, validator: (v) => _required(v, field: "License Plate"), decoration: InputDecoration( hintText: "AB 05 H 4948", hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), border: const OutlineInputBorder(), isDense: true, ), textCapitalization: TextCapitalization.characters, textInputAction: TextInputAction.next, ), ), _LabeledField( label: "Manufacturing Year (opt)", child: TextFormField( controller: _mfgYearCtrl, decoration: InputDecoration( hintText: "YYYY", hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), border: const OutlineInputBorder(), isDense: true, ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(4), ], textInputAction: TextInputAction.next, ), ), _LabeledField( label: "Insurance Expiry Date (opt)", child: TextFormField( controller: _insExpiryCtrl, readOnly: true, decoration: InputDecoration( hintText: "DD-MM-YYYY", hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400), border: const OutlineInputBorder(), isDense: true, suffixIcon: const Icon(Icons.calendar_today_outlined, size: 18), ), onTap: _pickInsuranceDate, ), ), SizedBox( child: ElevatedButton.icon( onPressed: _addTanker, label: Text( "Add Tanker", style: fontTextStyle(14, Colors.white, FontWeight.w600), ), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF8270DB), foregroundColor: Colors.white, minimumSize: const Size(343, 41), // Width & Height padding: const EdgeInsets.fromLTRB(24, 12, 24, 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), elevation: 0, // Optional: flat style per modern UI ), ), ) ], ), ), ), ); } } class _LabeledField extends StatelessWidget { final String label; final Widget child; const _LabeledField({required this.label, required this.child}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: fontTextStyle(12, Color(0xFF515253), FontWeight.w600)), SizedBox(height: 6), child, ], ), ); } } Widget _detailRow(String label, dynamic value) { return Padding( padding: const EdgeInsets.only(bottom: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "$label ", style: fontTextStyle(12, Color(0xFF515253), FontWeight.w600), ), Expanded( child: Text( value == null || value.toString().isEmpty ? "-" : value.toString(), style: fontTextStyle(12, Color(0xFF646566), FontWeight.w400), ), ), ], ), ); }