second commit

This commit is contained in:
Anbarasu
2026-05-27 10:35:09 +05:30
parent c53794c04c
commit 1435ac47b0
501 changed files with 52818 additions and 0 deletions

View 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,
),
),
),
],
);
}
}

View 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,
),
},
),
),
);
}
}

View 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 havent added any products yet.',
color: ColorConstants.blackColor,
fontSize: 14,
fontWeight: FontWeight.normal,
maxLines: 2,
textAlign: TextAlign.center,
),
],
),
);
}

View 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],)
],
),
],
),
],
),
),
);
});
}
}

View 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]),),
],
),
],
),
],
),
),
),
],
),
),
]
);
}
)
);
}
}

View 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]),
],
),
],
),
],
),
),
);
},
);
}
}

View 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],)
],
),
],
),
],
),
),
);
});
}
}

View 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';
}