You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1831 lines
76 KiB

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:bookatanker/common/settings.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:bookatanker/supplier/filter_screen.dart';
import 'package:bookatanker/supplier/plans/plan_suppliers_model.dart';
import 'package:bookatanker/supplier/supplier_details.dart';
import 'package:bookatanker/supplier/supplier_details_from_search.dart';
import 'package:bookatanker/supplier/suppliers_model.dart';
class PlanRequestScreen extends StatefulWidget {
const PlanRequestScreen({super.key});
@override
State<PlanRequestScreen> createState() => _PlanRequestScreenState();
}
class _PlanRequestScreenState extends State<PlanRequestScreen> {
String? selectedWaterType;
String? selectedFrequency;
String? selectedCapacity;
String? selectedQuantity;
String? selectedTime;
DateTime? selectStartDate;
DateTime? selectStopDate;
List<PlanSuppliersModel> PlanSuppliersList = [];
bool isDataLoading = false;
bool isSearchEnabled = false;
int sentRequests = 0;
int maxRequests = 5;
DateTime? firstRequestTime;
Timer? _resetTimer;
Timer? _countdownTimer;
String remainingTime = '';
double progress = 1.0;
int totalCooldown = 900; // 15 minutes in seconds
RangeValues? selectedRadius;
RangeValues? selectedRating;
RangeValues? selectedPrice;
String? selectedPump;
bool filterAll = true, filterConnected = false, filterNotConnected = false;
final TextEditingController _quotedAmountController = TextEditingController();
// TimeOfDay _selectedTime = (TimeOfDay.now());
final List<String> waterTypes = ['Drinking Water', 'Bore water'];
final List<String> frequencyTypes = ['Daily', 'Weekly Once','Weekly Twice','Weekly Thrice'];
final List<String> capacities = [
'1,000 L',
'2,000 L',
'3,000 L',
'5,000 L',
'10,000 L',
'20,000 L'
];
final List<String> quantities = ['1', '2', '3'];
final List<String> timeSlots = ['8 AM', '12 PM', '4 PM', '8 PM'];
@override
void initState() {
// TODO: implement initState
super.initState();
_selectedTime = _roundToNextHour(TimeOfDay.now());
_loadRequestState();
// Defer the bottom sheet call until after build
WidgetsBinding.instance.addPostFrameCallback((_) {
_showLocationBottomSheet();
});
}
@override
void dispose() {
_countdownTimer?.cancel();
_quotedAmountController.dispose();
super.dispose();
}
Future<void> _loadRequestState() async {
List<DateTime> validTimes = await _getValidRequestTimes();
validTimes.sort(); // Ensure chronological order
setState(() {
sentRequests = validTimes.length;
});
if (validTimes.isNotEmpty) {
final firstExpiry = validTimes.first.add(Duration(minutes: 15));
final remaining = firstExpiry.difference(DateTime.now()).inSeconds;
if (remaining > 0) {
_startCountdownTimer(remaining);
}
}
}
Future<List<DateTime>> _getValidRequestTimes() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final rawList = prefs.getStringList('requestTimes') ?? [];
final now = DateTime.now();
final validTimes = rawList
.map((s) => DateTime.tryParse(s))
.whereType<DateTime>()
.where((t) => now.difference(t).inMinutes < 15)
.toList();
return validTimes;
}
Future<void> _saveRequestTimes(List<DateTime> times) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList('requestTimes', times.map((e) => e.toIso8601String()).toList());
}
void _startCountdownTimer(int totalSeconds) {
_countdownTimer?.cancel();
totalCooldown = totalSeconds;
progress = 1.0;
_countdownTimer = Timer.periodic(Duration(seconds: 1), (timer) async {
final elapsed = timer.tick;
final remaining = totalSeconds - elapsed;
if (remaining <= 0) {
timer.cancel();
// 🧹 Clean expired request times
List<DateTime> updatedTimes = await _getValidRequestTimes();
updatedTimes.sort(); // Ensure order
await _saveRequestTimes(updatedTimes);
setState(() {
sentRequests = updatedTimes.length;
remainingTime = '';
progress = 0.0;
});
// 🕐 If more valid requests remain, restart countdown with new first one
if (updatedTimes.isNotEmpty) {
final nextExpiry = updatedTimes.first.add(Duration(minutes: 15));
final newRemaining = nextExpiry.difference(DateTime.now()).inSeconds;
if (newRemaining > 0) {
_startCountdownTimer(newRemaining);
}
}
} else {
final minutes = (remaining ~/ 60).toString().padLeft(2, '0');
final seconds = (remaining % 60).toString().padLeft(2, '0');
setState(() {
remainingTime = "$minutes:$seconds";
progress = remaining / totalCooldown;
});
}
});
}
void _showLocationBottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: false,
enableDrag: false, // 🔒 Prevents dragging
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
padding: EdgeInsets.all(16),
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.45,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Confirm Address?",
style: fontTextStyle(16, Color(0XFF343637), FontWeight.w600),
),
SizedBox(height: MediaQuery.of(context).size.height * .024),
Row(
children: [
Text(
"Your current selected address is",
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w600),
),
SizedBox(width: MediaQuery.of(context).size.width * .004),
Text(
"HOME",
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w600),
),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
Row(
children: [
Image.asset(
'images/marker-pin.png',
width: 24,
height: 24,
),
SizedBox(width: MediaQuery.of(context).size.width * .024),
Expanded(
child: Text(
AppSettings.userAddress,
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
)
],
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: GestureDetector(
onTap: () {
// Optional: handle "Change"
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: Color(0XFF939495)),
borderRadius: BorderRadius.circular(24),
),
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 12),
child: Text(
'Change',
style: fontTextStyle(14, Color(0XFF939495), FontWeight.w600),
),
),
),
),
SizedBox(width: MediaQuery.of(context).size.width * .010),
Expanded(
child: GestureDetector(
onTap: () {
Navigator.pop(context);
/* setState(() {
_isConfirmed = true;
});*/
},
child: Container(
decoration: BoxDecoration(
color: Color(0XFF1D7AFC),
border: Border.all(width: 1, color: Colors.white),
borderRadius: BorderRadius.circular(24),
),
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 12),
child: Text(
'Confirm',
style: fontTextStyle(14, Colors.white, FontWeight.w600),
),
),
),
),
],
),
],
),
),
),
);
},
);
}
TimeOfDay _roundToNextHour(TimeOfDay time) {
int nextHour = (time.minute > 0) ? (time.hour + 1) % 24 : time.hour;
return TimeOfDay(hour: nextHour, minute: 0);
}
void sendRequest() {
if (sentRequests < maxRequests) {
setState(() {
sentRequests++;
});
}
}
Future<void> _selectFromDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectStartDate ?? DateTime.now(),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 3)),
helpText: 'Select Date',
initialEntryMode: DatePickerEntryMode.calendarOnly,
builder: (BuildContext context, Widget? child) {
return Theme(
data: ThemeData.light().copyWith(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none, // Removes the text field border
),
colorScheme: ColorScheme.light(
primary: Color(0XFF1D7AFC),
onPrimary: Color(0XFFFFFFFF), // Header text color
surface: Color(0XFFFFFFFF),
onSurface: Colors.black,
secondary: Colors.pink,
),
dividerColor: Color(0XFFF5F6F6),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(
Color(0XFF1D7AFC),
), // Text color
//backgroundColor: MaterialStateProperty.all(Colors.grey[200]), // Background
textStyle: MaterialStateProperty.all(
fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
), // Font style
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))), // Rounded corners
),
// Background of the dialog box
),
textTheme: TextTheme(
bodyLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
labelLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
titleLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
headlineLarge:
fontTextStyle(20, Color(0XFF1D7AFC), FontWeight.w600),
),
),
child: child!,
);
},
);
if (picked != null) {
setState(() {
selectStartDate = picked;
//toDate1 = null; // Reset To Date
//toDateController1.clear();
});
}
}
Future<void> _selectToDate(BuildContext context) async {
if (selectStartDate == null) {
// Handle case when start date is not selected
return;
}
final DateTime firstDate = selectStartDate!;
final DateTime lastDate = DateTime(
firstDate.year,
firstDate.month + 1,
firstDate.day,
);
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectStopDate ?? firstDate,
firstDate: firstDate,
lastDate: lastDate,
helpText: 'Select Date',
initialEntryMode: DatePickerEntryMode.calendarOnly,
builder: (BuildContext context, Widget? child) {
return Theme(
data: ThemeData.light().copyWith(
inputDecorationTheme: const InputDecorationTheme(
border: InputBorder.none,
),
colorScheme: const ColorScheme.light(
primary: Color(0XFF1D7AFC),
onPrimary: Colors.white,
surface: Colors.white,
onSurface: Colors.black,
secondary: Colors.pink,
),
dividerColor: Color(0XFFF5F6F6),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
foregroundColor: MaterialStatePropertyAll(Color(0XFF1D7AFC)),
textStyle: MaterialStatePropertyAll(
fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
),
shape: MaterialStatePropertyAll(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
),
),
),
textTheme: TextTheme(
bodyLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
labelLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
titleLarge: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
headlineLarge: fontTextStyle(20, Color(0XFF1D7AFC), FontWeight.w600),
),
),
child: child ?? const SizedBox.shrink(),
);
},
);
if (picked != null) {
setState(() {
selectStopDate = picked;
});
}
}
TimeOfDay _selectedTime = TimeOfDay.now();
String _timeRangeText = '';
Future<void> _selectTime(BuildContext context) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: _selectedTime,
cancelText: 'Cancel',
confirmText: 'Confirm',
builder: (BuildContext context, Widget? child) {
return Theme(
data: ThemeData.light().copyWith(
primaryColor: Color(0XFF1D7AFC),
timePickerTheme: TimePickerThemeData(
backgroundColor: Colors.white,
dialBackgroundColor: Colors.white,
hourMinuteTextColor: Color(0XFF1D7AFC),
dayPeriodTextColor: Color(0XFF1D7AFC),
dialTextColor: Color(0XFF1D7AFC),
dayPeriodColor: Color(0XFFC3C4C4),
hourMinuteShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: Color(0XFFFFFFFF), width: 2),
),
dayPeriodShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
dialHandColor: Color(0XFFC3C4C4),
hourMinuteColor: Color(0XFFFFFFFF),
dialTextStyle:
TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
dayPeriodTextStyle:
TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
hourMinuteTextStyle:
TextStyle(fontSize: 50, fontWeight: FontWeight.w600),
helpTextStyle:
TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
),
),
child: child!,
);
},
);
if (picked != null) {
final now = TimeOfDay.now();
final today = DateTime.now();
final isToday = selectStartDate?.day == today.day &&
selectStartDate?.month == today.month &&
selectStartDate?.year == today.year;
bool isValid = true;
if (isToday) {
final nowMinutes = now.hour * 60 + now.minute;
final pickedMinutes = picked.hour * 60 + picked.minute;
isValid = pickedMinutes >= nowMinutes;
}
if (isValid) {
setState(() {
_selectedTime = picked;
_timeRangeText = _formatTimeRange(_selectedTime);
});
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Please select a time after the current time.")),
);
}
}
}
String _formatTimeRange(TimeOfDay start) {
final endHour = (start.hour + 2) % 24;
final end = TimeOfDay(hour: endHour, minute: start.minute);
return '${_formatTime(start)} to ${_formatTime(end)}';
}
String _formatTime(TimeOfDay time) {
final now = DateTime.now();
final dt = DateTime(now.year, now.month, now.day, time.hour, time.minute);
return TimeOfDay.fromDateTime(dt).format(context);
}
Widget _beforeDataScreen() {
return Padding(padding: EdgeInsets.fromLTRB(16, 0, 16, 0),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
"Whats new?",
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
RichText(
text: TextSpan(
text: "Find ",
style: fontTextStyle(20, Color(0XFF343637), FontWeight.w600),
children: [
TextSpan(
text: "exclusive offers",
style: fontTextStyle(20, Color(0XFF8270DB), FontWeight.w600),
),
TextSpan(
text: " & best deals available for you.",
style: fontTextStyle(20, Color(0XFF343637), FontWeight.w600),
),
],
),
),
SizedBox(height: MediaQuery.of(context).size.height * .024),
Container(
height: 80,
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
colors: [
Color(0xFFFFFFFF),
Color(0xFFE2DCFF)
], // Light gradient background
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
border: Border.all(color: Color(0xFF8270DB)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'AQUINTO',
style:
fontTextStyle(20, Color(0XFF8270DB), FontWeight.w800),
),
SizedBox(height: MediaQuery.of(context).size.height * .004),
Text(
'Your Water, Your Data, Your Control.',
style:
fontTextStyle(12, Color(0XFF8270DB), FontWeight.w500),
),
],
),
/*Image.asset(
'images/WaterTankImage.png', // Replace with your actual image asset path
height: 40,
width: 40,
fit: BoxFit.contain,
),*/
],
),
)
],
),);
}
Widget _beforeDataScreenAbove() {
return Column(
children: [
SizedBox(height: MediaQuery.of(context).size.height * .024),
CircleAvatar(radius: 80, backgroundColor: Colors.grey.shade300),
SizedBox(height: MediaQuery.of(context).size.height * .016),
Center(
child: Text("Plans",
style: fontTextStyle(20, Color(0XFF000000), FontWeight.w600)),
),
SizedBox(height: MediaQuery.of(context).size.height * .008),
Text(
"No more last-minute orders! Set up a regular water delivery schedule with this supplier and stay stress-free",
textAlign: TextAlign.center,
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
],
);
}
Widget _suppliersDataScreen() {
if (isDataLoading) {
return Center(
child: CircularProgressIndicator(
color: primaryColor,
strokeWidth: 5.0,
),
);
}
if (PlanSuppliersList.isEmpty) {
return Center(
child: Text(
'No Data Available',
style: fontTextStyle(12, Color(0XFF000000), FontWeight.w500),
),
);
}
return Container(
color: Color(0xFFF1F1F1), // Set your desired background color
padding: EdgeInsets.fromLTRB(16, 0, 16, 0),
child: Column(
children: [
Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 12),
decoration: BoxDecoration(
color: Color(0xFFF1F1F1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Row(
children: [
Image.asset(
'images/info.png',
fit: BoxFit.cover,
width:
16, // Match the diameter of the CircleAvatar
height: 16,
),
SizedBox(
width: MediaQuery.of(context).size.width * .008,
),
Text(
"Plan requests sent",
style: fontTextStyle(14, Color(0XFF2D2E30), FontWeight.w600),
),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),
Text("$sentRequests/$maxRequests",style: fontTextStyle(14, Color(0XFF515253), FontWeight.w600),),
Spacer(),
Text("$remainingTime",style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .016,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(maxRequests, (index) {
return Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 4),
height: 3,
decoration: BoxDecoration(
color: index < sentRequests
?Color(0XFF114690)
:Color(0XFF939495),
borderRadius: BorderRadius.circular(2),
),
),
);
}),
),
Padding(
padding: EdgeInsets.only(top: 12, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
border: Border.all(color: Color(0XFF515253)),
borderRadius: BorderRadius.circular(45),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
'images/sort.png',
width: 12,
height: 12,
color: Color(0XFF515253),
fit: BoxFit.contain,
),
SizedBox(width: MediaQuery.of(context).size.width * .008),
Text(
"Sort",
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
SizedBox(width: MediaQuery.of(context).size.width * .008),
Image.asset(
'images/arrow_down.png',
width: 16,
height: 16,
color: Color(0XFF515253),
fit: BoxFit.contain,
),
],
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * .016,
),
GestureDetector(
onTap: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (_) => FilterScreen(
initialFilters: {
'all': filterAll,
'connected': filterConnected,
'notConnected': filterNotConnected,
'radiusRange': selectedRadius,
'ratingRange': selectedRating,
'priceRange': selectedPrice,
'pumpChoice': selectedPump,
},
),
),
);
if (result != null && result is Map) {
setState(() {
filterAll = result['all'];
filterConnected = result['connected'];
filterNotConnected = result['notConnected'];
selectedRadius = result['radiusRange'];
selectedRating = result['ratingRange'];
selectedPrice = result['priceRange'];
selectedPump = result['pumpChoice'];
});
await getAllSuppliersPlans();
}
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
border: Border.all(color: Color(0XFF515253)),
borderRadius: BorderRadius.circular(45),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
'images/filter.png',
width: 12,
height: 12,
color: Color(0XFF515253),
fit: BoxFit.contain,
),
SizedBox(width: MediaQuery.of(context).size.width * .008),
Text(
"Filter",
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
],
),
),
)
],
),
)
],
)),
],
),
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: PlanSuppliersList.length,
separatorBuilder: (context, index) => SizedBox(
height: MediaQuery.of(context).size.height * .008,
),
itemBuilder: (BuildContext context, int index) {
//final supplier = SuppliersList[index];
return GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SupplierScreenFromSearch(details: PlanSuppliersList[index],)),
);
},
child:Card(
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: EdgeInsets.all(12),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 25,
backgroundColor: Color(0XFFE8F2FF),
child: Image.asset(
'images/profile_user.png',
fit: BoxFit.cover,
width: 50,
height: 50,
),
),
SizedBox(
width: MediaQuery.of(context).size.width * .024,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Name and Rating Row
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
PlanSuppliersList[index].supplier_name,
style: fontTextStyle(16,
Color(0XFF2D2E30), FontWeight.w600),
overflow: TextOverflow.ellipsis,
),
),
Row(
children: [
Image.asset(
'images/star.png',
width: 16,
height: 16,
),
SizedBox(
width:
MediaQuery.of(context).size.width *
.008,
),
Text(
'4.2',
style: fontTextStyle(10,
Color(0XFF515253), FontWeight.w400),
),
],
),
],
),
SizedBox(
height:
MediaQuery.of(context).size.height * .004,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Drinking | Bore Water',
style: fontTextStyle(
12, Color(0XFF4692FD), FontWeight.w500),
),
Text(
PlanSuppliersList[index].matchedPrice.toString()!="null"&&PlanSuppliersList[index].matchedPrice.toString()!=""
""? '\u20B9 ${AppSettings.formDouble(PlanSuppliersList[index].matchedPrice.toString())}': '',
style: fontTextStyle(10, Color(0XFF515253), FontWeight.w400),
),
],
),
SizedBox(
height:
MediaQuery.of(context).size.height * .004,
),
/// Address and Favourite
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
'${PlanSuppliersList[index].displayAddress} ${PlanSuppliersList[index].distanceInMeters} Km',
style: fontTextStyle(12,
Color(0XFF515253), FontWeight.w400),
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
onTap: () async {
AppSettings.preLoaderDialog(context);
if (PlanSuppliersList[index].isFavorite) {
try {
bool tankerResponse =
await AppSettings
.removeFavourites(
PlanSuppliersList[index]
.supplier_id);
if (tankerResponse) {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longSuccessToast(
'Supplier removed from favourites');
await getAllSuppliersPlans();
// await getConnectedSuppliersData();
} else {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longFailedToast(
'Failed to remove from favourites');
}
} catch (e) {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longFailedToast(
'Failed to remove from favourites');
}
} else {
try {
bool tankerResponse =
await AppSettings.addFavourites(
PlanSuppliersList[index]
.supplier_id);
if (tankerResponse) {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longSuccessToast(
'Supplier added to favourites');
await getAllSuppliersPlans();
//await getConnectedSuppliersData();
//await getAllFavouritesData();
} else {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longFailedToast(
'Failed to add favourites');
}
} catch (e) {
Navigator.of(context,
rootNavigator: true)
.pop();
AppSettings.longFailedToast(
'Failed to add favourites');
}
}
},
child: Image.asset(
PlanSuppliersList[index].isFavorite
? 'images/heart_active.png'
: 'images/heart_outline.png',
width: 20,
height: 20,
),
),
],
),
],
),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .016,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: GestureDetector(
onTap: () {},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Color(0XFFFFFFFF),
border: Border.all(
width: 1,
color: PlanSuppliersList[index].isRequetsedBooking?Color(0XFF1D7AFC):Color(0XFF939495),
),
borderRadius: BorderRadius.circular(
24,
)),
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.fromLTRB(16, 12, 16, 12),
child: Text('Call',
style: fontTextStyle(12, PlanSuppliersList[index].isRequetsedBooking?Color(0XFF1D7AFC):Color(0XFF939495),
FontWeight.w600)),
),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * .010,
),
Expanded(
child: GestureDetector(
onTap: () async{
if(!PlanSuppliersList[index].isRequetsedBooking){
requestPlanDialog(PlanSuppliersList[index]);
}
/* Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PlaceOrder(details: connectedSuppliersList[index],)),
);*/
},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: PlanSuppliersList[index].isRequetsedBooking?Color(0XFFDBDBDC):Color(0XFF1D7AFC),
border: Border.all(
width: 1,
color: Color(0XFFFFFFFF),
),
borderRadius: BorderRadius.circular(
24,
)),
alignment: Alignment.center,//
child: Padding(
padding: EdgeInsets.fromLTRB(16, 12, 16, 12),
child: Text('Request plan',
style: fontTextStyle(12, Color(0XFFFFFFFF), FontWeight.w600)),
),
),
))
],
)
],
),
),
) ,
)
;
},
)
],
),
);
}
requestPlanDialog(var details) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return AlertDialog(
backgroundColor: Color(0XFFFFFFFF),// Set your desired background color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), // Optional: Rounded corners
),
title: Center(child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text('ORDER DETAILS',style:fontTextStyle(16,Color(0XFF646566),FontWeight.w400)),
),
SizedBox(height: MediaQuery.of(context).size.height * .024,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Water Type',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(selectedWaterType!,style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500)),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Capacity',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(selectedCapacity!,style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500)),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Quantity',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(selectedQuantity!,style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500)),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Start Date',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(DateFormat('dd-MMM-yyyy').format(selectStartDate!),style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500)),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('End Date',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(DateFormat('dd-MMM-yyyy').format(selectStopDate!),style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500)),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Actual Price',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
Text(
details.matchedPrice.toString()!="null"&&details.matchedPrice.toString()!=""
""? '\u20B9 ${AppSettings.formDouble(details.matchedPrice.toString())}': '',
style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500),
),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .010,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Your Price',style:fontTextStyle(14,Color(0XFF646566),FontWeight.w500)),
SizedBox(
width: MediaQuery.of(context).size.width * 0.4, // Adjust width as needed
child: TextFormField(
controller: _quotedAmountController,
keyboardType: TextInputType.number,
textCapitalization: TextCapitalization.sentences,
maxLength: 10,
decoration: textFormFieldDecoration(Icons.phone,''),
style:fontTextStyle(14,Color(0XFF2D2E30),FontWeight.w500),
cursorColor: Color(0XFF1D7AFC),
//TextStyle(color: Colors.black,fontWeight: FontWeight.bold),
)
),
],
),
],
),),
actions: <Widget>[
Center(
child: Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Color(0XFF1D7AFC), width: 1),
borderRadius: BorderRadius.circular(24),
),
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Text(
'Cancel',
style: fontTextStyle(14, Color(0XFF1D7AFC), FontWeight.w600),
),
),
),
),
),
SizedBox(width: MediaQuery.of(context).size.width * .010,),
Expanded(
child: GestureDetector(
onTap: () async {
final now = DateTime.now();
List<DateTime> validTimes = await _getValidRequestTimes();
if (validTimes.length >= maxRequests) {
AppSettings.longFailedToast("Maximum 5 requests allowed in any 15-minute window.");
return;
}
final text = _quotedAmountController.text.trim();
if (text.isEmpty) return;
final quoted = int.tryParse(text);
if (quoted == null) {
AppSettings.longFailedToast("Invalid number");
return;
}
int matched = int.parse(details.matchedPrice);
if (quoted > matched + 300 || quoted < matched - 300) {
AppSettings.longFailedToast("Enter less than 300 within matched price ${details.matchedPrice}");
return;
}
AppSettings.preLoaderDialog(context);
bool isOnline = await AppSettings.internetConnectivity();
if (!isOnline) {
Navigator.of(context, rootNavigator: true).pop();
AppSettings.longFailedToast("Check your internet connection.");
return;
}
String freq='';
if(selectedFrequency.toString().toLowerCase()=='daily'){
freq='daily';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly once'){
freq='weekly_once';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly twice'){
freq='weekly_twice';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly thrice'){
freq='weekly_thrice';
}
var payload = {
"customerId": AppSettings.customerId,
"type_of_water":selectedWaterType,
"capacity":selectedCapacity,
"quantity":selectedQuantity,
"start_date": DateFormat('dd-MMM-yyyy').format(selectStartDate!),
"end_date": DateFormat('dd-MMM-yyyy').format(selectStopDate!),
"time": DateFormat('dd-MM-yyyy HH:mm').format(now),
"frequency": freq,
"weekly_count": 1,
"requested_suppliers": [
{
"supplierId": details.supplier_id,
"quoted_amount": quoted,
"time": DateFormat('dd-MM-yyyy HH:mm').format(now),
}
],
};
bool status = await AppSettings.requestPlan(payload);
Navigator.of(context, rootNavigator: true).pop();
if (status) {
_quotedAmountController.clear();
Navigator.pop(context);
validTimes.add(now);
validTimes.sort();
await _saveRequestTimes(validTimes);
sentRequests = validTimes.length;
if (validTimes.isNotEmpty) {
final firstExpiry = validTimes.first.add(Duration(minutes: 15));
final remaining = firstExpiry.difference(DateTime.now()).inSeconds;
if (remaining > 0) _startCountdownTimer(remaining);
}
setState(() {});
await getAllSuppliersPlans();
AppSettings.longSuccessToast("Request Sent");
} else {
AppSettings.longFailedToast("Request sending failed");
}
/* final text = _quotedAmountController.text.trim();
if (text.isNotEmpty) {
final quoted = int.tryParse(text);
if (quoted == null) {
// Handle invalid number if needed
} else if (quoted > int.parse(details.matchedPrice) + 300 || quoted < int.parse(details.matchedPrice) - 300) {
AppSettings.longFailedToast("Please Enter below 300 or above 300 for the selected tanker price ${details.matchedPrice}");
} else {
AppSettings.preLoaderDialog(context);
bool isOnline = await AppSettings.internetConnectivity();
if (isOnline) {
var payload = <String, dynamic>{
"customerId": AppSettings.customerId,
"type_of_water": selectedWaterType,
"capacity": selectedCapacity,
"quantity": selectedQuantity,
"date": DateFormat('dd-MMM-yyyy').format(selectedDate!), // e.g., '2025-07-01'
"time": _timeRangeText, // e.g., '14:00'
"requested_suppliers": [
{
"supplierId": details.supplier_id,
"quoted_amount": int.parse(_quotedAmountController.text),
"time": DateFormat('dd-MM-yyyy HH:mm').format(DateTime.now()),
}
],
};
bool status = await AppSettings.requestOrder(payload);
if(status){
_quotedAmountController.clear();
Navigator.of(context, rootNavigator: true).pop();
Navigator.pop(context);
await getAllSuppliers();
AppSettings.longSuccessToast("Request Sent");
}
else{
_quotedAmountController.clear();
Navigator.of(context, rootNavigator: true).pop();
AppSettings.longFailedToast("Request sending failed");
}
} else {
Navigator.of(context, rootNavigator: true).pop();
AppSettings.longFailedToast("Please Check internet");
}
}
}*/
},
child: Container(
decoration: BoxDecoration(
color: Color(0XFF1D7AFC),
border: Border.all(color: Color(0XFF1D7AFC), width: 1),
borderRadius: BorderRadius.circular(24),
),
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Text(
'Send Request',
style: fontTextStyle(14, Colors.white, FontWeight.w600),
),
),
),
),
),
],
),
),
],
);
});
});
}
Future<void> getAllSuppliersPlans() async {
AppSettings.preLoaderDialog(context);
bool isOnline = await AppSettings.internetConnectivity();
String freq='';
if(selectedFrequency.toString().toLowerCase()=='daily'){
freq='daily';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly once'){
freq='weekly_once';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly twice'){
freq='weekly_twice';
}
else if(selectedFrequency.toString().toLowerCase()=='weekly thrice'){
freq='weekly_thrice';
}
if (isOnline) {
var payload = new Map<String, dynamic>();
payload["type_of_water"] = selectedWaterType.toString();
payload["capacity"] = selectedCapacity.toString();
payload["quantity"] = selectedQuantity.toString();
payload["frequency"] = freq;
payload["start_date"] = DateFormat('dd-MMM-yyyy').format(selectStartDate!);
payload["end_date"] = DateFormat('dd-MMM-yyyy').format(selectStopDate!);
payload["radius_from"] = selectedRadius?.start.round().toString() ?? "";
payload["radius_to"] = selectedRadius?.end.round().toString() ?? "";
payload["rating_from"] = selectedRating?.start.toString() ?? "";
payload["rating_to"] = selectedRating?.end.toString() ?? "";
payload["price_from"] = selectedPrice?.start.round().toString() ?? "";
payload["price_to"] = selectedPrice?.end.round().toString() ?? "";
payload["pump"] = selectedPump.toString();
setState(() {
isDataLoading = true;
});
try {
var response = await AppSettings.getSuppliersForPlan(payload);
setState(() {
PlanSuppliersList =
((jsonDecode(response)['suppliers']) as List)
.map((dynamic model) {
return PlanSuppliersModel.fromJson(model);
}).toList();
// Clean the selected value: remove comma and " L"
String normalizedSelectedLitres = selectedCapacity!.replaceAll(",", "").replaceAll(" L", "").trim();
List<dynamic> suppliersJson = jsonDecode(response)['suppliers'];
PlanSuppliersList = suppliersJson.map((supplierData) {
List<dynamic> tankers = supplierData['tankers'];
String? matchedPrice;
for (var tanker in tankers) {
String capacity = tanker['capacity'].replaceAll(",", "").trim();
if (capacity == normalizedSelectedLitres) {
matchedPrice = tanker['price'];
break;
}
}
// Optional: attach matchedPrice to model if supported
var supplierModel = PlanSuppliersModel.fromJson(supplierData);
supplierModel.matchedPrice = matchedPrice; // <- Add this field to your model class
return supplierModel;
}).toList();
isDataLoading = false;
Navigator.of(context, rootNavigator: true).pop();
});
} catch (e) {
setState(() {
isDataLoading = false;
Navigator.of(context, rootNavigator: true).pop();
});
}
} else {
AppSettings.longFailedToast('Please check internet connection');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Color(0XFFFFFFFF),
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
title: GestureDetector(
onTap: () {
_showLocationBottomSheet();
},
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisSize:
MainAxisSize.min, // Ensures it doesn't take extra space
children: [
Text(
'Home',
style:
fontTextStyle(16, Color(0XFF232527), FontWeight.w600),
),
SizedBox(width: 5), // Space between text and icon
Image.asset(
'images/arrow_down.png', // Replace with your arrow image
width: 24, // Adjust size
height: 24,
)
],
),
Text(
AppSettings.userAddress,
style:
fontTextStyle(10, Color(0XFF515253), FontWeight.w400),
),
],
)
),
iconTheme: IconThemeData(color: Color(0XFF2A2A2A)),
actions: [
Row(
children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 10, 10, 10),
child: IconButton(
icon: Image.asset(
'images/notification_appbar.png', // Example URL image
),
onPressed: () {},
),
)
],
)
],
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(
8, 8, 8, 8), // Add padding if needed
child: Image.asset(
'images/backbutton_appbar.png', // Replace with your image path
fit: BoxFit.contain, // Adjust the fit
),
),
),
),
body: ListView(
padding: EdgeInsets.symmetric(horizontal: 0),
children: [
Padding(padding: EdgeInsets.fromLTRB(16, 0, 16, 0),
child: Column(
children: [
!isSearchEnabled ? _beforeDataScreenAbove() : Container(),
SizedBox(height: MediaQuery.of(context).size.height * .024),
_buildDropdownField(
hint: "Type of Water",
value: selectedWaterType,
items: waterTypes,
path: 'images/water.png',
onChanged: (val) => setState(() => selectedWaterType = val),
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
Row(
children: [
Expanded(
child: _buildDropdownField(
hint: "Capacity",
value: selectedCapacity,
items: capacities,
path:'',
onChanged: (val) =>
setState(() => selectedCapacity = val))),
SizedBox(width: MediaQuery.of(context).size.width * .024),
Expanded(
child: _buildDropdownField(
hint: "Quantity",
value: selectedQuantity,
items: quantities,
path:'',
onChanged: (val) =>
setState(() => selectedQuantity = val))),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
_buildDropdownField(
hint: "Frequency",
value: selectedFrequency,
items: frequencyTypes,
path:'images/frequency.png',
onChanged: (val) => setState(() => selectedFrequency = val),
),
SizedBox(height: MediaQuery.of(context).size.height * .012),
Row(
children: [
Expanded(
child: _buildDatePickerField(
hint: "Start date",
value: selectStartDate != null
? DateFormat('dd-MMM-yyyy').format(selectStartDate!)
: null,
onTap: () => _selectFromDate(context))),
SizedBox(width: MediaQuery.of(context).size.width * .024),
Expanded(
child: _buildDatePickerField(
hint: "End date",
value: selectStopDate != null
? DateFormat('dd-MMM-yyyy').format(selectStopDate!)
: null,
onTap: () => _selectToDate(context))),
],
),
SizedBox(height: MediaQuery.of(context).size.height * .024),
SizedBox(
width: double.infinity,
height: 41,
child: ElevatedButton(
onPressed: () async {
// ✅ FIELD VALIDATIONS
if (selectedWaterType == null || selectedWaterType!.isEmpty) {
AppSettings.longFailedToast('Please select Water Type');
return;
}
if (selectedCapacity == null || selectedCapacity!.isEmpty) {
AppSettings.longFailedToast('Please select Capacity');
return;
}
if (selectedQuantity == null || selectedQuantity!.isEmpty) {
AppSettings.longFailedToast('Please select Quantity');
return;
}
if (selectedFrequency == null || selectedFrequency!.isEmpty) {
AppSettings.longFailedToast('Please select Frequency');
return;
}
if (selectStartDate == null) {
AppSettings.longFailedToast('Please select Start Date');
return;
}
if (selectStopDate == null) {
AppSettings.longFailedToast('Please select End Date');
return;
}
// ✅ END DATE VALIDATION
if (selectStopDate!.isBefore(selectStartDate!)) {
AppSettings.longFailedToast('End Date must be after Start Date');
return;
}
// ✅ SEARCH ENABLE
setState(() {
isSearchEnabled = true;
});
await getAllSuppliersPlans();
},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0XFF1D7AFC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
),
child: Text(
"Search",
style: fontTextStyle(
14, Color(0xFFFFFFFF), FontWeight.w600),
),
),
),
SizedBox(height: MediaQuery.of(context).size.height * .036),
],
),
),
!isSearchEnabled ? _beforeDataScreen() : _suppliersDataScreen(),
],
),
);
}
Widget _buildDropdownField({
required String hint,
required String? value,
required List<String> items,
String? path, // ✅ Make path optional
required ValueChanged<String?> onChanged,
}) {
return DropdownButtonHideUnderline(
child: DropdownButton2<String>(
isExpanded: true,
hint: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (path != null&&path!='') ...[
Image.asset(
path,
width: 16,
height: 16,
color: Color(0XFF939495),
),
SizedBox(width: 6),
],
Text(
hint,
style: fontTextStyle(14, Color(0XFF939495), FontWeight.w400),
),
],
),
value: value,
items: items.map((item) {
return DropdownMenuItem<String>(
value: item,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 4),
child: Text(
item,
style: fontTextStyle(14, Color(0xFF2D2E30), FontWeight.w400),
),
),
);
}).toList(),
onChanged: onChanged,
buttonStyleData: ButtonStyleData(
height: 48,
padding: EdgeInsets.only(left: 0, right: 12),
decoration: BoxDecoration(
border: Border.all(color: Color(0XFF939495)),
borderRadius: BorderRadius.circular(12),
),
),
iconStyleData: IconStyleData(
icon: Padding(
padding: EdgeInsets.only(right: 4),
child: Image.asset(
'images/arrow_down.png',
width: 16,
height: 16,
color: Color(0XFF939495),
),
),
),
dropdownStyleData: DropdownStyleData(
padding: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
),
menuItemStyleData: MenuItemStyleData(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4),
),
),
);
}
Widget _buildDatePickerField({
required String hint,
String? value,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 48,
padding: EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade400),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Image.asset(
'images/calender_supplier_landing.png',
fit: BoxFit.cover,
width: 16, // Match the diameter of the CircleAvatar
height: 16,
color: Color(0XFF939495),
),
SizedBox(
width:
MediaQuery.of(context).size.width * .012,
),
Text(
value ?? hint,
style: value != null
? fontTextStyle(14, Color(0xFF2D2E30), FontWeight.w400)
: fontTextStyle(14, Color(0XFF939495), FontWeight.w400),
),
],
),
Image.asset(
'images/arrow_down.png',
width: 16,
height: 16,
color: Color(0XFF939495),
),
],
),
),
);
}
Widget _buildTimePickerField({
required String hint,
String? value,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 48,
padding: EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
border: Border.all(color: Color(0XFF939495)),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Text(
value ?? hint,
style: value != null
? fontTextStyle(14, Color(0xFF2D2E30), FontWeight.w400)
: fontTextStyle(14, Color(0XFF939495), FontWeight.w400),
overflow: TextOverflow.visible,
),
),
),
SizedBox(width: MediaQuery.of(context).size.width * .008),
Image.asset(
'images/arrow_down.png',
width: 16,
height: 16,
color: Color(0XFF939495),
),
],
),
),
);
}
}