"lib/screens/git@183.82.99.133:saisrinivas/gen_erp_2025.git" did not exist on "924f87325e503e0d6d3793371a2846ef0ae33cc3"
Commit 7ba7402c authored by Sai Srinivas's avatar Sai Srinivas Committed by Sai Srinivas
Browse files

Edit form and some fixes added

parent d2939607
...@@ -428,7 +428,8 @@ class MyApp extends StatelessWidget { ...@@ -428,7 +428,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => CasualLeaveHistoryProvider()), ChangeNotifierProvider(create: (_) => CasualLeaveHistoryProvider()),
ChangeNotifierProvider(create: (_) => ContactProvider()), ChangeNotifierProvider(create: (_) => ContactProvider()),
ChangeNotifierProvider(create: (_) => QrProvider()), ChangeNotifierProvider(create: (_) => QrProvider()),
ChangeNotifierProvider(create: (_) => CrmNearByGeneratorsProvider()),
ChangeNotifierProvider(create: (_) => EditCommonAccountProvider()),
], ],
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
......
...@@ -117,7 +117,17 @@ class _AccountslistState extends State<Accountslist> { ...@@ -117,7 +117,17 @@ class _AccountslistState extends State<Accountslist> {
return (connection == "Online") return (connection == "Online")
? Platform.isAndroid ? Platform.isAndroid
? WillPopScope( ? WillPopScope(
onWillPop: () => onBackPressed(context), onWillPop: () async {
onBackPressed(context);
_refreshList(context);
final provider = Provider.of<Accountslistprovider>(context, listen: false);
provider.resetValues();
provider.commonAccountListAPIFunction(context);
// Return true or false depending on whether you want to allow the pop
return true; // allow the back navigation
// return false; // prevent back navigation
},
child: SafeArea( child: SafeArea(
top: false, top: false,
bottom: true, bottom: true,
......
...@@ -8,11 +8,13 @@ import 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart'; ...@@ -8,11 +8,13 @@ import 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart';
import 'package:generp/Utils/app_colors.dart'; import 'package:generp/Utils/app_colors.dart';
import 'package:generp/Utils/commonServices.dart'; import 'package:generp/Utils/commonServices.dart';
import 'package:generp/Utils/commonWidgets.dart'; import 'package:generp/Utils/commonWidgets.dart';
import 'package:generp/screens/commom/editCommonAccount.dart';
import 'package:generp/screens/commom/transactionDetails.dart'; import 'package:generp/screens/commom/transactionDetails.dart';
import 'package:generp/screens/finance/submitPaymentRequestionListsByMode.dart'; import 'package:generp/screens/finance/submitPaymentRequestionListsByMode.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../Models/commonModels/commonAccountdetailsResponse.dart'; import '../../Models/commonModels/commonAccountdetailsResponse.dart';
import 'addCommonPayment.dart';
class Accountslistdetails extends StatefulWidget { class Accountslistdetails extends StatefulWidget {
final accountID; final accountID;
...@@ -131,7 +133,13 @@ class _AccountslistdetailsState extends State<Accountslistdetails> { ...@@ -131,7 +133,13 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
), ),
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
backgroundColor: AppColors.scaffold_bg_color, backgroundColor: AppColors.scaffold_bg_color,
body: SizedBox( body: Builder(builder: (context){
if (provider.isLoading) {
return const Center(
child: CircularProgressIndicator(color: Colors.blue),
);
}
return SizedBox(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
...@@ -201,7 +209,28 @@ class _AccountslistdetailsState extends State<Accountslistdetails> { ...@@ -201,7 +209,28 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
), ),
), ),
), ),
SizedBox(width: 10), SizedBox(width: 2),
Expanded(
flex: 1,
child: InkResponse(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => EditCommonAccountScreen(accountID: widget.accountID,))
).then((_) async {
var prov = Provider.of<Accountdetailsprovider>(context, listen: false);
await prov.accountdetailsAPIFunction(context, widget.accountID);
});
},
child: SizedBox(
height: 25,
width: 25,
child: SvgPicture.asset(
"assets/svg/crm_contact_edit.svg",
),
),
),
),
], ],
), ),
Visibility( Visibility(
...@@ -762,41 +791,41 @@ class _AccountslistdetailsState extends State<Accountslistdetails> { ...@@ -762,41 +791,41 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
), ),
), ),
Spacer(), Spacer(),
Expanded( // Expanded(
flex: 3, // flex: 3,
child: SizedBox( // child: SizedBox(
child: RichText( // child: RichText(
maxLines: 1, // maxLines: 1,
textAlign: TextAlign.right, // textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis, // overflow: TextOverflow.ellipsis,
text: TextSpan( // text: TextSpan(
children: [ // children: [
TextSpan( // TextSpan(
text: "Bal: ", // text: "Bal: ",
style: TextStyle( // style: TextStyle(
color: // color:
AppColors // AppColors
.semi_black, // .semi_black,
fontSize: 12, // fontSize: 12,
fontFamily: // fontFamily:
"JakartaRegular", // "JakartaRegular",
), // ),
), // ),
TextSpan( // TextSpan(
text: "$runningBalance", // text: "$runningBalance",
style: TextStyle( // style: TextStyle(
color: // color:
AppColors.grey_semi, // AppColors.grey_semi,
fontSize: 12, // fontSize: 12,
fontFamily: // fontFamily:
"JakartaMedium", // "JakartaMedium",
), // ),
), // ),
], // ],
), // ),
), // ),
), // ),
), // ),
], ],
), ),
], ],
...@@ -857,7 +886,9 @@ class _AccountslistdetailsState extends State<Accountslistdetails> { ...@@ -857,7 +886,9 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
], ],
), ),
), ),
), );
}
)
); );
}, },
); );
......
...@@ -31,7 +31,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -31,7 +31,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
Dropdowntheme ddtheme = Dropdowntheme(); Dropdowntheme ddtheme = Dropdowntheme();
int _currentStep = 0; int _currentStep = 0;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
List<FocusNode> focusNodes = List.generate(20, (index) => FocusNode()); final List<FocusNode> focusNodes = List.generate(30, (index) => FocusNode());
Map _source = {ConnectivityResult.mobile: true}; Map _source = {ConnectivityResult.mobile: true};
final MyConnectivity _connectivity = MyConnectivity.instance; final MyConnectivity _connectivity = MyConnectivity.instance;
...@@ -274,7 +274,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -274,7 +274,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
// custom continue logic: // custom continue logic:
if (_currentStep == 0) { if (_currentStep == 0) {
// validate step1 via provider // validate step1 via provider
if (provider.validateStep1()) { if (provider.validateStep1(context)) {
setState(() => _currentStep = 1); setState(() => _currentStep = 1);
} else { } else {
// show error (provider sets errors and notifies) // show error (provider sets errors and notifies)
...@@ -337,7 +337,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -337,7 +337,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
setState(() => _currentStep = 0); setState(() => _currentStep = 0);
} else if (value == 1) { } else if (value == 1) {
// user wants to jump to step 1 - ensure step 0 valid // user wants to jump to step 1 - ensure step 0 valid
if (provider.validateStep1()) { if (provider.validateStep1(context)) {
setState(() => _currentStep = 1); setState(() => _currentStep = 1);
} else { } else {
provider.notifyListeners(); provider.notifyListeners();
...@@ -345,7 +345,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -345,7 +345,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
} }
} else if (value == 2) { } else if (value == 2) {
// allow jump if step0 valid; step1 optional // allow jump if step0 valid; step1 optional
if (provider.validateStep1()) { if (provider.validateStep1(context)) {
setState(() => _currentStep = 2); setState(() => _currentStep = 2);
} else { } else {
provider.notifyListeners(); provider.notifyListeners();
...@@ -353,7 +353,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -353,7 +353,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
} }
} else if (value == 3) { } else if (value == 3) {
// final - require step0 valid // final - require step0 valid
if (!provider.validateStep1()) { if (!provider.validateStep1(context)) {
provider.notifyListeners(); provider.notifyListeners();
setState(() => _currentStep = 0); setState(() => _currentStep = 0);
return; return;
...@@ -442,6 +442,9 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -442,6 +442,9 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
(p0) { (p0) {
provider.updateName(p0); provider.updateName(p0);
provider.checkInputsAPI(context, "name", provider.nameController.text); provider.checkInputsAPI(context, "name", provider.nameController.text);
// Recompare with GST response if exists
provider.recheckNameWithGst();
}, },
TextInputType.text, TextInputType.text,
false, false,
...@@ -708,52 +711,120 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -708,52 +711,120 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// GST field - if provided, validate and autofill address; compare company name // GST field (unique focus node 9). Only one GST widget here.
textControllerWidget( Text("GST Number"),
context, const SizedBox(height: 6),
provider.gstNumberController, TextFormField(
"GST Number", controller: provider.gstNumberController,
"Enter GST Number", focusNode: focusNodes[9],
(val) async { textInputAction: TextInputAction.done,
// when user types, just update; validation on field submit keyboardType: TextInputType.text,
provider.gstNumberController.text = val; style: TextStyle(
height: 1.2,
color: Colors.black87,
backgroundColor: AppColors.text_field_color,
),
decoration: InputDecoration(
hintText: "Enter GST Number",
filled: true,
hintStyle: TextStyle(
height: 1.2,
backgroundColor: AppColors.text_field_color,
color: AppColors.grey_semi,
),
fillColor: AppColors.text_field_color,
contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
),
onChanged: (value) {
// only clear GST error when user edits
provider.updateGSTNumber(value);
final trimmed = value.trim();
if (trimmed.isEmpty) {
// user cleared GST -> clear response + errors
provider.gstResponse = null;
provider.gstNumberError = null;
provider.nameError = null; // also clear mismatch error, if any
provider.notifyListeners(); provider.notifyListeners();
return;
}
// OPTIONAL: auto-validate once full 15-char GST typed
if (trimmed.length == 15) {
provider.checkAndApplyGst(context, trimmed);
}
},
onFieldSubmitted: (value) async {
final trimmed = value.trim();
if (trimmed.isNotEmpty) {
await provider.checkAndApplyGst(context, trimmed);
}
// move focus to Bank Account Number
FocusScope.of(context).requestFocus(focusNodes[10]);
}, },
TextInputType.text,
false,
null,
focusNodes[9],
focusNodes[10],
TextInputAction.next,
null,
// onEditingComplete / onFieldSubmitted, we will validate
), ),
// Validate GST when user leaves the field (on editing complete)
// To do that we use FocusNode
const SizedBox(height: 4), const SizedBox(height: 4),
errorWidget(context, provider.gstNumberError), errorWidget(context, provider.gstNumberError),
// Bank Account Number
const SizedBox(height: 4),
// errorWidget(context, provider.gstNumberError),
// Bank Account Number (use same style as other fields)
textControllerWidget( textControllerWidget(
context, context,
provider.bankAcNumberController, provider.bankAcNumberController,
"Bank Account Number", "Bank Account Number",
"Enter Bank Account Number", "Enter Bank Account Number",
(p0) { (p0) {
// update provider value and trigger bank validation if IFSC already present
provider.updateNumber(p0); provider.updateNumber(p0);
// attempt validation only when IFSC present // If account entered but IFSC empty -> provider will set IFSC required error via checkAndApplyBank
if (provider.bankIfscCotroller.text.trim().isNotEmpty) { if (provider.bankIfscCotroller.text.trim().isNotEmpty) {
_validateBankIfNeeded(provider); // validate once IFSC is present
provider.checkAndApplyBank(context, p0.trim());
} else {
// If account present but IFSC empty, show IFSC required error
if (p0.trim().isNotEmpty) {
provider.bankIFSCError = "IFSC is required when account number is entered";
provider.notifyListeners();
} else {
provider.bankIFSCError = null;
provider.notifyListeners();
}
} }
}, },
TextInputType.number, TextInputType.number,
false, false,
FilteringTextInputFormatter.digitsOnly, FilteringTextInputFormatter.digitsOnly,
focusNodes[10], focusNodes[10], // bank account unique
focusNodes[11], focusNodes[8], // move to IFSC next
TextInputAction.next, TextInputAction.next,
), ),
const SizedBox(height: 4),
errorWidget(context, provider.bankAcNumberError), errorWidget(context, provider.bankAcNumberError),
// IFSC
// Bank IFSC
textControllerWidget( textControllerWidget(
context, context,
provider.bankIfscCotroller, provider.bankIfscCotroller,
...@@ -761,28 +832,46 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -761,28 +832,46 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
"Enter Bank IFSC", "Enter Bank IFSC",
(p0) { (p0) {
provider.updateIFSC(p0); provider.updateIFSC(p0);
// validate IFSC format locally; if good and account present, trigger server validation // local IFSC format check
if (_isIfscValidFormat(p0) && provider.bankAcNumberController.text.trim().isNotEmpty) { final reg = RegExp(r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$');
_validateBankIfNeeded(provider); if (p0.trim().isEmpty) {
// if account exists and IFSC empty -> show required error
if (provider.bankAcNumberController.text.trim().isNotEmpty) {
provider.bankIFSCError = "IFSC is required when account number is entered";
provider.notifyListeners();
} else { } else {
if (p0.trim().isNotEmpty && !_isIfscValidFormat(p0)) { provider.bankIFSCError = null;
provider.notifyListeners();
}
return;
}
if (!reg.hasMatch(p0.trim())) {
provider.bankIFSCError = "Invalid IFSC format"; provider.bankIFSCError = "Invalid IFSC format";
provider.notifyListeners(); provider.notifyListeners();
return;
} else { } else {
provider.bankIFSCError = null; provider.bankIFSCError = null;
provider.notifyListeners(); provider.notifyListeners();
} }
// if acc and IFSC both present and valid -> call bank API
if (provider.bankAcNumberController.text.trim().isNotEmpty) {
provider.checkAndApplyBank(context, provider.bankAcNumberController.text.trim());
} }
}, },
TextInputType.text, TextInputType.text,
false, false,
null, null,
focusNodes[8], focusNodes[8], // unique IFSC focus
focusNodes[9], focusNodes[11], // next focus after IFSC (holder / or UPI)
TextInputAction.next, TextInputAction.next,
), ),
const SizedBox(height: 4),
errorWidget(context, provider.bankIFSCError), errorWidget(context, provider.bankIFSCError),
// Bank Name (autofill) const SizedBox(height: 8),
// Bank Name (autofill by API) (unique focus node 6)
textControllerWidget( textControllerWidget(
context, context,
provider.bankNameController, provider.bankNameController,
...@@ -797,7 +886,10 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -797,7 +886,10 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputAction.next, TextInputAction.next,
), ),
errorWidget(context, provider.banknameError), errorWidget(context, provider.banknameError),
// Branch
const SizedBox(height: 8),
// Branch (unique focus node 7)
textControllerWidget( textControllerWidget(
context, context,
provider.branchNameController, provider.branchNameController,
...@@ -808,11 +900,14 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -808,11 +900,14 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
false, false,
null, null,
focusNodes[7], focusNodes[7],
focusNodes[8], focusNodes[11],
TextInputAction.next, TextInputAction.next,
), ),
errorWidget(context, provider.bankBranchError), errorWidget(context, provider.bankBranchError),
// Holder
const SizedBox(height: 8),
// Bank Holder Name (unique focus node 11) — previously incorrectly used 9
textControllerWidget( textControllerWidget(
context, context,
provider.bankHolderNameController, provider.bankHolderNameController,
...@@ -822,12 +917,16 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -822,12 +917,16 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputType.text, TextInputType.text,
false, false,
null, null,
focusNodes[9], focusNodes[11], // <-- corrected unique index
focusNodes[10], focusNodes[12],
TextInputAction.next, TextInputAction.next,
), ),
errorWidget(context, provider.bankHolderNameError), errorWidget(context, provider.bankHolderNameError),
// UPI
const SizedBox(height: 8),
// Bank UPI (unique focus node 12)
// Bank UPI (use different focus nodes than Contact Person)
textControllerWidget( textControllerWidget(
context, context,
provider.bankUpiController, provider.bankUpiController,
...@@ -837,8 +936,8 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -837,8 +936,8 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputType.text, TextInputType.text,
false, false,
null, null,
focusNodes[11], focusNodes[17], //
focusNodes[12], focusNodes[18], // next focus
TextInputAction.next, TextInputAction.next,
), ),
errorWidget(context, provider.upiError), errorWidget(context, provider.upiError),
...@@ -973,6 +1072,23 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -973,6 +1072,23 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
return; return;
} }
if (provider.validateStep1(context)) {
// move to first error step
final errStep = _firstErrorStep(provider);
if (errStep != null) {
setState(() {
_currentStep = errStep;
});
}else{
provider.submitClickced = true;
provider.notifyListeners();
await provider.submitCommonAccountsAPI(context, widget.from);
}
// ensure UI updated
provider.notifyListeners();
return;
}
// All good => submit // All good => submit
provider.submitClickced = true; provider.submitClickced = true;
provider.notifyListeners(); provider.notifyListeners();
...@@ -994,7 +1110,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> { ...@@ -994,7 +1110,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
onTap: () { onTap: () {
setState(() { setState(() {
if (_currentStep == 0) { if (_currentStep == 0) {
if (provider.validateStep1()) { if (provider.validateStep1(context)) {
_currentStep = 1; _currentStep = 1;
} else { } else {
provider.notifyListeners(); provider.notifyListeners();
......
This diff is collapsed.
import 'dart:io';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:generp/Utils/commonWidgets.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:interactive_slider/interactive_slider.dart';
import 'package:provider/provider.dart';
import '../../Notifiers/crmProvider/CrmNearByGeneratorsProvider.dart';
import '../../Utils/dropdownTheme.dart';
class CrmNearbyGenerators extends StatefulWidget {
const CrmNearbyGenerators({super.key});
@override
State<CrmNearbyGenerators> createState() => _CrmNearbyGeneratorsState();
}
class _CrmNearbyGeneratorsState extends State<CrmNearbyGenerators> {
Dropdowntheme ddtheme = Dropdowntheme();
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
var provider = Provider.of<CrmNearByGeneratorsProvider>(
context,
listen: false,
);
provider.getLocationPermission(context);
});
}
@override
Widget build(BuildContext context) {
debugPrint("Nearbygenerators widget rebuilt");
return Consumer<CrmNearByGeneratorsProvider>(
builder: (context, provider, child) {
var sendWidget = GestureDetector(
onTap: () {
_showFilterBottomSheet(context);
},
child: SvgPicture.asset("assets/svg/filter_ic.svg", height: 25),
);
return WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: Platform.isIOS ? false : true,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: appbar2(
context,
"Nearby Generators",
provider.resetAll,
sendWidget,
),
backgroundColor: AppColors.scaffold_bg_color,
body: Container(
child: SingleChildScrollView(
child: Column(
children: [
ClipRRect(
// Apply border radius using ClipRRect
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
// padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Stack(
children: [
GoogleMap(
scrollGesturesEnabled: true,
rotateGesturesEnabled: true,
myLocationEnabled: true,
zoomGesturesEnabled: true,
zoomControlsEnabled: true,
gestureRecognizers: {
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer(),
),
Factory<PanGestureRecognizer>(
() => PanGestureRecognizer(),
),
Factory<ScaleGestureRecognizer>(
() => ScaleGestureRecognizer(),
), // Prioritize pinch-to-zoom
},
initialCameraPosition: CameraPosition(
target: provider.startLocation,
zoom: 14.0,
),
markers: provider.markers.toSet(),
mapType: MapType.normal,
onMapCreated: (controller) {
setState(() {
provider.mapController = controller;
});
},
onCameraMove: (position) {
provider.onCameraMove(context, position);
},
),
],
),
),
),
],
),
),
),
),
),
);
},
);
}
Future<void> _showFilterBottomSheet(BuildContext context) {
return showModalBottomSheet(
useSafeArea: true,
isDismissible: true,
isScrollControlled: true,
showDragHandle: true,
enableDrag: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return SafeArea(
child: Consumer<CrmNearByGeneratorsProvider>(
builder: (context, provider, child) {
return Container(
margin: EdgeInsets.only(
bottom: 15,
left: 15,
right: 15,
top: 15,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Filter",
style: TextStyle(
color: AppColors.app_blue,
fontFamily: "JakartaSemiBold",
fontSize: 16,
),
),
SizedBox(height: 15),
Align(
alignment: Alignment.centerLeft,
child: Text(
'Status',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
),
),
),
DropdownButtonHideUnderline(
child: Row(
children: [
Expanded(
child: DropdownButton2<String>(
isExpanded: true,
hint: const Row(
children: [
Expanded(
child: Text(
'Select Complaint Status',
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
<String>[
'Active',
'Inactive',
'Suspense',
]
.map(
(
value,
) => DropdownMenuItem<String>(
value: value,
child: Text(
value ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
value: provider.selectedItem,
onChanged: (String? newValue) {
setState(() {
provider.selectedItem = newValue!;
});
},
buttonStyleData:
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
),
),
],
),
),
SizedBox(height: 10),
Row(
children: [
Text(
"Radius",
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
),
),
Spacer(),
Text(
'${provider.currentValue.toStringAsFixed(2)} KM',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
),
),
],
),
InteractiveSlider(
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0),
min: 1.0,
max: 5.0, // MAX 5 KM
enabled: true,
foregroundColor: AppColors.app_blue,
segmentDividerColor: Color(0xFFF6F6F8),
onChanged: (value) {
// just to be extra safe, clamp in provider too
provider.currentValue = value;
},
),
// Slider(
// value: provider.currentValue,
// max: 100,
// divisions: 100,
//
// label: provider.currentValue.toStringAsFixed(2),
// inactiveColor: Color(0xFFD7D7D7),
// activeColor: AppColors.cyan_blue,
// onChanged: (value) {
// provider.currentValue = value;
// provider.debounce(() {
// provider.LoadNearbyGeneratorsAPI(context);
// }, Duration(milliseconds: 200));
// },
// ),
SizedBox(height: 30.0),
Container(
child: InkWell(
onTap: () {
provider.debounce(() {
provider.LoadNearbyGeneratorsAPI(
context,
provider.currentValue,
);
Navigator.pop(context);
}, Duration(milliseconds: 500));
},
child: Container(
alignment: Alignment.center,
height: 45,
margin: EdgeInsets.only(
left: 15.0,
right: 15.0,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14.0),
color: AppColors.app_blue,
),
child: Text(
"Search",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'JakartaMedium',
color: Colors.white,
),
),
),
),
),
],
),
],
),
),
);
},
),
);
},
);
},
);
}
}
...@@ -357,6 +357,19 @@ class _LeadlistbymodeState extends State<Leadlistbymode> { ...@@ -357,6 +357,19 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
), ),
child: Consumer<Leadlistprovider>( child: Consumer<Leadlistprovider>(
builder: (context, provider, child) { builder: (context, provider, child) {
// 🔹 Initialize filter selections from widget.filter only once
if (provider.selectedLeadStatus == null &&
widget.filter?.status != null &&
widget.filter!.status!.toString().isNotEmpty) {
provider.selectedLeadStatus = widget.filter!.status;
}
if (provider.selectedOpenStatus == null &&
widget.filter?.openStatus != null &&
widget.filter!.openStatus!.toString().isNotEmpty) {
provider.selectedOpenStatus = widget.filter!.openStatus;
}
int selectedIndex = isSelected.indexWhere( int selectedIndex = isSelected.indexWhere(
(element) => element == true, (element) => element == true,
); );
...@@ -373,6 +386,22 @@ class _LeadlistbymodeState extends State<Leadlistbymode> { ...@@ -373,6 +386,22 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
if (widget.mode != "executive") { if (widget.mode != "executive") {
headings.add("Employee"); headings.add("Employee");
} }
// int selectedIndex = isSelected.indexWhere(
// (element) => element == true,
// );
// final headings = [
// "Lead Status",
// "Open/Close Status",
// "Mobile Number",
// "Company Name",
// "Source",
// "Reference",
// "Team",
// "Segment",
// ];
if (widget.mode != "executive") {
headings.add("Employee");
}
return SizedBox( return SizedBox(
height: MediaQuery.of(context).size.height * 0.7, height: MediaQuery.of(context).size.height * 0.7,
child: Column( child: Column(
...@@ -512,17 +541,12 @@ class _LeadlistbymodeState extends State<Leadlistbymode> { ...@@ -512,17 +541,12 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (selectedIndex == 0) ...[ if (selectedIndex == 0) ...[
...provider.leadStatusList.map(( ...provider.leadStatusList.map((status,) {// here i want to do that i want to show selected from widget.filter!.status,
status,
) {
return SizedBox( return SizedBox(
height: 35, height: 35,
child: CheckboxListTile( child: CheckboxListTile(
activeColor: activeColor: AppColors.app_blue,
AppColors.app_blue, controlAffinity: ListTileControlAffinity.leading,
controlAffinity:
ListTileControlAffinity
.leading,
checkboxShape: CircleBorder( checkboxShape: CircleBorder(
side: BorderSide( side: BorderSide(
width: 0.5, width: 0.5,
...@@ -568,7 +592,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> { ...@@ -568,7 +592,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
width: 0.5, width: 0.5,
), ),
), ),
title: Text( title: Text(// same here widget.filter!.openStatus,
status ?? 'Unknown Status', status ?? 'Unknown Status',
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 14,
...@@ -963,6 +987,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> { ...@@ -963,6 +987,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
}, },
); );
} }
void _showContactOptions(BuildContext context, String? phoneNumber) { void _showContactOptions(BuildContext context, String? phoneNumber) {
if (phoneNumber == null || phoneNumber.isEmpty) { if (phoneNumber == null || phoneNumber.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
......
...@@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; ...@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:generp/Notifiers/crmProvider/addNewLeadsandProspectsProvider.dart'; import 'package:generp/Notifiers/crmProvider/addNewLeadsandProspectsProvider.dart';
import 'package:generp/screens/crm/CrmNearbyGenerators.dart';
import 'package:generp/screens/crm/addLeadsProspectsScreen.dart'; import 'package:generp/screens/crm/addLeadsProspectsScreen.dart';
import 'package:generp/screens/crm/appointmentCalendar.dart'; import 'package:generp/screens/crm/appointmentCalendar.dart';
import 'package:generp/screens/crm/followUpListonType.dart'; import 'package:generp/screens/crm/followUpListonType.dart';
...@@ -741,6 +742,69 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -741,6 +742,69 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
], ],
), ),
), ),
SizedBox(height: 10,),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 15, top: 10, right: 15),
child: Text(
"Nearby Generators",
style: TextStyle(
fontSize: 16,
color: AppColors.grey_semi,
),
),
),
),
SizedBox(height: 12,),
InkResponse(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CrmNearbyGenerators(),
),
);
},
child: Container(
height: 60,
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Row(
children: [
Expanded(
flex: 1,
child: Container(
height: 35,
width: 35,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Color(0xFFEDF8FF),
shape: BoxShape.circle,
),
child: SvgPicture.asset(
"assets/svg/find_generator.svg",
),
),
),
Expanded(
flex: 4,
child: Text(
"Find Nearby Generators",
style: TextStyle(
fontSize: 14,
color: AppColors.app_blue,
),
),
),
],
),
),
),
if (provider.nearByLeads.isNotEmpty) ...[ if (provider.nearByLeads.isNotEmpty) ...[
Align( Align(
......
...@@ -359,16 +359,19 @@ class _AttendanceRequestDetailScreenState ...@@ -359,16 +359,19 @@ class _AttendanceRequestDetailScreenState
"Other Details", "Other Details",
scaleFactor, scaleFactor,
), ),
if (details.type == "Check In" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Check In Type", "Check In Type",
details.checkInType, details.checkInType,
scaleFactor, scaleFactor,
), ),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Check Out Type", "Check Out Type",
details.chechOutType, details.chechOutType,
scaleFactor, scaleFactor,
), ),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Check Out Time", "Check Out Time",
details.checkOutTime, details.checkOutTime,
......
...@@ -72,12 +72,12 @@ class _ContactListScreenState extends State<ContactListScreen> { ...@@ -72,12 +72,12 @@ class _ContactListScreenState extends State<ContactListScreen> {
// Clean phone number // Clean phone number
final cleanPhoneNumber = _cleanPhoneNumber(phoneNumber); final cleanPhoneNumber = _cleanPhoneNumber(phoneNumber);
// Instead of inserting contact, open system form // Instead of inserting contact, open system form
final newContact = Contact() final newContact = Contact()
..name = Name(first: name) ..name = Name(first: name)
..phones = [Phone(cleanPhoneNumber)]; ..phones = [Phone(cleanPhoneNumber)];
// 🟢 This opens the phone’s native “Add contact” screen (prefilled) // This opens the phone’s native “Add contact” screen (prefilled)
await FlutterContacts.openExternalInsert(newContact); await FlutterContacts.openExternalInsert(newContact);
// Hide loading // Hide loading
......
...@@ -25,6 +25,7 @@ export 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart'; ...@@ -25,6 +25,7 @@ export 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart';
export 'package:generp/Notifiers/commonProvider/accountsListProvider.dart'; export 'package:generp/Notifiers/commonProvider/accountsListProvider.dart';
export 'package:generp/Notifiers/commonProvider/commonPagesProvider.dart'; export 'package:generp/Notifiers/commonProvider/commonPagesProvider.dart';
export 'package:generp/Notifiers/commonProvider/accountLedgerProvider.dart'; export 'package:generp/Notifiers/commonProvider/accountLedgerProvider.dart';
export 'package:generp/Notifiers/commonProvider/editCommonAccountProvider.dart';
export 'package:generp/Notifiers/financeProvider/DashboardProvider.dart'; export 'package:generp/Notifiers/financeProvider/DashboardProvider.dart';
export 'package:generp/Notifiers/financeProvider/RequestionListProvider.dart'; export 'package:generp/Notifiers/financeProvider/RequestionListProvider.dart';
...@@ -56,6 +57,7 @@ export 'package:generp/Notifiers/crmProvider/addProspectLeadsProvider.dart'; ...@@ -56,6 +57,7 @@ export 'package:generp/Notifiers/crmProvider/addProspectLeadsProvider.dart';
export 'package:generp/Notifiers/crmProvider/followUpUpdateProvider.dart'; export 'package:generp/Notifiers/crmProvider/followUpUpdateProvider.dart';
export 'package:generp/Notifiers/crmProvider/appointmentCalendarProvider.dart'; export 'package:generp/Notifiers/crmProvider/appointmentCalendarProvider.dart';
export 'package:generp/Notifiers/crmProvider/addNewLeadsandProspectsProvider.dart'; export 'package:generp/Notifiers/crmProvider/addNewLeadsandProspectsProvider.dart';
export 'package:generp/Notifiers/crmProvider/CrmNearByGeneratorsProvider.dart';
export 'package:generp/Notifiers/hrmProvider/hrmAccessiblePagesProvider.dart'; export 'package:generp/Notifiers/hrmProvider/hrmAccessiblePagesProvider.dart';
export 'package:generp/Notifiers/hrmProvider/attendanceListProvider.dart'; export 'package:generp/Notifiers/hrmProvider/attendanceListProvider.dart';
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment