Files
kent_logistics_app/lib/screens/order_shipment_screen.dart
2025-12-03 11:57:05 +05:30

185 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import '../services/dio_client.dart';
import '../services/order_service.dart';
class OrderShipmentScreen extends StatefulWidget {
final String orderId;
const OrderShipmentScreen({super.key, required this.orderId});
@override
State<OrderShipmentScreen> createState() => _OrderShipmentScreenState();
}
class _OrderShipmentScreenState extends State<OrderShipmentScreen> {
bool loading = true;
Map? shipment; // nullable
@override
void initState() {
super.initState();
load();
}
Future<void> load() async {
final service = OrderService(DioClient.getInstance(context));
final res = await service.getShipment(widget.orderId);
if (res['success'] == true) {
shipment = res['shipment']; // may be null
}
loading = false;
setState(() {});
}
Widget _row(String label, dynamic value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label,
style: const TextStyle(fontSize: 14, color: Colors.grey)),
Text(value?.toString() ?? "N/A",
style: const TextStyle(
fontSize: 15, fontWeight: FontWeight.w600)),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Shipment Details")),
body: loading
? const Center(child: CircularProgressIndicator())
// ---------------------------------------
// 🚨 CASE 1: Shipment NOT created yet
// ---------------------------------------
: (shipment == null)
? const Center(
child: Text(
"Order not shipped yet",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.grey),
),
)
// ---------------------------------------
// 🚛 CASE 2: Shipment available
// ---------------------------------------
: Padding(
padding: const EdgeInsets.all(16),
child: ListView(
children: [
const Text(
"Shipment Summary",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
_row("Shipment ID", shipment!['shipment_id']),
_row("Status", shipment!['status']),
_row("Shipment Date", shipment!['shipment_date']),
_row("Origin", shipment!['origin']),
_row("Destination", shipment!['destination']),
const Divider(height: 30),
const Text(
"Totals",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
_row("Total CTN", shipment!['total_ctn']),
_row("Total Qty", shipment!['total_qty']),
_row("Total TTL Qty", shipment!['total_ttl_qty']),
_row("Total Amount", shipment!['total_amount']),
_row("Total CBM", shipment!['total_cbm']),
_row("Total TTL CBM", shipment!['total_ttl_cbm']),
_row("Total KG", shipment!['total_kg']),
_row("Total TTL KG", shipment!['total_ttl_kg']),
const Divider(height: 30),
_row("Meta", shipment!['meta']),
const Divider(height: 30),
const Text(
"Shipment Items",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
...List.generate(shipment!['items']?.length ?? 0, (i) {
final item = shipment!['items'][i];
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 🔹 Title: Order ID
Text(
"Order ID: ${item['order_id'] ?? 'N/A'}",
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
// 🔹 Mark No (optional)
if (item['mark_no'] != null)
Text(
"Mark No: ${item['mark_no']}",
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 6),
// 🔹 Total Quantity
Text("Total Qty: ${item['total_ttl_qty'] ?? 0}"),
// 🔹 Total CBM (optional)
if (item['total_ttl_cbm'] != null)
Text("Total CBM: ${item['total_ttl_cbm']}"),
// 🔹 Total KG (optional)
if (item['total_ttl_kg'] != null)
Text("Total KG: ${item['total_ttl_kg']}"),
const SizedBox(height: 6),
// 🔹 Total Amount
Text(
"Amount: ₹${item['total_amount'] ?? 0}",
style: const TextStyle(
color: Colors.indigo,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
})
],
),
),
);
}
}