second commit
This commit is contained in:
951
lib/View/Orders/Deliverydetails/Deliverydetailsview.dart
Normal file
951
lib/View/Orders/Deliverydetails/Deliverydetailsview.dart
Normal file
@@ -0,0 +1,951 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_core/src/get_main.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../../../Controller/map_controller.dart';
|
||||
import '../../../Globalwidgets/textwidget.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
import '../../../Helper/utility.dart';
|
||||
import '../../../Model/Response/Summary/Getsummarysresponse.dart';
|
||||
|
||||
|
||||
|
||||
class MapWithBottomSheetPage extends StatelessWidget {
|
||||
|
||||
final DeliveriesDetails data;
|
||||
|
||||
MapWithBottomSheetPage({super.key, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
MapWithPolylines(
|
||||
endLatLng: LatLng(
|
||||
double.tryParse(data.deliverylat ?? '') ?? 0.0,
|
||||
double.tryParse(data.deliverylong ?? '') ?? 0.0,
|
||||
),
|
||||
startLatLng: LatLng(
|
||||
double.tryParse(data.pickuplat ?? '') ?? 0.0,
|
||||
double.tryParse(data.pickuplon ?? '') ?? 0.0,
|
||||
),
|
||||
),
|
||||
DraggableScrollableSheet(
|
||||
initialChildSize: 0.22,
|
||||
minChildSize: 0.12,
|
||||
maxChildSize: 0.65,
|
||||
builder: (context, scrollController) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(18)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 5,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: ColorConstants.primaryColor,
|
||||
radius: 30,
|
||||
child: TextWidget(
|
||||
text: data.ridername?[0] ?? '',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 20,
|
||||
color: ColorConstants.secondaryColor,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
data.ridername ?? '',
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
|
||||
),
|
||||
Text("Order ID: ${data.orderid}"),
|
||||
Text("Status: ${data.orderstatus}", style: TextStyle(color: Colors.green)),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.phone, color: ColorConstants.primaryColor),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text("Pickup Location"),
|
||||
subtitle: Text(data.pickupaddress ?? ''),
|
||||
leading: Icon(Icons.location_on, color: Colors.red),
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
ListTile(
|
||||
title: Text("Drop-off Location"),
|
||||
subtitle: Text(data.deliveryaddress ?? ''),
|
||||
leading: Icon(Icons.flag, color: Colors.green),
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
TextWidget(
|
||||
text: 'Order Details',
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
Row(
|
||||
children: [
|
||||
TextWidget(
|
||||
text: 'Delivery Charges',
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Spacer(),
|
||||
TextWidget(
|
||||
text: data.deliverycharges.toString(),
|
||||
fontWeight: FontWeight.w700,
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
Row(
|
||||
children: [
|
||||
TextWidget(
|
||||
text: 'Total Amount',
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Spacer(),
|
||||
TextWidget(
|
||||
text: data.deliveryamt.toString(),
|
||||
fontWeight: FontWeight.w700,
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
TextWidget(
|
||||
text: 'Payment Details',
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
Row(
|
||||
children: [
|
||||
TextWidget(
|
||||
text: data.deliverycustomer ?? '',
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Spacer(),
|
||||
TextWidget(
|
||||
text: data.deliverycontactno.toString(),
|
||||
fontWeight: FontWeight.w700,
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
TextWidget(
|
||||
text: 'Payment method',
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
TextWidget(
|
||||
text: 'Cash on delivery',
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// class SummaryDetailsView extends StatelessWidget {
|
||||
// final DeliveriesDetails data;
|
||||
//
|
||||
// const SummaryDetailsView({super.key, required this.data});
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Scaffold(
|
||||
// appBar: _buildAppBar(),
|
||||
// backgroundColor: Colors.grey[100],
|
||||
// body: _buildBody(context),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /// Builds the app bar with a back button and title.
|
||||
// AppBar _buildAppBar() {
|
||||
// return AppBar(
|
||||
// leading: InkWell(
|
||||
// onTap: Get.back,
|
||||
// child: Icon(
|
||||
// Icons.arrow_back,
|
||||
// color: ColorConstants.blackColor,
|
||||
// size: 28,
|
||||
// ),
|
||||
// ),
|
||||
// title: TextWidget(
|
||||
// text: 'Delivery Details',
|
||||
// fontSize: 20,
|
||||
// fontWeight: FontWeight.w700,
|
||||
// ),
|
||||
// backgroundColor: ColorConstants.secondaryColor,
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /// Builds the scrollable body with delivery details and map.
|
||||
// Widget _buildBody(BuildContext context) {
|
||||
// return SingleChildScrollView(
|
||||
// padding: const EdgeInsets.all(0.0),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(left: 0,right: 0),
|
||||
// child: SizedBox(
|
||||
// height: Get.height * 0.60,
|
||||
// child: MapWithPolylines(
|
||||
// endLatLng: LatLng(
|
||||
// double.tryParse(data.deliverylat ?? '') ?? 0.0,
|
||||
// double.tryParse(data.deliverylong ?? '') ?? 0.0,
|
||||
// ),
|
||||
// startLatLng: LatLng(
|
||||
// double.tryParse(data.pickuplat ?? '') ?? 0.0,
|
||||
// double.tryParse(data.pickuplon ?? '') ?? 0.0,
|
||||
// ),
|
||||
// )
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// DeliveryCard(data: data, isFromSummary: true,),
|
||||
// const SizedBox(height: 20,)
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
/// A reusable card widget displaying delivery header information (date, tenant, order).
|
||||
class DeliveryHeaderCard extends StatelessWidget {
|
||||
final DeliveriesDetails data;
|
||||
|
||||
const DeliveryHeaderCard({super.key, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: ColorConstants.secondaryColor,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
height: 95,
|
||||
child: Row(
|
||||
children: [
|
||||
_buildDateSection(),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
IconTextRow(
|
||||
icon: Icons.person,
|
||||
text: data.tenantname ?? '',
|
||||
textStyle: _textStyle(15, Colors.grey[500]),
|
||||
),
|
||||
IconTextRow(
|
||||
icon: Icons.receipt,
|
||||
text: data.orderid ?? '',
|
||||
textStyle: _textStyle(13, Colors.black54),
|
||||
),
|
||||
IconTextRow(
|
||||
icon: Icons.phone,
|
||||
text: data.tenantcontactno ?? '',
|
||||
textStyle: _textStyle(13, Colors.black54),
|
||||
onTap: () => _launchPhone(data.tenantcontactno),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Builds the date section with day, month, and time.
|
||||
Widget _buildDateSection() {
|
||||
final date = DateFormat("yyyy-MM-dd", "en_US").parse(data.deliverydate ?? DateTime.now().toString());
|
||||
return Container(
|
||||
width: 75,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.primaryColor1,
|
||||
shape: BoxShape.rectangle,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white70,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat("dd").format(date),
|
||||
style: _textStyle(14, Colors.grey[700]),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
DateFormat("MMM").format(date),
|
||||
style: _textStyle(14, Colors.grey[700], height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
DateFormat("hh.mm a").format(date),
|
||||
style: _textStyle(11, Colors.grey[700]),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Helper method to create consistent text styles.
|
||||
TextStyle _textStyle(double fontSize, Color? color, {double? height}) {
|
||||
return TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: height,
|
||||
);
|
||||
}
|
||||
|
||||
/// Launches phone dialer with the provided number.
|
||||
void _launchPhone(String? number) {
|
||||
if (number != null && number.isNotEmpty) {
|
||||
launch('tel://$number');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A reusable card widget for displaying pickup or delivery location details.
|
||||
class DeliveryLocationCard extends StatelessWidget {
|
||||
final String title;
|
||||
final String address;
|
||||
final String contact;
|
||||
final double lat;
|
||||
final double lon;
|
||||
final Color iconColor;
|
||||
final bool isPickup;
|
||||
|
||||
const DeliveryLocationCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.address,
|
||||
required this.contact,
|
||||
required this.lat,
|
||||
required this.lon,
|
||||
required this.iconColor,
|
||||
required this.isPickup,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
color: Colors.red[100]!.withAlpha(100),
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(13)),
|
||||
child: SizedBox(
|
||||
height: 150,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(height: 15),
|
||||
_buildMarkerIcon(),
|
||||
const Spacer(),
|
||||
_buildNavigationIcon(),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 14,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 15),
|
||||
IconTextRow(
|
||||
icon: isPickup ? Icons.business : Icons.person,
|
||||
text: title,
|
||||
textStyle: const TextStyle(color: Colors.black87, fontSize: 15),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
IconTextRow(
|
||||
icon: Icons.location_on_rounded,
|
||||
text: address,
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 13,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
maxLines: 2,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
IconTextRow(
|
||||
icon: Icons.phone,
|
||||
text: contact,
|
||||
textStyle: const TextStyle(color: Colors.black87, fontSize: 13),
|
||||
onTap: () => Utility.openPhoneCallApp(contact),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Builds the marker icon for the location.
|
||||
Widget _buildMarkerIcon() {
|
||||
return Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.mapMarkerAlt,
|
||||
size: 22,
|
||||
color: iconColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Builds the navigation icon with a tap action to open the map.
|
||||
Widget _buildNavigationIcon() {
|
||||
return InkWell(
|
||||
onTap: () => Utility.openMap(lat, lon),
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.assistant_direction_rounded,
|
||||
size: 30,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A reusable widget for displaying an icon and text with an optional tap action.
|
||||
class IconTextRow extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String text;
|
||||
final TextStyle textStyle;
|
||||
final int? maxLines;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const IconTextRow({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.text,
|
||||
required this.textStyle,
|
||||
this.maxLines,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon, size: 14, color: Colors.black38),
|
||||
const SizedBox(width: 4),
|
||||
Flexible(
|
||||
child: Text(
|
||||
text,
|
||||
style: textStyle,
|
||||
maxLines: maxLines,
|
||||
overflow: maxLines != null ? TextOverflow.ellipsis : null,
|
||||
),
|
||||
),
|
||||
if (maxLines != null) const SizedBox(width: 5),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Map with polyLines
|
||||
class MapWithPolylines extends StatelessWidget {
|
||||
final LatLng startLatLng;
|
||||
final LatLng endLatLng;
|
||||
|
||||
MapWithPolylines({
|
||||
required this.startLatLng,
|
||||
required this.endLatLng,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final mapController = Get.put(MapController());
|
||||
|
||||
Set<Polyline> _createPolylines() {
|
||||
return {
|
||||
Polyline(
|
||||
polylineId: const PolylineId('route1'),
|
||||
visible: true,
|
||||
points: [startLatLng, endLatLng],
|
||||
color: Colors.blue,
|
||||
width: 5,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Obx(() => GoogleMap(
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: startLatLng,
|
||||
zoom: mapController.zoom.value,
|
||||
),
|
||||
polylines: _createPolylines(),
|
||||
markers: {
|
||||
Marker(markerId: const MarkerId("start"), position: startLatLng),
|
||||
Marker(markerId: const MarkerId("end"), position: endLatLng),
|
||||
},
|
||||
onMapCreated: (controller) {
|
||||
mapController.setController(controller);
|
||||
},
|
||||
)),
|
||||
Positioned(
|
||||
top: 20,
|
||||
right: 10,
|
||||
child: Column(
|
||||
children: [
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
backgroundColor: Colors.white,
|
||||
onPressed: mapController.zoomIn,
|
||||
child: const Icon(Icons.add, color: Colors.black),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
backgroundColor: Colors.white,
|
||||
onPressed: mapController.zoomOut,
|
||||
child: const Icon(Icons.remove, color: Colors.black),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 20,
|
||||
left: 10,
|
||||
child: FloatingActionButton(
|
||||
mini: true,
|
||||
backgroundColor: Colors.white,
|
||||
child: Icon(Icons.arrow_back, color: Colors.black),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DeliveryInfoCard extends StatelessWidget {
|
||||
final String deliveryDate;
|
||||
final String tenantName;
|
||||
final String orderId;
|
||||
final String contactNumber;
|
||||
final VoidCallback onPhoneTap;
|
||||
final Color primaryColor;
|
||||
|
||||
const DeliveryInfoCard({
|
||||
super.key,
|
||||
required this.deliveryDate,
|
||||
required this.tenantName,
|
||||
required this.orderId,
|
||||
required this.contactNumber,
|
||||
required this.onPhoneTap,
|
||||
required this.primaryColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final date = DateFormat("yyyy-MM-dd").parse(deliveryDate);
|
||||
final dateTime = DateFormat("yyyy-MM-ddTHH:mm:ss").parse(deliveryDate);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 6,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
child: Row(
|
||||
children: [
|
||||
/// LEFT SIDE: DATE
|
||||
Container(
|
||||
width: 80,
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
bottomLeft: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat("dd").format(date),
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
DateFormat("MMM").format(date),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
DateFormat("hh:mm a").format(dateTime),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(width: 12),
|
||||
|
||||
/// RIGHT SIDE: DETAILS
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildIconText(Icons.person, tenantName, 15),
|
||||
_buildIconText(Icons.receipt, orderId, 13),
|
||||
InkWell(
|
||||
onTap: onPhoneTap,
|
||||
child: _buildIconText(Icons.phone, contactNumber, 13, isLink: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIconText(IconData icon, String text, double fontSize, {bool isLink = false}) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(icon, color: Colors.black45, size: 18),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: isLink ? Colors.blue : Colors.black87,
|
||||
fontWeight: FontWeight.w500,
|
||||
decoration: isLink ? TextDecoration.underline : TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DeliveryCard extends StatelessWidget {
|
||||
final dynamic data;
|
||||
final bool isFromSummary;
|
||||
|
||||
const DeliveryCard({super.key, required this.data, this.isFromSummary = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(12),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
||||
elevation: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
/// Timeline: Pickup icon, dotted line, Drop icon
|
||||
SizedBox(
|
||||
height: 190, // <-- match the combined height of your content
|
||||
child: Column(
|
||||
children: [
|
||||
_circleIcon(FontAwesomeIcons.mapMarkerAlt as IconData, isFromSummary ? Colors.red : Colors.green),
|
||||
Expanded(child: _verticalDottedLine()),
|
||||
_circleIcon((isFromSummary ? FontAwesomeIcons.checkCircle : FontAwesomeIcons.mapMarkerAlt) as IconData, isFromSummary ? Colors.green : Colors.red),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
|
||||
/// Content Block
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildInfoBlock(
|
||||
label: "Pickup",
|
||||
name: data?.pickupcustomer ?? '',
|
||||
address: data?.pickupaddress ?? '',
|
||||
contact: data?.pickupcontactno ?? '',
|
||||
lat: data?.pickuplat,
|
||||
lon: data?.pickuplon,
|
||||
isPickup: true,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildInfoBlock(
|
||||
label: isFromSummary ? "Delivered" : "Drop",
|
||||
name: data?.deliverycustomer ?? '',
|
||||
address: data?.deliveryaddress ?? '',
|
||||
contact: data?.deliverycontactno ?? '',
|
||||
lat: data?.droplat,
|
||||
lon: data?.droplon,
|
||||
isPickup: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget _circleIcon(IconData icon, Color color) {
|
||||
return Container(
|
||||
height: 38,
|
||||
width: 38,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 3)],
|
||||
),
|
||||
child: FaIcon(icon as FaIconData?, color: color, size: 20),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _verticalDottedLine({double height = 60}) {
|
||||
return SizedBox(
|
||||
height: height,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: List.generate(
|
||||
(height ~/ 6),
|
||||
(index) => Container(
|
||||
width: 1,
|
||||
height: 4,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoBlock({
|
||||
required String label,
|
||||
required String name,
|
||||
required String address,
|
||||
required String contact,
|
||||
required String? lat,
|
||||
required String? lon,
|
||||
required bool isPickup,
|
||||
}) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
_infoRow(Icons.person, name),
|
||||
const SizedBox(height: 4),
|
||||
_infoRow(Icons.location_on, address, maxLines: 2),
|
||||
const SizedBox(height: 4),
|
||||
InkWell(
|
||||
onTap: () => Utility.openPhoneCallApp(contact),
|
||||
child: _infoRow(Icons.phone, contact),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Utility.openMap(
|
||||
double.tryParse(lat ?? '0') ?? 0,
|
||||
double.tryParse(lon ?? '0') ?? 0,
|
||||
);
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.assistant_direction_rounded,
|
||||
color: ColorConstants.primaryColor, size: 20),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
"Navigate",
|
||||
style: TextStyle(
|
||||
color: ColorConstants.primaryColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoRow(IconData icon, String text, {int maxLines = 1}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(icon, size: 16, color: Colors.black45),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
maxLines: maxLines,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
431
lib/View/Orders/Deliverydetails/delivery_detail_view.dart
Normal file
431
lib/View/Orders/Deliverydetails/delivery_detail_view.dart
Normal file
@@ -0,0 +1,431 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_core/src/get_main.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../Globalwidgets/textwidget.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
import '../../../Model/Response/Summary/Getsummarysresponse.dart';
|
||||
import '../../../Model/Response/products/product_info.dart';
|
||||
import '../orderDetails.dart';
|
||||
|
||||
class OrderDetailsPage extends StatelessWidget {
|
||||
final DeliveriesDetails orderDetails;
|
||||
final List<ProductDetails> productDetails;
|
||||
|
||||
const OrderDetailsPage({
|
||||
super.key,
|
||||
required this.productDetails,
|
||||
required this.orderDetails,
|
||||
});
|
||||
|
||||
// to replace "null" with empty text
|
||||
String safe(String? v) {
|
||||
if (v == null || v == "null") return "";
|
||||
return v;
|
||||
}
|
||||
|
||||
// to avoid crash when parsing date
|
||||
DateTime safeParseDate(String? date) {
|
||||
if (date == null || date.isEmpty || date == "null") {
|
||||
return DateTime.now();
|
||||
}
|
||||
try {
|
||||
return DateTime.parse(date);
|
||||
} catch (e) {
|
||||
print("Invalid date received: $date");
|
||||
return DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
bool isValidLatLng(double lat, double lng) {
|
||||
return lat != 0.0 && lng != 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double totalAmount = 0;
|
||||
double totalTax = 0;
|
||||
|
||||
for (var product in productDetails) {
|
||||
totalAmount += product.productsumprice ?? 0.0;
|
||||
totalTax += product.taxamount ?? 0.0;
|
||||
}
|
||||
|
||||
final totalWithTax = totalAmount + totalTax;
|
||||
|
||||
final DateTime dateTime = safeParseDate(orderDetails.deliverydate);
|
||||
final String formattedDate = DateFormat('dd-MM-yy').format(dateTime);
|
||||
final String formattedTime = DateFormat('hh:mm a').format(dateTime);
|
||||
|
||||
final pickupLat = double.tryParse(safe(orderDetails.pickuplat)) ?? 0.0;
|
||||
final pickupLng = double.tryParse(safe(orderDetails.pickuplon)) ?? 0.0;
|
||||
final deliveryLat = double.tryParse(safe(orderDetails.deliverylat)) ?? 0.0;
|
||||
final deliveryLng = double.tryParse(safe(orderDetails.deliverylong)) ?? 0.0;
|
||||
|
||||
final bool showMap = isValidLatLng(pickupLat, pickupLng) &&
|
||||
isValidLatLng(deliveryLat, deliveryLng);
|
||||
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: true,
|
||||
title: TextWidget(
|
||||
text: 'Order Details',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
backgroundColor: ColorConstants.secondaryColor,
|
||||
leading: InkWell(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Icon(
|
||||
Icons.arrow_back,
|
||||
color: ColorConstants.blackColor,
|
||||
)),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_sectionCard(
|
||||
icon: Icons.receipt_long,
|
||||
title: "Order Info",
|
||||
children: [
|
||||
_infoRow("Order ID", safe(orderDetails.orderid)),
|
||||
_infoRow("Date", formattedDate),
|
||||
_infoRow("Time", formattedTime),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_sectionCard(
|
||||
icon: Icons.shopping_cart,
|
||||
title: "Products",
|
||||
children: [
|
||||
...productDetails.map((product) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${safe(product.productname)} x${product.orderqty}")),
|
||||
Text(
|
||||
"₹${((product.price ?? 0) * (product.orderqty ?? 0)).toStringAsFixed(0)}",
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
const Divider(height: 24),
|
||||
_infoRow("Amount", "₹${totalAmount.toStringAsFixed(2)}",
|
||||
isForProducts: true),
|
||||
_infoRow("Tax", "₹${totalTax.toStringAsFixed(2)}",
|
||||
isForProducts: true),
|
||||
_infoRow("Total", "₹${totalWithTax.toStringAsFixed(2)}",
|
||||
isForProducts: true),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_sectionCard(
|
||||
icon: Icons.person,
|
||||
title: "Customer",
|
||||
children: [
|
||||
_infoRow("Name", safe(orderDetails.deliverycustomer)),
|
||||
_infoRow("Address", safe(orderDetails.deliveryaddress)),
|
||||
_infoRow("Phone", safe(orderDetails.deliverycontactno)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Visibility(
|
||||
visible: safe(orderDetails.ridername).isNotEmpty,
|
||||
child: _sectionCard(
|
||||
icon: Icons.delivery_dining,
|
||||
title: "Rider",
|
||||
children: [
|
||||
_infoRow("Name", safe(orderDetails.ridername)),
|
||||
_infoRow("Phone", safe(orderDetails.ridercontact)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
SizedBox(
|
||||
height: 200,
|
||||
child: OrderStatusTimeline(
|
||||
stages: [
|
||||
Stage(
|
||||
label: "Accepted",
|
||||
icon: Icons.check,
|
||||
completed: safe(orderDetails.starttime).isNotEmpty,
|
||||
time: convertTo12HourFormat(safe(orderDetails.starttime)),
|
||||
),
|
||||
Stage(
|
||||
label: "Arrived",
|
||||
icon: Icons.location_on,
|
||||
completed: safe(orderDetails.arrivaltime).isNotEmpty,
|
||||
time: convertTo12HourFormat(safe(orderDetails.arrivaltime)),
|
||||
),
|
||||
Stage(
|
||||
label: "Picked",
|
||||
icon: Icons.shopping_bag,
|
||||
completed: safe(orderDetails.pickuptime).isNotEmpty,
|
||||
time: convertTo12HourFormat(safe(orderDetails.pickuptime)),
|
||||
),
|
||||
Stage(
|
||||
label: "Delivered",
|
||||
icon: Icons.delivery_dining,
|
||||
completed: safe(orderDetails.deliverytime).isNotEmpty,
|
||||
time: convertTo12HourFormat(safe(orderDetails.deliverytime)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Only show map if lat/lng are valid (not 0.0)
|
||||
if (showMap)
|
||||
SizedBox(
|
||||
height: 300,
|
||||
child: MapWithPolyLines(
|
||||
startLatLng: LatLng(pickupLat, pickupLng),
|
||||
endLatLng: LatLng(deliveryLat, deliveryLng),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
height: 80,
|
||||
alignment: Alignment.center,
|
||||
child: Text("Map not available"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _sectionCard({
|
||||
required IconData icon,
|
||||
required String title,
|
||||
String? Amount,
|
||||
String? TaxAmount,
|
||||
String? Total,
|
||||
required List<Widget> children,
|
||||
}) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 20, color: ColorConstants.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 16)),
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
...children,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoRow(String label, String value, {bool? isForProducts}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(color: Colors.black54),
|
||||
),
|
||||
),
|
||||
(isForProducts ?? false) ? Spacer() : const SizedBox(width: 8),
|
||||
(isForProducts ?? false)
|
||||
? Text(
|
||||
value,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
showBottomSheet(BuildContext context, {required VoidCallback onAccept}) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
|
||||
),
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 5,
|
||||
margin: EdgeInsets.symmetric(vertical: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(2.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
'Confirm Order',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
'Accept this order and assign a rider?',
|
||||
style: TextStyle(fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 24.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey[300],
|
||||
foregroundColor: Colors.black,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: TextWidget(text: 'Cancel'),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16.0),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
onAccept();
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: ColorConstants.primaryColor,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: TextWidget(
|
||||
text: 'Accept',
|
||||
color: ColorConstants.secondaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────
|
||||
// MAP WITH POLYLINES — SAFE (NO CRASH)
|
||||
// ──────────────────────────────────────────────────────────
|
||||
|
||||
class MapWithPolyLines extends StatelessWidget {
|
||||
final LatLng startLatLng;
|
||||
final LatLng endLatLng;
|
||||
|
||||
const MapWithPolyLines({
|
||||
super.key,
|
||||
required this.startLatLng,
|
||||
required this.endLatLng,
|
||||
});
|
||||
|
||||
Set<Polyline> _createPolylines() {
|
||||
final polylineCoordinates = [
|
||||
startLatLng,
|
||||
endLatLng,
|
||||
];
|
||||
|
||||
return {
|
||||
Polyline(
|
||||
polylineId: const PolylineId('route1'),
|
||||
visible: true,
|
||||
points: polylineCoordinates,
|
||||
color: Colors.blue,
|
||||
width: 5,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: GoogleMap(
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: startLatLng,
|
||||
zoom: 13.0,
|
||||
),
|
||||
onMapCreated: (GoogleMapController controller) {},
|
||||
polylines: _createPolylines(),
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: const MarkerId("start"),
|
||||
position: startLatLng,
|
||||
),
|
||||
Marker(
|
||||
markerId: const MarkerId("end"),
|
||||
position: endLatLng,
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
330
lib/View/Orders/Orderspage.dart
Normal file
330
lib/View/Orders/Orderspage.dart
Normal file
@@ -0,0 +1,330 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../Controller/products/product_controller.dart';
|
||||
import '../../Globalwidgets/textwidget.dart';
|
||||
import '../../Helper/Constants/AssetConstants.dart';
|
||||
import '../../Helper/Constants/Colorconstants.dart';
|
||||
import '../../Helper/Logger.dart';
|
||||
import '../../Model/Response/products/product_response.dart';
|
||||
import '../Dashboard/Dashboardview.dart';
|
||||
|
||||
class ProductView extends StatelessWidget {
|
||||
ProductView({super.key});
|
||||
|
||||
final ProductController controller = Get.put(ProductController());
|
||||
final FocusNode searchFocusNode = FocusNode();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<ProductController>(
|
||||
initState: (_) {
|
||||
controller.getProducts();
|
||||
},
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
title: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return SizeTransition(
|
||||
sizeFactor: animation,
|
||||
axis: Axis.horizontal,
|
||||
child: FadeTransition(opacity: animation, child: child),
|
||||
);
|
||||
},
|
||||
child: controller.isSearchModeEnable.value
|
||||
? TextField(
|
||||
key: const ValueKey('searchField'),
|
||||
focusNode: searchFocusNode,
|
||||
controller: controller.productSearchController,
|
||||
cursorColor: ColorConstants.primaryColor,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Search Products',
|
||||
border: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(color: Colors.white, width: 2),
|
||||
),
|
||||
isDense: false,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
style: const TextStyle(color: Colors.black),
|
||||
|
||||
// 🔥 FIXED HERE — USE LOCAL SEARCH
|
||||
onChanged: (value) {
|
||||
controller.applySearch(value);
|
||||
},
|
||||
|
||||
autofocus: true,
|
||||
)
|
||||
: TextWidget(
|
||||
key: const ValueKey('titleText'),
|
||||
text: 'Products',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (controller.isSearchModeEnable.value) {
|
||||
controller.productSearchController.clear();
|
||||
searchFocusNode.unfocus();
|
||||
|
||||
// 🔥 FIXED HERE — RESTORE LIST
|
||||
controller.applySearch('');
|
||||
} else {
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
searchFocusNode.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
controller.isSearchModeEnable.value =
|
||||
!controller.isSearchModeEnable.value;
|
||||
controller.update();
|
||||
},
|
||||
child: Icon(
|
||||
controller.isSearchModeEnable.value
|
||||
? Icons.cancel
|
||||
: Icons.search,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
body: Obx(() {
|
||||
if (controller.isProductLoading.value) {
|
||||
return const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: ShimmerListView(height: 100),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (controller.product.isEmpty) {
|
||||
return emptyProductsWidget();
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
cacheExtent: 1000,
|
||||
itemCount: controller.product.length,
|
||||
itemBuilder: (context, index) {
|
||||
final product = controller.product[index];
|
||||
return ProductCard(
|
||||
key: ValueKey(product.productid),
|
||||
product: product,
|
||||
index: index,
|
||||
controller: controller,
|
||||
isLoading: controller.loadingIndices.contains(index),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Product Card Widget
|
||||
class ProductCard extends StatelessWidget {
|
||||
final ProductData product;
|
||||
final int index;
|
||||
final ProductController controller;
|
||||
final bool isLoading;
|
||||
|
||||
const ProductCard({
|
||||
super.key,
|
||||
required this.product,
|
||||
required this.index,
|
||||
required this.controller,
|
||||
required this.isLoading,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isAvailable = product.status == 'Active';
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
shadowColor: Colors.grey.shade100,
|
||||
color: Colors.white,
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 12, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: product.productimage ?? '',
|
||||
width: 80,
|
||||
height: 80,
|
||||
fit: BoxFit.cover,
|
||||
memCacheHeight: 160,
|
||||
memCacheWidth: 160,
|
||||
maxHeightDiskCache: 160,
|
||||
maxWidthDiskCache: 160,
|
||||
placeholder: (context, url) => Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
color: Colors.grey.shade100,
|
||||
child: Icon(Icons.image,
|
||||
color: Colors.grey.shade400, size: 40),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
color: Colors.grey.shade100,
|
||||
child: Icon(Icons.broken_image_outlined,
|
||||
color: Colors.grey.shade400, size: 40),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget(
|
||||
text: product.productname ?? 'Unknown',
|
||||
maxLines: 1,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isAvailable
|
||||
? Colors.black87
|
||||
: Colors.grey.shade600,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.inventory_2_outlined,
|
||||
size: 16,
|
||||
color: Colors.grey.shade500,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
"Qty: ${product.productstock ?? 0}",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade700,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
product.productcost != null
|
||||
? '₹${product.productcost!.toStringAsFixed(2)}'
|
||||
: 'N/A',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade700,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: isAvailable
|
||||
? Colors.green.shade500
|
||||
: Colors.red.shade400,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
isAvailable ? "Active" : "Out of Stock",
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
AnimatedOpacity(
|
||||
opacity: isLoading ? 0.6 : 1.0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Switch.adaptive(
|
||||
value: isAvailable,
|
||||
activeColor: Colors.green.shade500,
|
||||
inactiveThumbColor: Colors.grey.shade400,
|
||||
inactiveTrackColor: Colors.grey.shade200,
|
||||
onChanged: isLoading
|
||||
? null
|
||||
: (_) => controller.toggleAvailability(index),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget emptyProductsWidget() {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Image.asset(
|
||||
AssetConstants.noProductsFound,
|
||||
height: 200,
|
||||
width: 200,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
TextWidget(
|
||||
text: 'No Products Found!',
|
||||
color: ColorConstants.blackColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextWidget(
|
||||
text: 'You haven’t added any products yet.',
|
||||
color: ColorConstants.blackColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
883
lib/View/Orders/Tabs/Month.dart
Normal file
883
lib/View/Orders/Tabs/Month.dart
Normal file
@@ -0,0 +1,883 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import '../../../Controller/Orders/Tabs/Monthcontroller.dart';
|
||||
import '../../../Helper/Constants/Assetconstants.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
import '../Deliverydetails/Deliverydetailsview.dart';
|
||||
|
||||
class MonthOrderView extends StatelessWidget {
|
||||
MonthOrderView({super.key});
|
||||
MonthOrderController monthOrderController = Get.put(MonthOrderController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MonthOrderController>(
|
||||
initState: (_){
|
||||
monthOrderController.shimmer.value = true;
|
||||
monthOrderController.getOrders();
|
||||
},
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey[100],
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10, top: 5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5, right: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.94,
|
||||
child: TextField(
|
||||
// textAlign: TextAlign.center,
|
||||
controller: controller.searchController,
|
||||
// style: TextStyle(fontSize: 15),
|
||||
onChanged: (data) {
|
||||
controller.search(data);
|
||||
controller.update();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(
|
||||
bottom: 10,
|
||||
right: 45,
|
||||
// left: 10
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
// suffixIcon: popUp(),
|
||||
hintText: 'Name'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child:monthOrderController.orderAllList.length == 0&& !monthOrderController.shimmer.value
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 92,
|
||||
),
|
||||
Image(
|
||||
height: 160,
|
||||
width: 160,
|
||||
image: AssetImage(AssetConstants.NoRecords),
|
||||
),
|
||||
|
||||
Text(
|
||||
"No orders at this moment",
|
||||
style: TextStyle(color: Colors.grey[600], fontSize: 18),
|
||||
),
|
||||
],
|
||||
))
|
||||
: controller.shimmer.value
|
||||
? orderShimmerCard(context): ListView.builder(
|
||||
itemCount: controller.orderAllList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
// height: Get.height * 0.21,
|
||||
// width: Get.width * 0.9,
|
||||
margin:
|
||||
EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: InkWell(
|
||||
onTap: (){
|
||||
// Get.to(()=> DeliveryDetailsView(data: controller.orderAllList[index]));
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
controller.orderAllList[index].deliverydate == "" ? Text(''):
|
||||
Text(
|
||||
'${DateFormat("dd").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
controller.orderAllList[index].deliverydate == "" ? Text(''):
|
||||
|
||||
Text(
|
||||
'${DateFormat("MMM").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delivery_dining,
|
||||
size: 25,
|
||||
color: ColorConstants
|
||||
.primaryColor,
|
||||
),
|
||||
controller.orderAllList[index].kms==null?Text(
|
||||
'0.0',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
):Text(
|
||||
'${controller.orderAllList[index].kms?.toString()}Km',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
color: Colors.grey[400]!)),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 10,),
|
||||
CircleAvatar(
|
||||
radius: 10,
|
||||
backgroundColor: ColorConstants.primaryColor1,
|
||||
child: controller.orderAllList[index].paymenttype==42?Icon(Icons.mobile_friendly,color: ColorConstants.primaryColor,size: 12,):controller.orderAllList[index].paymenttype==43?Icon(Icons.money,color: ColorConstants.primaryColor,size: 12,):Icon(Icons.wallet,color: ColorConstants.primaryColor,size: 12,)),
|
||||
SizedBox(width: 07,),
|
||||
Text(
|
||||
"₹ ${controller.orderAllList[index].deliverycharges}",
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 9,
|
||||
),
|
||||
controller.orderAllList[index].orderstatus =='cancelled'?Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:Colors.red,borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
Icon(Icons.cancel,
|
||||
color: ColorConstants.secondaryColor, size: 18),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus }',
|
||||
style: TextStyle(
|
||||
color: ColorConstants.secondaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
):Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:controller.orderAllList[index].orderstatus =='completed'?Colors.green: Colors.grey[100],borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
CircleAvatar(
|
||||
backgroundColor:controller.orderAllList[index].orderstatus =='completed'?
|
||||
ColorConstants.secondaryColor:
|
||||
ColorConstants.primaryColor1,
|
||||
radius: 10,
|
||||
child: Icon(Icons.check,
|
||||
color: Colors.grey, size: 15),
|
||||
),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus }',
|
||||
style: TextStyle(
|
||||
color:controller.orderAllList[index].orderstatus =='completed'?
|
||||
ColorConstants.secondaryColor: ColorConstants.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.person,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Container(
|
||||
width: Get.width*0.35,
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].pickupcustomer}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
|
||||
),
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment:
|
||||
// MainAxisAlignment.start,
|
||||
// crossAxisAlignment:
|
||||
// CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons.location_on,
|
||||
// color: Colors.grey[500],
|
||||
// size: 22,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 4,
|
||||
// ),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(
|
||||
// top: 2),
|
||||
// child: Container(
|
||||
// width: Get.width*0.35,
|
||||
// child: Text(
|
||||
// '${controller.orderAllList[index].delivceryaddress}',
|
||||
// style: TextStyle(
|
||||
// color: Colors.black87,
|
||||
// fontWeight:
|
||||
// FontWeight.normal,
|
||||
// fontSize: 14,
|
||||
//
|
||||
// ),
|
||||
// maxLines: 2,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: 10,
|
||||
// ),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.phone,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].pickupcontactno}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.confirmation_num,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].orderid}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.business_rounded,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].tenantname}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.primaryColor,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0, horizontal: 5),
|
||||
child: Text(
|
||||
'${DateFormat("hh.mm a").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
fontSize: 10.5,
|
||||
color: Colors.white)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
})
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
orderShimmerCard(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: 6,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
height: Get.height * 0.21,
|
||||
width: Get.width * 0.9,
|
||||
margin:
|
||||
EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Shimmer.fromColors(
|
||||
enabled: true,
|
||||
highlightColor: ColorConstants.lightGreyBg!,
|
||||
baseColor: Colors.grey[300]!,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delivery_dining,
|
||||
size: 25,
|
||||
color: ColorConstants
|
||||
.primaryColor,
|
||||
),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
color: Colors.grey[400]!)),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"",
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:Colors.grey[100],borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
CircleAvatar(
|
||||
backgroundColor:Colors.grey[100],
|
||||
radius: 10,
|
||||
child: Icon(Icons.check,
|
||||
color: Colors.grey, size: 15),
|
||||
),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color:Colors.grey[100],
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.person,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.phone,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.confirmation_num,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.business,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height*0.02,
|
||||
width: Get.width*0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0, horizontal: 5),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
fontSize: 10.5,
|
||||
color: Colors.white)),
|
||||
)),
|
||||
SizedBox(height: 80,),
|
||||
Icon(Icons.cancel,size: 30,color: Colors.grey[100],)
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
206
lib/View/Orders/Tabs/Summary.dart
Normal file
206
lib/View/Orders/Tabs/Summary.dart
Normal file
@@ -0,0 +1,206 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../Controller/Orders/Tabs/Summarycontroller.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
|
||||
class OrderSummary extends StatelessWidget {
|
||||
OrderSummary({super.key});
|
||||
OrderSummaryController orderSummaryController = Get.put(OrderSummaryController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor : Colors.grey[100],
|
||||
body: GetBuilder<OrderSummaryController>(
|
||||
initState: (_){
|
||||
orderSummaryController.shimmer.value = true;
|
||||
orderSummaryController.getOrdersSummary();
|
||||
},
|
||||
builder: (controller) {
|
||||
return controller.shimmer.value
|
||||
? Center(child: CircularProgressIndicator(color: ColorConstants.primaryColor,))
|
||||
:ListView(
|
||||
scrollDirection: Axis.vertical,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10,left: 10,right: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height*0.10,
|
||||
width: Get.width*0.94,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Center(child: Icon(Icons.pending, size: 54, color:ColorConstants.primaryColor1)),
|
||||
const SizedBox(width: 5,),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 2,),
|
||||
Text('Pending',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.grey[600]),),
|
||||
const SizedBox(height: 4,),
|
||||
Text('${controller.getOrderSummary.pending}',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20,color: Colors.grey[600]),),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15,),
|
||||
Container(
|
||||
height: Get.height*0.10,
|
||||
width: Get.width*0.94,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Center(child: Icon(Icons.check_circle, size: 46, color:ColorConstants.primaryColor1)),
|
||||
const SizedBox(width: 10,),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4,),
|
||||
Text('Completed',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.grey[600]),),
|
||||
const SizedBox(height: 4,),
|
||||
Row(
|
||||
children: [
|
||||
Text('${controller.getOrderSummary.delivered}',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20,color: Colors.grey[600]),),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15,),
|
||||
Container(
|
||||
height: Get.height*0.10,
|
||||
width: Get.width*0.94,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Center(child: Icon(Icons.cancel, size: 48, color:ColorConstants.primaryColor1)),
|
||||
const SizedBox(width: 10,),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4,),
|
||||
Text('Cancelled',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.grey[600]),),
|
||||
const SizedBox(height: 4,),
|
||||
Row(
|
||||
children: [
|
||||
Text('${controller.getOrderSummary.cancelled}',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20,color: Colors.grey[600]),),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 15,),
|
||||
Container(
|
||||
height: Get.height*0.10,
|
||||
width: Get.width*0.94,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Center(child: Icon(Icons.location_city, size: 46, color:ColorConstants.primaryColor1)),
|
||||
const SizedBox(width: 10,),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4,),
|
||||
Text('Amount',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.grey[600]),),
|
||||
const SizedBox(height: 4,),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.currency_rupee_sharp,color: Colors.grey[600],size: 20),
|
||||
Text('0.00',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 20,color: Colors.grey[600]),),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
612
lib/View/Orders/Tabs/Today.dart
Normal file
612
lib/View/Orders/Tabs/Today.dart
Normal file
@@ -0,0 +1,612 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import '../../../Controller/Orders/Tabs/Todaycontroller.dart';
|
||||
import '../../../Helper/Constants/Assetconstants.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
import '../../../Helper/toast.dart';
|
||||
|
||||
class TodayOrderView extends StatefulWidget {
|
||||
const TodayOrderView({super.key});
|
||||
|
||||
@override
|
||||
State<TodayOrderView> createState() => _TodayOrderViewState();
|
||||
}
|
||||
|
||||
class _TodayOrderViewState extends State<TodayOrderView> {
|
||||
late TodayOrderController todayOrderController;
|
||||
Timer? _refreshTimer;
|
||||
final TodayOrderController controller = Get.put(TodayOrderController());
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
todayOrderController.shimmer.value = true;
|
||||
|
||||
// Fetch once
|
||||
todayOrderController.getOrders();
|
||||
|
||||
// Then refresh every 3 seconds
|
||||
_refreshTimer = Timer.periodic(const Duration(seconds: 3), (timer) {
|
||||
print('hi');
|
||||
todayOrderController.getOrders();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_refreshTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<TodayOrderController>(
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey[100],
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10, top: 5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5, right: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.94,
|
||||
child: TextField(
|
||||
controller: controller.searchController,
|
||||
onChanged: (data) {
|
||||
controller.search(data);
|
||||
controller.update();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(
|
||||
bottom: 10,
|
||||
right: 45,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
hintText: 'Name',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: controller.orderAllList.isEmpty && !controller.shimmer.value
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: 92),
|
||||
Image(
|
||||
height: 160,
|
||||
width: 160,
|
||||
image: AssetImage(AssetConstants.NoRecords),
|
||||
),
|
||||
Text(
|
||||
"No orders at this moment",
|
||||
style: TextStyle(color: Colors.grey[600], fontSize: 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: controller.shimmer.value
|
||||
? orderShimmerCard(context)
|
||||
: ListView.builder(
|
||||
itemCount: controller.orderAllList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// Get.to(() => DeliveryDetailsView(data: controller.orderAllList[index]));
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: ColorConstants.primaryColor),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
controller.orderAllList[index].deliverydate == ""
|
||||
? Text('')
|
||||
: Text(
|
||||
'${DateFormat("dd").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
controller.orderAllList[index].deliverydate == ""
|
||||
? Text('')
|
||||
: Text(
|
||||
'${DateFormat("MMM").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: ColorConstants.primaryColor),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delivery_dining,
|
||||
size: 25,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
controller.orderAllList[index].kms == null
|
||||
? Text(
|
||||
'0.0',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'${controller.orderAllList[index].kms?.toString()}Km',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: Colors.grey[400]!),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 10),
|
||||
CircleAvatar(
|
||||
radius: 10,
|
||||
backgroundColor: ColorConstants.primaryColor1,
|
||||
child: controller.orderAllList[index].paymenttype == 42
|
||||
? Icon(Icons.mobile_friendly, color: ColorConstants.primaryColor, size: 12)
|
||||
: controller.orderAllList[index].paymenttype == 43
|
||||
? Icon(Icons.money, color: ColorConstants.primaryColor, size: 12)
|
||||
: Icon(Icons.wallet, color: ColorConstants.primaryColor, size: 12),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
Text(
|
||||
"₹ ${controller.orderAllList[index].deliverycharges}",
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 9),
|
||||
controller.orderAllList[index].orderstatus == 'cancelled'
|
||||
? Container(
|
||||
height: Get.height * 0.04,
|
||||
width: Get.width * 0.3,
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5),
|
||||
Icon(Icons.cancel, color: ColorConstants.secondaryColor, size: 18),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus}',
|
||||
style: TextStyle(
|
||||
color: ColorConstants.secondaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: Get.height * 0.04,
|
||||
width: Get.width * 0.3,
|
||||
decoration: BoxDecoration(
|
||||
color: controller.orderAllList[index].orderstatus == 'completed' ? Colors.green : Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5),
|
||||
CircleAvatar(
|
||||
backgroundColor: controller.orderAllList[index].orderstatus == 'completed'
|
||||
? ColorConstants.secondaryColor
|
||||
: ColorConstants.primaryColor1,
|
||||
radius: 10,
|
||||
child: Icon(Icons.check, color: Colors.grey, size: 15),
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus}',
|
||||
style: TextStyle(
|
||||
color: controller.orderAllList[index].orderstatus == 'completed'
|
||||
? ColorConstants.secondaryColor
|
||||
: ColorConstants.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.person, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Container(
|
||||
width: Get.width * 0.35,
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].pickupcustomer}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.phone, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'${controller.orderAllList[index].pickupcontactno}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.confirmation_num, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderid}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.business_rounded, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'${controller.orderAllList[index].tenantname}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.primaryColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3.0, horizontal: 5),
|
||||
child: Text(
|
||||
'${DateFormat("hh.mm a").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(fontSize: 10.5, color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget orderShimmerCard(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: 6,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
height: Get.height * 0.21,
|
||||
width: Get.width * 0.9,
|
||||
margin: EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Shimmer.fromColors(
|
||||
enabled: true,
|
||||
highlightColor: ColorConstants.lightGreyBg!,
|
||||
baseColor: Colors.grey[300]!,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: ColorConstants.primaryColor!),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 15)),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: ColorConstants.primaryColor!),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.delivery_dining, size: 25, color: ColorConstants.primaryColor),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: Colors.grey[400]!),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text("", style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
Container(
|
||||
height: Get.height * 0.04,
|
||||
width: Get.width * 0.3,
|
||||
decoration: BoxDecoration(color: Colors.grey[100], borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5),
|
||||
CircleAvatar(backgroundColor: Colors.grey[100], radius: 10, child: Icon(Icons.check, color: Colors.grey, size: 15)),
|
||||
SizedBox(width: 6),
|
||||
Text('', style: TextStyle(color: Colors.grey[100], fontWeight: FontWeight.bold, fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.person, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.normal, fontSize: 14)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.phone, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.normal, fontSize: 14)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.confirmation_num, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.normal, fontSize: 14)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.business, color: Colors.grey[500], size: 22),
|
||||
SizedBox(width: 4),
|
||||
Text('', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.normal, fontSize: 14)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.02,
|
||||
width: Get.width * 0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.all(Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3.0, horizontal: 5),
|
||||
child: Text('', style: TextStyle(fontSize: 10.5, color: Colors.white)),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 80),
|
||||
Icon(Icons.cancel, size: 30, color: Colors.grey[100]),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
883
lib/View/Orders/Tabs/Week.dart
Normal file
883
lib/View/Orders/Tabs/Week.dart
Normal file
@@ -0,0 +1,883 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import '../../../Controller/Orders/Tabs/Weekcontroller.dart';
|
||||
import '../../../Helper/Constants/Assetconstants.dart';
|
||||
import '../../../Helper/Constants/Colorconstants.dart';
|
||||
import '../Deliverydetails/Deliverydetailsview.dart';
|
||||
|
||||
class WeekOrderView extends StatelessWidget {
|
||||
WeekOrderView({super.key});
|
||||
WeekOrderController weekOrderController = Get.put(WeekOrderController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<WeekOrderController>(
|
||||
initState: (_){
|
||||
weekOrderController.shimmer.value = true;
|
||||
weekOrderController.getOrders();
|
||||
},
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey[100],
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10, top: 5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5, right: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.94,
|
||||
child: TextField(
|
||||
// textAlign: TextAlign.center,
|
||||
controller: controller.searchController,
|
||||
// style: TextStyle(fontSize: 15),
|
||||
onChanged: (data) {
|
||||
controller.search(data);
|
||||
controller.update();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(
|
||||
bottom: 10,
|
||||
right: 45,
|
||||
// left: 10
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(30),
|
||||
borderSide: BorderSide(
|
||||
color: ColorConstants.primaryColor,
|
||||
)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: ColorConstants.primaryColor,
|
||||
),
|
||||
// suffixIcon: popUp(),
|
||||
hintText: 'Name'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child:weekOrderController.orderAllList.length == 0&& !weekOrderController.shimmer.value
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 92,
|
||||
),
|
||||
Image(
|
||||
height: 160,
|
||||
width: 160,
|
||||
image: AssetImage(AssetConstants.NoRecords),
|
||||
),
|
||||
|
||||
Text(
|
||||
"No orders at this moment",
|
||||
style: TextStyle(color: Colors.grey[600], fontSize: 18),
|
||||
),
|
||||
],
|
||||
))
|
||||
: controller.shimmer.value
|
||||
? orderShimmerCard(context): ListView.builder(
|
||||
itemCount: controller.orderAllList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
// height: Get.height * 0.21,
|
||||
// width: Get.width * 0.9,
|
||||
margin:
|
||||
EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: InkWell(
|
||||
onTap: (){
|
||||
// Get.to(()=> DeliveryDetailsView(data: controller.orderAllList[index]));
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
controller.orderAllList[index].deliverydate == "" ? Text(''):
|
||||
Text(
|
||||
'${DateFormat("dd").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
controller.orderAllList[index].deliverydate == "" ? Text(''):
|
||||
|
||||
Text(
|
||||
'${DateFormat("MMM").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delivery_dining,
|
||||
size: 25,
|
||||
color: ColorConstants
|
||||
.primaryColor,
|
||||
),
|
||||
controller.orderAllList[index].kms==null?Text(
|
||||
'0.0',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
):Text(
|
||||
'${controller.orderAllList[index].kms?.toString()}Km',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
color: Colors.grey[400]!)),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 10,),
|
||||
CircleAvatar(
|
||||
radius: 10,
|
||||
backgroundColor: ColorConstants.primaryColor1,
|
||||
child: controller.orderAllList[index].paymenttype==42?Icon(Icons.mobile_friendly,color: ColorConstants.primaryColor,size: 12,):controller.orderAllList[index].paymenttype==43?Icon(Icons.money,color: ColorConstants.primaryColor,size: 12,):Icon(Icons.wallet,color: ColorConstants.primaryColor,size: 12,)),
|
||||
SizedBox(width: 07,),
|
||||
Text(
|
||||
"₹ ${controller.orderAllList[index].deliverycharges}",
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 9,
|
||||
),
|
||||
controller.orderAllList[index].orderstatus =='cancelled'?Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:Colors.red,borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
Icon(Icons.cancel,
|
||||
color: ColorConstants.secondaryColor, size: 18),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus }',
|
||||
style: TextStyle(
|
||||
color: ColorConstants.secondaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
):Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:controller.orderAllList[index].orderstatus =='completed'?Colors.green: Colors.grey[100],borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
CircleAvatar(
|
||||
backgroundColor:controller.orderAllList[index].orderstatus =='completed'?
|
||||
ColorConstants.secondaryColor:
|
||||
ColorConstants.primaryColor1,
|
||||
radius: 10,
|
||||
child: Icon(Icons.check,
|
||||
color: Colors.grey, size: 15),
|
||||
),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'${controller.orderAllList[index].orderstatus }',
|
||||
style: TextStyle(
|
||||
color:controller.orderAllList[index].orderstatus =='completed'?
|
||||
ColorConstants.secondaryColor: ColorConstants.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.person,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Container(
|
||||
width: Get.width*0.35,
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].pickupcustomer}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
|
||||
),
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment:
|
||||
// MainAxisAlignment.start,
|
||||
// crossAxisAlignment:
|
||||
// CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons.location_on,
|
||||
// color: Colors.grey[500],
|
||||
// size: 22,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 4,
|
||||
// ),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(
|
||||
// top: 2),
|
||||
// child: Container(
|
||||
// width: Get.width*0.35,
|
||||
// child: Text(
|
||||
// '${controller.orderAllList[index].delivceryaddress}',
|
||||
// style: TextStyle(
|
||||
// color: Colors.black87,
|
||||
// fontWeight:
|
||||
// FontWeight.normal,
|
||||
// fontSize: 14,
|
||||
//
|
||||
// ),
|
||||
// maxLines: 2,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: 10,
|
||||
// ),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.phone,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].pickupcontactno}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.confirmation_num,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].orderid}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.business_rounded,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'${controller.orderAllList[index].tenantname}',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.primaryColor,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0, horizontal: 5),
|
||||
child: Text(
|
||||
'${DateFormat("hh.mm a").format(DateFormat("yyyy-MM-dd'T'HH:mm:ss", "en_US").parse(controller.orderAllList[index].deliverydate!))}',
|
||||
style: TextStyle(
|
||||
fontSize: 10.5,
|
||||
color: Colors.white)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
})
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
orderShimmerCard(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: 6,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
height: Get.height * 0.21,
|
||||
width: Get.width * 0.9,
|
||||
margin:
|
||||
EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||
padding: EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Shimmer.fromColors(
|
||||
enabled: true,
|
||||
highlightColor: ColorConstants.lightGreyBg!,
|
||||
baseColor: Colors.grey[300]!,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 7,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.06,
|
||||
width: Get.width * 0.13,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
border: Border.all(
|
||||
color: ColorConstants
|
||||
.primaryColor!)),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delivery_dining,
|
||||
size: 25,
|
||||
color: ColorConstants
|
||||
.primaryColor,
|
||||
),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
height: Get.height * 0.05,
|
||||
width: Get.width * 0.28,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
color: Colors.grey[400]!)),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"",
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Container(
|
||||
height: Get.height*0.04,
|
||||
width: Get.width*0.3,
|
||||
decoration: BoxDecoration(color:Colors.grey[100],borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 5,),
|
||||
CircleAvatar(
|
||||
backgroundColor:Colors.grey[100],
|
||||
radius: 10,
|
||||
child: Icon(Icons.check,
|
||||
color: Colors.grey, size: 15),
|
||||
),
|
||||
SizedBox(width: 6,),
|
||||
Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color:Colors.grey[100],
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 7),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.person,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.phone,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.confirmation_num,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.business,
|
||||
color: Colors.grey[500],
|
||||
size: 22,
|
||||
),
|
||||
SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
fontWeight:
|
||||
FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
height: Get.height*0.02,
|
||||
width: Get.width*0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(12.0)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0, horizontal: 5),
|
||||
child: Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
fontSize: 10.5,
|
||||
color: Colors.white)),
|
||||
)),
|
||||
SizedBox(height: 80,),
|
||||
Icon(Icons.cancel,size: 30,color: Colors.grey[100],)
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
618
lib/View/Orders/orderDetails.dart
Normal file
618
lib/View/Orders/orderDetails.dart
Normal file
@@ -0,0 +1,618 @@
|
||||
import 'package:country_currency_pickers/currency_picker_cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
|
||||
import 'package:timeline_tile/timeline_tile.dart';
|
||||
import '../../Controller/Dashboard/Tabs/Ordercontroller.dart';
|
||||
import '../../Globalwidgets/textwidget.dart';
|
||||
import '../../Helper/Constants/Colorconstants.dart';
|
||||
import '../../Helper/Logger.dart';
|
||||
import '../../Model/Response/Orders/Getorderresponse.dart';
|
||||
import '../../Model/Response/products/product_info.dart';
|
||||
import '../Rider/rider_assign.dart';
|
||||
|
||||
class OrderDetailsPage extends StatelessWidget {
|
||||
|
||||
final OrderDetails orderDetails;
|
||||
final List<ProductDetails> productDetails;
|
||||
final CurrentOrderController controller;
|
||||
|
||||
|
||||
const OrderDetailsPage({
|
||||
super.key,
|
||||
required this.productDetails,
|
||||
required this.orderDetails,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double totalAmount = 0;
|
||||
double totalTax = 0;
|
||||
|
||||
for (var product in productDetails) {
|
||||
totalAmount = product.productsumprice ?? 0.0;
|
||||
totalTax += product.taxamount ?? 0.0;
|
||||
}
|
||||
|
||||
final totalWithTax = totalAmount + totalTax;
|
||||
|
||||
final DateTime dateTime = DateTime.parse(orderDetails.orderdate ?? '');
|
||||
|
||||
final String formattedDate = DateFormat('dd-MM-yy').format(dateTime);
|
||||
final String formattedTime = DateFormat('hh:mm a').format(dateTime);
|
||||
|
||||
logger.i('Order Status : ${orderDetails.orderstatus}');
|
||||
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: true,
|
||||
title: TextWidget(
|
||||
text: 'Order Details',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
backgroundColor: ColorConstants.secondaryColor,
|
||||
leading: InkWell(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Icon(
|
||||
Icons.arrow_back,
|
||||
color: ColorConstants.blackColor,
|
||||
)
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_sectionCard(
|
||||
icon: Icons.receipt_long,
|
||||
title: "Order Info",
|
||||
children: [
|
||||
_infoRow("Order ID", orderDetails.orderid ?? ''),
|
||||
_infoRow("Date", "${formattedDate}"),
|
||||
_infoRow("Time", "${formattedTime}"),
|
||||
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_sectionCard(
|
||||
icon: Icons.shopping_cart,
|
||||
title: "Products",
|
||||
children: [
|
||||
// List of products
|
||||
...productDetails.map((product) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: Text("${product.productname} x${product.orderqty}")),
|
||||
Text(
|
||||
"₹${((product.price ?? 0.0) * (product.orderqty ?? 1)).toStringAsFixed(2)}",
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
|
||||
const Divider(height: 24),
|
||||
|
||||
// Additional totals
|
||||
_infoRow("Amount", "₹${totalAmount.toStringAsFixed(2)}", isForProducts: true),
|
||||
_infoRow("Tax", "₹${totalTax.toStringAsFixed(2)}", isForProducts: true),
|
||||
_infoRow(
|
||||
"Total",
|
||||
"₹${totalWithTax.toStringAsFixed(2)}",
|
||||
isForProducts: true
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_sectionCard(
|
||||
icon: Icons.person,
|
||||
title: "Customer",
|
||||
children: [
|
||||
_infoRow("Name", orderDetails.deliverycustomer ?? ''),
|
||||
_infoRow("Address", orderDetails.deliveryaddress ?? ''),
|
||||
_infoRow("Phone", orderDetails.deliverycontactno ?? ''),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
Visibility(
|
||||
visible: orderDetails.rider?.isNotEmpty ?? false,
|
||||
child: _sectionCard(
|
||||
icon: Icons.delivery_dining,
|
||||
title: "Rider",
|
||||
children: [
|
||||
_infoRow("Name", orderDetails.rider ?? ''),
|
||||
_infoRow("Phone", orderDetails.ridercontactno ?? ''),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
SizedBox(
|
||||
height: 200,
|
||||
child: OrderStatusTimeline(
|
||||
stages: [
|
||||
Stage(
|
||||
label: "Accepted",
|
||||
icon: Icons.check,
|
||||
completed: orderDetails.starttime?.isNotEmpty ?? false,
|
||||
time: convertTo12HourFormat(orderDetails.starttime ?? '',
|
||||
),
|
||||
),
|
||||
Stage(
|
||||
label: "Arrived",
|
||||
icon: Icons.location_on,
|
||||
completed: orderDetails.arrivaltime?.isNotEmpty ?? false,
|
||||
time: convertTo12HourFormat(orderDetails.arrivaltime ?? '',
|
||||
),
|
||||
),
|
||||
Stage(
|
||||
label: "Picked",
|
||||
icon: Icons.shopping_bag,
|
||||
completed: orderDetails.pickuptime?.isNotEmpty ?? false,
|
||||
time: convertTo12HourFormat(orderDetails.pickuptime ?? '')
|
||||
),
|
||||
Stage(
|
||||
label: "Delivered",
|
||||
icon: Icons.delivery_dining,
|
||||
completed:orderDetails.deliverytime?.isNotEmpty ?? false,
|
||||
time: convertTo12HourFormat(orderDetails.deliverytime ?? '')
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: orderDetails.orderstatus == 'cancelled' || orderDetails.orderstatus == 'delivered' ?
|
||||
SizedBox() :
|
||||
SafeArea(
|
||||
child: SizedBox(
|
||||
height: 80,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 14,right: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: (orderDetails.orderstatus == 'pending' || orderDetails.orderstatus == 'created') ,
|
||||
child: Expanded(
|
||||
child: RoundedLoadingButton(
|
||||
controller: controller.cancelOrderButton,
|
||||
color: Colors.red,
|
||||
onPressed: () {
|
||||
showCancelOrderDialog(
|
||||
context,
|
||||
() {
|
||||
controller.declineOrder(
|
||||
orderDetails.orderheaderid,
|
||||
orderDetails.orderid,
|
||||
orderDetails.customertoken,
|
||||
orderDetails.ridertoken,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: TextWidget(
|
||||
text: 'Cancel',
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorConstants.secondaryColor,
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Visibility(
|
||||
visible: orderDetails.orderstatus == 'created',
|
||||
child: Expanded(
|
||||
child: RoundedLoadingButton(
|
||||
controller: controller.acceptOrderButton,
|
||||
color: Colors.green,
|
||||
onPressed: () {
|
||||
Get.to(() => ReassignRidersView(deliveryDetails: orderDetails));
|
||||
controller.acceptOrderButton.reset();
|
||||
|
||||
},
|
||||
child: TextWidget(
|
||||
text: 'Accept',
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorConstants.secondaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Alert dialog for the Cancel Order
|
||||
void showCancelOrderDialog(BuildContext context, VoidCallback onConfirm) {
|
||||
controller.cancelOrderButton.reset();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
title: const TextWidget(
|
||||
text: 'Cancel Order',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
),
|
||||
content: const TextWidget(text: 'Would you like to cancel this order?', fontSize: 14,),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const TextWidget(text: 'No'),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.red),
|
||||
foregroundColor: WidgetStateProperty.all(ColorConstants.secondaryColor),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
onConfirm();
|
||||
},
|
||||
child: TextWidget(
|
||||
text: 'Yes, Cancel' ,
|
||||
color: ColorConstants.secondaryColor,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget _sectionCard({
|
||||
required IconData icon,
|
||||
required String title,
|
||||
String? Amount,
|
||||
String? TaxAmount,
|
||||
String? Total,
|
||||
required List<Widget> children,
|
||||
}) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
// boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 4)],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 20, color: ColorConstants.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(title, style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 16)),
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
...children,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoRow(String label, String value, {bool? isForProducts}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100, // fixed width for label
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(color: Colors.black54),
|
||||
),
|
||||
),
|
||||
(isForProducts ?? false) ?
|
||||
Spacer() :
|
||||
const SizedBox(width: 8),
|
||||
(isForProducts ?? false) ?
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
maxLines: 3, // Allow wrapping for address
|
||||
overflow: TextOverflow.ellipsis,
|
||||
) :
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
maxLines: 3, // Allow wrapping for address
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
showBottomSheet(BuildContext context, {required VoidCallback onAccept}) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
|
||||
),
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Optional: Add a handle or title
|
||||
Center(
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 5,
|
||||
margin: EdgeInsets.symmetric(vertical: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(2.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
'Confirm Order',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
'Accept this order and assign a rider?',
|
||||
style: TextStyle(fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 24.0),
|
||||
// Buttons
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
// Handle Cancel action
|
||||
Navigator.pop(context);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey[300],
|
||||
foregroundColor: Colors.black,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: TextWidget(
|
||||
text: 'Cancel'
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16.0),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
// Handle Accept action
|
||||
onAccept();
|
||||
// Add your accept logic here
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: ColorConstants.primaryColor,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: TextWidget(
|
||||
text: 'Accept',
|
||||
color: ColorConstants.secondaryColor,
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class OrderStatusTimeline extends StatelessWidget {
|
||||
final List<Stage> stages;
|
||||
|
||||
const OrderStatusTimeline({super.key, required this.stages});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorConstants.secondaryColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
// boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 4)],
|
||||
),
|
||||
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Title
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 12, bottom: 8),
|
||||
child: Text(
|
||||
'Order Status',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
// Horizontal Timeline
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
child: Row(
|
||||
children: List.generate(stages.length, (index) {
|
||||
final isFirst = index == 0;
|
||||
final isLast = index == stages.length - 1;
|
||||
final stage = stages[index];
|
||||
|
||||
return TimelineTile(
|
||||
axis: TimelineAxis.horizontal,
|
||||
alignment: TimelineAlign.center,
|
||||
isFirst: isFirst,
|
||||
isLast: isLast,
|
||||
beforeLineStyle: LineStyle(
|
||||
color: stage.completed ? Colors.green : Colors.grey.shade400,
|
||||
thickness: 2,
|
||||
),
|
||||
afterLineStyle: LineStyle(
|
||||
color: stage.completed ? Colors.green : Colors.grey.shade400,
|
||||
thickness: 2,
|
||||
),
|
||||
indicatorStyle: IndicatorStyle(
|
||||
width: 30,
|
||||
height: 30,
|
||||
indicator: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: stage.completed ? Colors.green : Colors.grey.shade400,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
stage.icon,
|
||||
color: Colors.white,
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
endChild: Container(
|
||||
margin: const EdgeInsets.only(top: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
stage.label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: stage.completed ? Colors.black : Colors.grey,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
if (stage.time != null)
|
||||
Expanded(
|
||||
child: Text(
|
||||
stage.time!,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.black54,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Stage {
|
||||
final String label;
|
||||
final IconData icon;
|
||||
final bool completed;
|
||||
final String? time;
|
||||
|
||||
Stage({
|
||||
required this.label,
|
||||
required this.icon,
|
||||
this.completed = false,
|
||||
this.time,
|
||||
});
|
||||
}
|
||||
|
||||
String convertTo12HourFormat(String dateTimeString) {
|
||||
logger.i('Convert This into 12 : ${dateTimeString}');
|
||||
|
||||
// Check if input is empty
|
||||
if (dateTimeString.isEmpty) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Parse the input string to DateTime
|
||||
DateTime dateTime = DateTime.parse(dateTimeString);
|
||||
|
||||
// Get hour and minute
|
||||
int hour = dateTime.hour;
|
||||
int minute = dateTime.minute;
|
||||
|
||||
// Determine AM/PM
|
||||
String period = hour >= 12 ? 'PM' : 'AM';
|
||||
|
||||
// Convert to 12-hour format
|
||||
hour = hour % 12;
|
||||
if (hour == 0) hour = 12;
|
||||
|
||||
// Format minute to always show two digits
|
||||
String minuteStr = minute.toString().padLeft(2, '0');
|
||||
|
||||
return '$hour:$minuteStr $period';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user