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 {
ChangeNotifierProvider(create: (_) => CasualLeaveHistoryProvider()),
ChangeNotifierProvider(create: (_) => ContactProvider()),
ChangeNotifierProvider(create: (_) => QrProvider()),
ChangeNotifierProvider(create: (_) => CrmNearByGeneratorsProvider()),
ChangeNotifierProvider(create: (_) => EditCommonAccountProvider()),
],
child: Builder(
builder: (BuildContext context) {
......
......@@ -117,7 +117,17 @@ class _AccountslistState extends State<Accountslist> {
return (connection == "Online")
? Platform.isAndroid
? 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(
top: false,
bottom: true,
......
......@@ -8,11 +8,13 @@ import 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:generp/Utils/commonServices.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/finance/submitPaymentRequestionListsByMode.dart';
import 'package:provider/provider.dart';
import '../../Models/commonModels/commonAccountdetailsResponse.dart';
import 'addCommonPayment.dart';
class Accountslistdetails extends StatefulWidget {
final accountID;
......@@ -131,7 +133,13 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
),
resizeToAvoidBottomInset: true,
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: Column(
crossAxisAlignment: CrossAxisAlignment.start,
......@@ -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(
......@@ -762,41 +791,41 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
),
),
Spacer(),
Expanded(
flex: 3,
child: SizedBox(
child: RichText(
maxLines: 1,
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
text: TextSpan(
children: [
TextSpan(
text: "Bal: ",
style: TextStyle(
color:
AppColors
.semi_black,
fontSize: 12,
fontFamily:
"JakartaRegular",
),
),
TextSpan(
text: "$runningBalance",
style: TextStyle(
color:
AppColors.grey_semi,
fontSize: 12,
fontFamily:
"JakartaMedium",
),
),
],
),
),
),
),
// Expanded(
// flex: 3,
// child: SizedBox(
// child: RichText(
// maxLines: 1,
// textAlign: TextAlign.right,
// overflow: TextOverflow.ellipsis,
// text: TextSpan(
// children: [
// TextSpan(
// text: "Bal: ",
// style: TextStyle(
// color:
// AppColors
// .semi_black,
// fontSize: 12,
// fontFamily:
// "JakartaRegular",
// ),
// ),
// TextSpan(
// text: "$runningBalance",
// style: TextStyle(
// color:
// AppColors.grey_semi,
// fontSize: 12,
// fontFamily:
// "JakartaMedium",
// ),
// ),
// ],
// ),
// ),
// ),
// ),
],
),
],
......@@ -857,7 +886,9 @@ class _AccountslistdetailsState extends State<Accountslistdetails> {
],
),
),
),
);
}
)
);
},
);
......
......@@ -31,7 +31,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
Dropdowntheme ddtheme = Dropdowntheme();
int _currentStep = 0;
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};
final MyConnectivity _connectivity = MyConnectivity.instance;
......@@ -274,7 +274,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
// custom continue logic:
if (_currentStep == 0) {
// validate step1 via provider
if (provider.validateStep1()) {
if (provider.validateStep1(context)) {
setState(() => _currentStep = 1);
} else {
// show error (provider sets errors and notifies)
......@@ -337,7 +337,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
setState(() => _currentStep = 0);
} else if (value == 1) {
// user wants to jump to step 1 - ensure step 0 valid
if (provider.validateStep1()) {
if (provider.validateStep1(context)) {
setState(() => _currentStep = 1);
} else {
provider.notifyListeners();
......@@ -345,7 +345,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
}
} else if (value == 2) {
// allow jump if step0 valid; step1 optional
if (provider.validateStep1()) {
if (provider.validateStep1(context)) {
setState(() => _currentStep = 2);
} else {
provider.notifyListeners();
......@@ -353,7 +353,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
}
} else if (value == 3) {
// final - require step0 valid
if (!provider.validateStep1()) {
if (!provider.validateStep1(context)) {
provider.notifyListeners();
setState(() => _currentStep = 0);
return;
......@@ -442,6 +442,9 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
(p0) {
provider.updateName(p0);
provider.checkInputsAPI(context, "name", provider.nameController.text);
// Recompare with GST response if exists
provider.recheckNameWithGst();
},
TextInputType.text,
false,
......@@ -708,52 +711,120 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// GST field - if provided, validate and autofill address; compare company name
textControllerWidget(
context,
provider.gstNumberController,
"GST Number",
"Enter GST Number",
(val) async {
// when user types, just update; validation on field submit
provider.gstNumberController.text = val;
// GST field (unique focus node 9). Only one GST widget here.
Text("GST Number"),
const SizedBox(height: 6),
TextFormField(
controller: provider.gstNumberController,
focusNode: focusNodes[9],
textInputAction: TextInputAction.done,
keyboardType: TextInputType.text,
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();
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),
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(
context,
provider.bankAcNumberController,
"Bank Account Number",
"Enter Bank Account Number",
(p0) {
// update provider value and trigger bank validation if IFSC already present
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) {
_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,
false,
FilteringTextInputFormatter.digitsOnly,
focusNodes[10],
focusNodes[11],
focusNodes[10], // bank account unique
focusNodes[8], // move to IFSC next
TextInputAction.next,
),
const SizedBox(height: 4),
errorWidget(context, provider.bankAcNumberError),
// IFSC
// Bank IFSC
textControllerWidget(
context,
provider.bankIfscCotroller,
......@@ -761,28 +832,46 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
"Enter Bank IFSC",
(p0) {
provider.updateIFSC(p0);
// validate IFSC format locally; if good and account present, trigger server validation
if (_isIfscValidFormat(p0) && provider.bankAcNumberController.text.trim().isNotEmpty) {
_validateBankIfNeeded(provider);
// local IFSC format check
final reg = RegExp(r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$');
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 {
if (p0.trim().isNotEmpty && !_isIfscValidFormat(p0)) {
provider.bankIFSCError = null;
provider.notifyListeners();
}
return;
}
if (!reg.hasMatch(p0.trim())) {
provider.bankIFSCError = "Invalid IFSC format";
provider.notifyListeners();
return;
} else {
provider.bankIFSCError = null;
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,
false,
null,
focusNodes[8],
focusNodes[9],
focusNodes[8], // unique IFSC focus
focusNodes[11], // next focus after IFSC (holder / or UPI)
TextInputAction.next,
),
const SizedBox(height: 4),
errorWidget(context, provider.bankIFSCError),
// Bank Name (autofill)
const SizedBox(height: 8),
// Bank Name (autofill by API) (unique focus node 6)
textControllerWidget(
context,
provider.bankNameController,
......@@ -797,7 +886,10 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputAction.next,
),
errorWidget(context, provider.banknameError),
// Branch
const SizedBox(height: 8),
// Branch (unique focus node 7)
textControllerWidget(
context,
provider.branchNameController,
......@@ -808,11 +900,14 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
false,
null,
focusNodes[7],
focusNodes[8],
focusNodes[11],
TextInputAction.next,
),
errorWidget(context, provider.bankBranchError),
// Holder
const SizedBox(height: 8),
// Bank Holder Name (unique focus node 11) — previously incorrectly used 9
textControllerWidget(
context,
provider.bankHolderNameController,
......@@ -822,12 +917,16 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputType.text,
false,
null,
focusNodes[9],
focusNodes[10],
focusNodes[11], // <-- corrected unique index
focusNodes[12],
TextInputAction.next,
),
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(
context,
provider.bankUpiController,
......@@ -837,8 +936,8 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
TextInputType.text,
false,
null,
focusNodes[11],
focusNodes[12],
focusNodes[17], //
focusNodes[18], // next focus
TextInputAction.next,
),
errorWidget(context, provider.upiError),
......@@ -973,6 +1072,23 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
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
provider.submitClickced = true;
provider.notifyListeners();
......@@ -994,7 +1110,7 @@ class _AddcommonpaymentState extends State<Addcommonpayment> {
onTap: () {
setState(() {
if (_currentStep == 0) {
if (provider.validateStep1()) {
if (provider.validateStep1(context)) {
_currentStep = 1;
} else {
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> {
),
child: Consumer<Leadlistprovider>(
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(
(element) => element == true,
);
......@@ -373,6 +386,22 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
if (widget.mode != "executive") {
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(
height: MediaQuery.of(context).size.height * 0.7,
child: Column(
......@@ -512,17 +541,12 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
mainAxisSize: MainAxisSize.min,
children: [
if (selectedIndex == 0) ...[
...provider.leadStatusList.map((
status,
) {
...provider.leadStatusList.map((status,) {// here i want to do that i want to show selected from widget.filter!.status,
return SizedBox(
height: 35,
child: CheckboxListTile(
activeColor:
AppColors.app_blue,
controlAffinity:
ListTileControlAffinity
.leading,
activeColor: AppColors.app_blue,
controlAffinity: ListTileControlAffinity.leading,
checkboxShape: CircleBorder(
side: BorderSide(
width: 0.5,
......@@ -568,7 +592,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
width: 0.5,
),
),
title: Text(
title: Text(// same here widget.filter!.openStatus,
status ?? 'Unknown Status',
style: const TextStyle(
fontSize: 14,
......@@ -963,6 +987,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
},
);
}
void _showContactOptions(BuildContext context, String? phoneNumber) {
if (phoneNumber == null || phoneNumber.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
......
......@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.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/appointmentCalendar.dart';
import 'package:generp/screens/crm/followUpListonType.dart';
......@@ -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) ...[
Align(
......
......@@ -359,16 +359,19 @@ class _AttendanceRequestDetailScreenState
"Other Details",
scaleFactor,
),
if (details.type == "Check In" || details.type == "Check In/Out")
_buildDetailTile(
"Check In Type",
details.checkInType,
scaleFactor,
),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile(
"Check Out Type",
details.chechOutType,
scaleFactor,
),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile(
"Check Out Time",
details.checkOutTime,
......
......@@ -72,12 +72,12 @@ class _ContactListScreenState extends State<ContactListScreen> {
// Clean phone number
final cleanPhoneNumber = _cleanPhoneNumber(phoneNumber);
// Instead of inserting contact, open system form
// Instead of inserting contact, open system form
final newContact = Contact()
..name = Name(first: name)
..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);
// Hide loading
......
......@@ -25,6 +25,7 @@ export 'package:generp/Notifiers/commonProvider/accountDetailsProvider.dart';
export 'package:generp/Notifiers/commonProvider/accountsListProvider.dart';
export 'package:generp/Notifiers/commonProvider/commonPagesProvider.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/RequestionListProvider.dart';
......@@ -56,6 +57,7 @@ export 'package:generp/Notifiers/crmProvider/addProspectLeadsProvider.dart';
export 'package:generp/Notifiers/crmProvider/followUpUpdateProvider.dart';
export 'package:generp/Notifiers/crmProvider/appointmentCalendarProvider.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/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