Miler rider app: surface system, visible design language, backend lifecycle
Design system - MilerSurface ladder (canvas → working → raised → floating) with MilerPanel as layer 1; canvas moved to #DEE3EA so white separates at 1.290:1. - Visible vocabulary applied across Home, Deliveries, Activity, Account and the sheets: hero heads (tabular numeral + small caption, clamped at 1.3x), canvas wells for anything that opens, small filled tags for shelf labels, demoted placeholders. Recorded in DESIGN_SYSTEM.md §6. - One icon family: 222 Material glyphs migrated to Lucide; none left outside lib/xpress. - Colour semantics corrected: amber only for what is genuinely owed, brand red reserved for the live stop, disabled primaries go neutral rather than pale. Data and lifecycle - lib/data/lifecycle.dart reads mutations for what they prove; route_order.dart makes admin sequence the single ordering authority; service_day.dart, and stop_area.dart rewritten against live Coimbatore addresses (digit-token stripping, city stoplist, street suffixes, stammer collapse). - countLabel states the load once, in bags. Testing - 1440 tests passing; golden shot harnesses for Home, Deliveries, Activity, sheets and verify, with test/failures/ now gitignored (diff debris). - New pins: home_gutter_test, stop_area_test, plus updated structural bounds. Note: this commit also carries pre-existing working-tree deletions that were present before this work (API_SPEC.md, README.md, demo test fixtures). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:miler/views/Dashboard/pickups/stop_verify.dart';
|
||||
@@ -33,17 +34,16 @@ void main() {
|
||||
int deliveryQty = 0,
|
||||
int pickupQty = 0,
|
||||
double cash = 0,
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'orderid': 'T-1',
|
||||
'type': type,
|
||||
'pickupcustomer': 'Priya Sharma',
|
||||
'pickupaddress': '45, Lake View Apartments, Coimbatore',
|
||||
if (deliveryQty > 0) 'deliveryqty': '$deliveryQty',
|
||||
if (pickupQty > 0) 'pickupqty': '$pickupQty',
|
||||
'Quantity': '${pickupQty > 0 ? pickupQty : deliveryQty}',
|
||||
if (cash > 0) 'collectionamt': '$cash',
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'orderid': 'T-1',
|
||||
'type': type,
|
||||
'pickupcustomer': 'Priya Sharma',
|
||||
'pickupaddress': '45, Lake View Apartments, Coimbatore',
|
||||
if (deliveryQty > 0) 'deliveryqty': '$deliveryQty',
|
||||
if (pickupQty > 0) 'pickupqty': '$pickupQty',
|
||||
'Quantity': '${pickupQty > 0 ? pickupQty : deliveryQty}',
|
||||
if (cash > 0) 'collectionamt': '$cash',
|
||||
};
|
||||
|
||||
testWidgets('a pickup stop runs one collect leg', (tester) async {
|
||||
await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 3));
|
||||
@@ -54,32 +54,36 @@ void main() {
|
||||
expect(find.text('Hand over'), findsNothing);
|
||||
|
||||
// The collect leg's own controls.
|
||||
expect(find.text('PARCELS COLLECTED'), findsOneWidget);
|
||||
expect(find.text('Parcels collected'), findsOneWidget);
|
||||
expect(find.text('of 3 booked'), findsOneWidget);
|
||||
expect(find.text('PICKUP CODE'), findsOneWidget);
|
||||
expect(find.text('Pickup code'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('a delivery stop runs one hand-over leg with a parcel checklist',
|
||||
(tester) async {
|
||||
await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 2));
|
||||
testWidgets(
|
||||
'a delivery stop runs one hand-over leg with a parcel checklist',
|
||||
(tester) async {
|
||||
await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 2));
|
||||
|
||||
expect(find.text('Verify delivery'), findsOneWidget);
|
||||
expect(find.text('Hand over'), findsOneWidget);
|
||||
expect(find.text('Collect'), findsNothing);
|
||||
expect(find.text('Verify delivery'), findsOneWidget);
|
||||
expect(find.text('Hand over'), findsOneWidget);
|
||||
expect(find.text('Collect'), findsNothing);
|
||||
|
||||
// One tile per parcel — this is what stops a 2-parcel drop closing on 1.
|
||||
expect(find.text('Parcel 1 of 2'), findsOneWidget);
|
||||
expect(find.text('Parcel 2 of 2'), findsOneWidget);
|
||||
expect(find.text('WHO RECEIVED IT?'), findsOneWidget);
|
||||
expect(find.text('DELIVERY OTP'), findsOneWidget);
|
||||
// One tile per parcel — this is what stops a 2-parcel drop closing on 1.
|
||||
expect(find.text('Parcel 1 of 2'), findsOneWidget);
|
||||
expect(find.text('Parcel 2 of 2'), findsOneWidget);
|
||||
expect(find.text('Who received it?'), findsOneWidget);
|
||||
expect(find.text('Delivery OTP'), findsOneWidget);
|
||||
|
||||
// Nothing about weight or condition on a delivery.
|
||||
expect(find.text('Condition'), findsNothing);
|
||||
});
|
||||
// Nothing about weight or condition on a delivery.
|
||||
expect(find.text('Condition'), findsNothing);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('a combined stop runs hand over, then collect', (tester) async {
|
||||
await pumpStop(
|
||||
tester, stopOf(type: 'combined', deliveryQty: 1, pickupQty: 2));
|
||||
tester,
|
||||
stopOf(type: 'combined', deliveryQty: 1, pickupQty: 2),
|
||||
);
|
||||
|
||||
expect(find.text('Verify stop'), findsOneWidget);
|
||||
// Three steps, delivery first — the rider walks up holding the outbound
|
||||
@@ -93,12 +97,13 @@ void main() {
|
||||
expect(find.text('Collect 2'), findsOneWidget);
|
||||
|
||||
// Step 1 is the delivery leg.
|
||||
expect(find.text('HAND OVER THE PARCELS'), findsOneWidget);
|
||||
expect(find.text('PARCELS COLLECTED'), findsNothing);
|
||||
expect(find.text('Hand over the parcels'), findsOneWidget);
|
||||
expect(find.text('Parcels collected'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('the delivery leg will not advance without its proof',
|
||||
(tester) async {
|
||||
testWidgets('the delivery leg will not advance without its proof', (
|
||||
tester,
|
||||
) async {
|
||||
await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 1));
|
||||
|
||||
// Blocked from the start, and the bar says what is missing next.
|
||||
@@ -113,11 +118,12 @@ void main() {
|
||||
expect(find.text('Take a proof photo'), findsOneWidget);
|
||||
|
||||
// Still on step 1 — the camera is the last gate and cannot be faked here.
|
||||
expect(find.text('HAND OVER THE PARCELS'), findsOneWidget);
|
||||
expect(find.text('Hand over the parcels'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('handing over to a third party demands their name',
|
||||
(tester) async {
|
||||
testWidgets('handing over to a third party demands their name', (
|
||||
tester,
|
||||
) async {
|
||||
await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 1));
|
||||
|
||||
await tester.tap(find.text('Parcel 1 of 1'));
|
||||
@@ -128,8 +134,10 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text("Person's name"), findsOneWidget);
|
||||
expect(find.text('Enter the name of the person who took it'),
|
||||
findsOneWidget);
|
||||
expect(
|
||||
find.text('Enter the name of the person who took it'),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('a short count forces a written reason', (tester) async {
|
||||
@@ -137,22 +145,22 @@ void main() {
|
||||
|
||||
// Pre-set to the booked count, so the common case needs no explanation.
|
||||
expect(find.text('3'), findsOneWidget);
|
||||
expect(find.text('WHAT HAPPENED?'), findsNothing);
|
||||
expect(find.text('What happened?'), findsNothing);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.remove_rounded));
|
||||
await tester.tap(find.byIcon(LucideIcons.minus));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('1 fewer than the parcels booked'), findsOneWidget);
|
||||
expect(find.text('WHAT HAPPENED?'), findsOneWidget);
|
||||
expect(find.text('What happened?'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('damaged goods force a written reason too', (tester) async {
|
||||
await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 1));
|
||||
|
||||
expect(find.text('WHAT HAPPENED?'), findsNothing);
|
||||
expect(find.text('What happened?'), findsNothing);
|
||||
await tester.tap(find.text('Damaged'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('WHAT HAPPENED?'), findsOneWidget);
|
||||
expect(find.text('What happened?'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('COD is surfaced on the stop summary', (tester) async {
|
||||
|
||||
Reference in New Issue
Block a user