Customer Trip Container
Customer Trip Container
dart';
import 'package:iconsax/iconsax.dart';
import 'package:intl/intl.dart';
import 'package:skeletonizer/skeletonizer.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../Features/Trip/Cubit/GetMyTrips_State.dart';
import '../../Helper/constants.dart';
import '../../Helper/customToast.dart';
import '../../Helper/imageConstants.dart';
const CustomTripContainer({
Key? key,
required this.name,
this.viewFunction,
this.updateFunction,
this.deleteFunction,
this.deActiveFunction,
this.shareTrip,
this.status,
required this.data,
}) : super(key: key);
@override
State<CustomTripContainer> createState() => _CustomTripContainerState();
}
@override
void initState() {
// TODO: implement initState
super.initState();
}
_ShareTripBottomSheet(BuildContext context) {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _contactController = TextEditingController();
ValueNotifier<String> _selectedOption =
ValueNotifier<String>('phone'); // To track selected option
showModalBottomSheet(
enableDrag: true,
isDismissible: true,
context: context,
useSafeArea: true,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
backgroundColor: Colors.white,
builder: (BuildContext context) {
return Padding(
padding: EdgeInsets.only(
left: 16.0,
right: 16.0,
top: 16.0,
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Share Trip',
style: Theme.of(context).textTheme.labelMedium,
),
SizedBox(height: 20.h),
ValueListenableBuilder<String>(
valueListenable: _selectedOption,
builder: (context, value, _) {
return Column(
children: [
TextFormField(
controller: _contactController,
style: Theme.of(context).textTheme.bodySmall,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'Phone Number',
labelStyle:
Theme.of(context).textTheme.labelSmall,
prefixIcon: Icon(Icons.phone),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(14.0),
),
),
validator: (value) {
// Validation for phone number
if (value != null && value.isNotEmpty) {
if (!RegExp(r'^\d{10,14}$').hasMatch(value)) {
return 'Enter a valid phone number (10-14
digits)';
}
}
return null;
},
),
SizedBox(
height: 10.h,
),
TextFormField(
controller: _emailController,
style: Theme.of(context).textTheme.bodySmall,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
labelStyle:
Theme.of(context).textTheme.labelSmall,
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(14.0),
),
),
validator: (value) {
// Validation for email
if (value != null && value.isNotEmpty) {
if (!RegExp(
r'^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+')
.hasMatch(value)) {
return 'Enter a valid email';
}
}
return null;
},
),
],
);
},
),
SizedBox(height: 20.h),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ButtonStyle(
minimumSize:
WidgetStateProperty.all<Size>(Size(90, 40)),
shape:
WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0).r,
),
),
backgroundColor:
WidgetStateProperty.all<Color>(Colors.red),
),
child: Text(
'Cancel',
style: Theme.of(context).textTheme.headlineSmall,
),
),
SizedBox(width: 10.w),
ElevatedButton(
onPressed: () async {
if ((_contactController.text.isEmpty &&
_emailController.text.isEmpty)) {
/*ScaffoldMessenger.of(context).showSnackBar(
SnackBar(,content: Text('Please enter either contact
number or email')),
);*/
showErrorToast(
'Please enter contact number and email');
return;
}
if (_formKey.currentState!.validate()) {
if (widget.shareTrip != null) {
await widget.shareTrip!(_contactController.text,
_emailController.text);
Navigator.pop(context);
}
}
},
style: ButtonStyle(
minimumSize:
WidgetStateProperty.all<Size>(Size(90, 40)),
shape:
WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
backgroundColor:
WidgetStateProperty.all<Color>(Colors.blue),
),
child: Text(
'Share Trip',
style: Theme.of(context).textTheme.headlineSmall,
),
),
],
),
SizedBox(height: 10.h),
],
),
),
),
);
},
);
}
Widget statusIndicator() {
final color = widget.status == true ? Constants.on : Constants.ErrorText;
return Container(
height: 10.h,
width: 10.w,
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
);
}
@override
Widget build(BuildContext context) {
var currentTimestamp =
DateTime.fromMillisecondsSinceEpoch(widget.data.actualEndTime==null||
widget.data.actualStartTime==null?widget.data.startTime!:widget.data.actualEndTime!
* 1000);
var endTime =
DateTime.fromMillisecondsSinceEpoch(widget.data.actualEndTime==null||
widget.data.actualStartTime==null?widget.data.endTime!:widget.data.actualEndTime! *
1000);
return Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 10.0, right: 10.0, bottom: 0, top: 5.0)
.r,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(07).r,
border: Border.all(color: Colors.white, width: 2.w),
color: Colors.white70,
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15).r,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 10.h,
),
Row(
children: [
Skeleton.shade(child: statusIndicator()),
Text(
" Trip Id :${widget.data.tripID.toString()}",
style: Theme.of(context).textTheme.labelMedium,
),
Spacer(),
/* IconButton(
onPressed: () async {
final result = await _ShareTripBottomSheet(context);
if (result != null) {
String contact = result['contact'];
String email = result['email'];
if (widget.shareTrip != null) {
widget.shareTrip!(contact, email);
}
}
},
icon: Icon(
Icons.share,
color: Colors.blue,
size: 20,
),
),*/
PopupMenuButton<String>(
offset: Offset(0, 30),
itemBuilder: (BuildContext context) {
List<PopupMenuItem<String>> menuItems = [];
if (widget.data.actualEndTime==null||
widget.data.actualStartTime==null) {
// Add Update option
menuItems.add(
PopupMenuItem(
onTap: () {
widget.updateFunction!();
},
value: 'edit',
child: SizedBox(
width: 130.w,
child: Row(
children: [
Icon(
Iconsax.edit,
size: 20,
color: Colors.black,
),
SizedBox(width: 10),
Text(
'Update',
style:
Theme.of(context).textTheme.bodyMedium,
),
],
),
),
),
);
return menuItems;
},
child: Image.asset(
ImageConstants.dots,
height: 22.h,
),
),
SizedBox(
height: 33.h,
),
],
),
SizedBox(
height: 10.h,
),
Row(
children: [
Text(
"Vehicle No : ",
style: Theme.of(context).textTheme.labelMedium,
),
Text(
"${widget.data.vehicleNumber!.toUpperCase() ?? ''}",style:
TextStyle(fontWeight: FontWeight.bold,),
// style: Theme.of(context).textTheme.bodySmall,
),
],
),
SizedBox(height: 10.h),
Row(children: [
Icon(Icons.radio_button_checked, color: Colors.green,size: 15),
SizedBox(width: 5.w), Text(
'Source:',style: TextStyle(fontWeight: FontWeight.bold,color:
Colors.green),
//style: Theme.of(context).textTheme.labelMedium,
),
]),
Column(crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 22,top: 01),
child: Text(
"${widget.data.source!}",
maxLines: 3,
style: Theme.of(context).textTheme.bodySmall,
),
),
],
),
SizedBox(height: 10.h),
Row(
children: [
Icon(Icons.radio_button_checked, color: Colors.red,size:
15,),
SizedBox(width: 5.w),
Text(
'Destination:',style: TextStyle(fontWeight:
FontWeight.bold,color: Colors.red),
//style: Theme.of(context).textTheme.labelMedium,
),
],
),
Column(
children: [
Padding(
padding: EdgeInsets.only(left: 22,top: 01),
child: Text(
"${widget.data.destination!}",
maxLines: 3,
style: Theme.of(context).textTheme.bodySmall,
),
),
],
),
Divider(height: 14, color: Colors.grey),
Row(
children: [
Icon(
Icons.timelapse,
color: Colors.black,
size: 20,
),
SizedBox(
width: 5.w,
),
Text(
widget.data.actualEndTime==null||
widget.data.actualStartTime==null?"Start Date & Time":"Actual start date",
style: Theme.of(context).textTheme.labelMedium,
),
Spacer(),
Text(
'${DateFormat('dd/MM/yyyy, hh:mm
a').format(currentTimestamp)}',
style: Theme.of(context).textTheme.bodySmall,
),
],
),
SizedBox(height: 10.h),
Row(
children: [
Icon(
Icons.timelapse,
color: Colors.black,
size: 20,
),
SizedBox(
width: 5.w,
),
Text(
widget.data.actualEndTime==null||
widget.data.actualStartTime==null?"End Date & Time":"Actual end date",
style: Theme.of(context).textTheme.labelMedium,
),
Spacer(),
Text(
'${DateFormat('dd/MM/yyyy, hh:mm a').format(endTime)}',
style: Theme.of(context).textTheme.bodySmall,
),
],
),
SizedBox(height: 10.h),
],
),
),
),
),
],
);
}
}