import 'dart:io'; import 'package:dotted_line/dotted_line.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:generp/Utils/dropdownTheme.dart'; import 'package:generp/screens/crm/generateQuotationAddEditProduct.dart'; import 'package:provider/provider.dart'; import '../../Models/crmModels/crmLeadDetailsGenerateQuotationViewResponse.dart'; import '../../Notifiers/crmProvider/crmGenerateQuotationProvider.dart'; import '../../Utils/app_colors.dart'; import '../../Utils/commonWidgets.dart'; class Generatequotationscreen extends StatefulWidget { final leadId; const Generatequotationscreen({super.key, required this.leadId}); @override State createState() => _GeneratequotationscreenState(); } class _GeneratequotationscreenState extends State { Dropdowntheme ddtheme = Dropdowntheme(); List focusNodes = List.generate(12, (index) => FocusNode()); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) async { final provider = Provider.of( context, listen: false, ); await provider.crmLeadDetailsGenerateQuoteViewAPIFunction( context, widget.leadId, ); // Initialize controllers and dropdowns after API call provider.addEditInitializeForm(context); }); } @override void dispose() { focusNodes.map((e) => e.dispose()); super.dispose(); } @override Widget build(BuildContext context) { return Consumer( builder: (context, provider, child) { return WillPopScope( onWillPop: () async { provider.resetForm(); return true; }, child: SafeArea( top: false, bottom: Platform.isIOS ? false : true, child: Scaffold( resizeToAvoidBottomInset: true, backgroundColor: AppColors.scaffold_bg_color, appBar: appbar2New( context, "Generate Quotation", provider.resetForm, const SizedBox(width: 0), 0xFFFFFFFF, ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), margin: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ textControllerWidget( context, provider.mailIdController, "Email Id", "Enter Email Id", provider.onChangemailId, TextInputType.emailAddress, false, null, focusNodes[0], focusNodes[1], TextInputAction.done, null, ), errorWidget(context, provider.mailIdError), textControllerWidget( context, provider.mobileController, "Mobile Number", "Enter Mobile Number", provider.onChangemobile, TextInputType.phone, false, FilteringTextInputFormatter.digitsOnly, focusNodes[1], focusNodes[2], TextInputAction.done, null, ), errorWidget(context, provider.mobileError), textControllerWidget( context, provider.subjectsController, "Subject", "Enter Subject", provider.onChangesubjects, TextInputType.text, false, null, focusNodes[2], focusNodes[3], TextInputAction.done, null, ), errorWidget(context, provider.subjectsError), ], ), ), Container( padding: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), margin: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ InkResponse( onTap: () async { var res = await Navigator.push( context, MaterialPageRoute( builder: (context) => Generatequotationaddeditproduct( leadId: widget.leadId, type: "add", ), settings: RouteSettings( name: 'Generatequotationaddeditproduct', ), ), ); if (res != null && res == true) { print("result $res"); // Force refresh the provider and UI await provider.crmLeadDetailsGenerateQuoteViewAPIFunction( context, widget.leadId, ); // Force UI update if (mounted) { setState(() {}); } } }, child: Container( margin: const EdgeInsets.symmetric(vertical: 10), height: 45, width: MediaQuery.of(context).size.width, decoration: BoxDecoration( color: const Color(0xFFE6F6FF), borderRadius: BorderRadius.circular(12), border: Border.all( color: AppColors.app_blue, width: 0.5, ), ), child: Center( child: Text( "+ Add Product", style: TextStyle( fontFamily: "JakartaMedium", color: AppColors.app_blue, ), ), ), ), ), if (provider.leadProductsList.isNotEmpty) ...[ SizedBox( width: double.infinity, height: 125, child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), shrinkWrap: true, scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric( vertical: 15, horizontal: 0, ), itemCount: provider.leadProductsList.length, itemBuilder: (context, lp) { return InkResponse( onTap: () async { var res = await Navigator.push( context, MaterialPageRoute( builder: ( context, ) => Generatequotationaddeditproduct( leadId: widget.leadId, type: "edit", product: provider .leadProductsList[lp], index: lp, ), settings: RouteSettings( name: 'Generatequotationaddeditproduct', ), ), ); if (res != null && res == true) { print("result $res"); // Force refresh after editing await provider.crmLeadDetailsGenerateQuoteViewAPIFunction( context, widget.leadId, ); // Force UI update if (mounted) { setState(() {}); } } }, child: Container( height: 125, width: MediaQuery.of(context).size.width * 0.8, decoration: BoxDecoration( color: Color(0xFFE6F6FF), borderRadius: BorderRadius.circular(14), ), padding: EdgeInsets.symmetric( horizontal: 10, vertical: 8, ), margin: EdgeInsets.symmetric( horizontal: 5, ), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( flex: 1, child: SvgPicture.asset( "assets/svg/crm/product_details_ic.svg", ), ), SizedBox(width: 10), Expanded( flex: 6, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, // Changed to spaceBetween children: [ // Top section - Product name and price Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( flex: 4, child: Text( provider.leadProductsList[lp].productName ?? "-", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontFamily: "JakartaMedium", fontSize: 14, color: AppColors.semi_black, ), ), ), Expanded( flex: 3, child: Text( textAlign: TextAlign.right, maxLines: 1, "₹${provider.leadProductsList[lp].price ?? "-"}", style: TextStyle( fontFamily: "JakartaMedium", fontSize: 14, color: AppColors.semi_black, ), ), ), ], ), SizedBox(height: 1), // Reduced spacing Text( "x ${provider.leadProductsList[lp].qty ?? "-"}", style: TextStyle( fontFamily: "JakartaMedium", fontSize: 12, // Slightly smaller font color: AppColors.grey_semi, ), ), ], ), // Middle section - Dotted line Center( child: DottedLine( dashGapLength: 4, dashGapColor: Colors.white, dashColor: AppColors.grey_semi, dashLength: 2, lineThickness: 0.5, ), ), // Bottom section - Total price Text( "₹${provider.leadProductsList[lp].prodTotalPrice ?? " - "}", style: TextStyle( fontFamily: "JakartaMedium", fontSize: 14, color: AppColors.semi_black, ), ), ], ), ), ], ), ), ); }, ), ), ], errorWidget(context, provider.productRowsError), ], ), ), Container( padding: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), margin: EdgeInsets.symmetric( horizontal: 10, vertical: 10, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextWidget(context, "Taxes"), DropdownButtonHideUnderline( child: Row( children: [ Expanded( child: DropdownButton2( isExpanded: true, hint: const Row( children: [ Expanded( child: Text( 'Select Lead Status', style: TextStyle(fontSize: 14), overflow: TextOverflow.ellipsis, ), ), ], ), items: ["Extra", "Including"] .map( (value) => DropdownMenuItem( value: value, child: Text( value ?? '', style: const TextStyle( fontSize: 14, ), overflow: TextOverflow.ellipsis, ), ), ) .toList(), value: provider.selectedTaxes, onChanged: (String? newValue) { setState(() { provider.selectedTaxes = newValue!; }); }, buttonStyleData: ddtheme.buttonStyleData, iconStyleData: ddtheme.iconStyleData, menuItemStyleData: ddtheme.menuItemStyleData, dropdownStyleData: ddtheme.dropdownStyleData, ), ), ], ), ), errorWidget(context, provider.taxesError), textControllerWidget( context, provider.SpecialNoteController, "Special Note", "Enter Special Note", provider.onChangeSpecialNote, TextInputType.text, false, null, focusNodes[3], focusNodes[4], TextInputAction.done, null, ), errorWidget(context, provider.SpecialNoteError), textControllerWidget( context, provider.forController, "FOR", "Enter FOR", provider.onChangefor, TextInputType.text, false, null, focusNodes[4], focusNodes[5], TextInputAction.done, null, ), errorWidget(context, provider.forError), textControllerWidget( context, provider.paymentTermsController, "Payment Terms", "Enter Payment Terms", provider.onChangepaymentTerms, TextInputType.text, false, null, focusNodes[5], focusNodes[6], TextInputAction.done, null, ), errorWidget(context, provider.paymentTermsError), ], ), ), ], ), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, bottomNavigationBar: Material( elevation: 2, shadowColor: Colors.black12, child: Container( height: 80, decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.white54, blurRadius: 10, offset: Offset(0, -2), ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: provider.buttonsLoading ? [ SizedBox(width: 25), CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation( AppColors.app_blue, ), ), SizedBox(width: 25), ] : [ Expanded( child: InkResponse( onTap: provider.buttonsLoading ? null : () { HapticFeedback.mediumImpact(); provider.buttonsLoading = true; //genquotedown final insertedData = provider.productRows; print(insertedData); provider .crmLeadDetailsGenerateQuoteSubmitAPIFunction( context, widget.leadId, insertedData, "genquotedown", ); }, child: Container( height: 45, alignment: Alignment.center, decoration: BoxDecoration( // color: AppColors.app_blue, borderRadius: BorderRadius.circular(10), ), child: provider.submitLoading ? CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation( AppColors.app_blue, ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( "assets/svg/crm/download_quote_ic.svg", ), SizedBox(width: 10), Text( "Download", style: TextStyle( fontSize: 14, fontFamily: "JakartaRegular", ), ), ], ), ), ), ), SvgPicture.asset( "assets/svg/crm/vertical_line_ic.svg", ), Expanded( child: InkResponse( onTap: provider.buttonsLoading ? null : () { HapticFeedback.mediumImpact(); provider.buttonsLoading = true; //genquotemail, final insertedData = provider.productRows; print(insertedData); provider .crmLeadDetailsGenerateQuoteSubmitAPIFunction( context, widget.leadId, insertedData, "genquotemail", ); }, child: Container( height: 45, alignment: Alignment.center, decoration: BoxDecoration( // color: AppColors.app_blue, borderRadius: BorderRadius.circular(10), ), child: provider.submitLoading ? CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation( AppColors.app_blue, ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( "assets/svg/crm/email_quote_ic.svg", ), SizedBox(width: 10), Text( "Email", style: TextStyle( fontSize: 14, fontFamily: "JakartaRegular", ), ), ], ), ), ), ), SvgPicture.asset( "assets/svg/crm/vertical_line_ic.svg", ), Expanded( child: InkResponse( onTap: provider.buttonsLoading ? null : () { HapticFeedback.mediumImpact(); provider.buttonsLoading = true; //genquotewhatsapp, final insertedData = provider.productRows; print(insertedData); provider .crmLeadDetailsGenerateQuoteSubmitAPIFunction( context, widget.leadId, insertedData, "genquotewhatsapp", ); }, child: Container( height: 45, alignment: Alignment.center, decoration: BoxDecoration( // color: AppColors.app_blue, borderRadius: BorderRadius.circular(10), ), child: provider.submitLoading ? CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation( AppColors.app_blue, ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( "assets/svg/crm/whatsapp_quote_ic.svg", ), SizedBox(width: 10), Text( "Whatsapp", style: TextStyle( fontSize: 14, fontFamily: "JakartaRegular", ), ), ], ), ), ), ), ], ), ), ), ), ), ); }, ); } }