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:
119
test/home_gutter_test.dart
Normal file
119
test/home_gutter_test.dart
Normal file
@@ -0,0 +1,119 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:miler/data/service_profile.dart';
|
||||
import 'package:miler/views/Dashboard/home/trip.dart';
|
||||
import 'package:miler/views/Dashboard/home/trip_brief_strip.dart';
|
||||
import 'package:miler/views/Dashboard/home/trip_card.dart';
|
||||
|
||||
/// ── Home stands on one column ──
|
||||
///
|
||||
/// The trip brief and the route are separate widgets with separate paddings,
|
||||
/// and they drifted: the brief padded 12 while the route padded 16, so the
|
||||
/// two header rows the rider reads first — "N stops left" and "TODAY'S RUN" —
|
||||
/// sat four points apart, directly above a list of stop cards that were all on
|
||||
/// the wider one. Four points is the worst distance for two edges to be apart:
|
||||
/// far enough to see, near enough to read as a mistake rather than a margin.
|
||||
///
|
||||
/// A comment in the brief already asserted the two shared a column. It had
|
||||
/// been wrong for as long as it had been there, which is the argument for
|
||||
/// pinning it here instead: a number two files apart from the number it must
|
||||
/// equal only stays equal if something checks.
|
||||
void main() {
|
||||
Map<String, dynamic> order(String id, String customer) => {
|
||||
'orderid': id,
|
||||
'tripid': 'T1',
|
||||
'type': 'delivery',
|
||||
'pickupcustomer': customer,
|
||||
'pickupaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004',
|
||||
'dropaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004',
|
||||
'orderstatus': 'new',
|
||||
'kitchenid': 'K1',
|
||||
'kitchenname': 'Vidhya Kitchen',
|
||||
'pickupcontactno': '9787698259',
|
||||
'Quantity': 1,
|
||||
'expected_pickup_time': DateTime.now()
|
||||
.add(const Duration(minutes: 20))
|
||||
.toIso8601String(),
|
||||
'pickuplat': 11.0368,
|
||||
'pickuplon': 76.9758,
|
||||
'droplat': 11.0408,
|
||||
'droplon': 76.9798,
|
||||
};
|
||||
|
||||
Future<void> pump(WidgetTester tester) async {
|
||||
ServiceProfile.setActive(ServiceProfile.milkMan);
|
||||
SharedPreferences.setMockInitialValues({'userid': 1});
|
||||
tester.view.physicalSize = const Size(390 * 3, 1400 * 3);
|
||||
tester.view.devicePixelRatio = 3.0;
|
||||
addTearDown(tester.view.reset);
|
||||
addTearDown(Get.reset);
|
||||
|
||||
final trip = Trip.groupIntoTrips([
|
||||
order('K1-1', 'Joe Mathew'),
|
||||
order('K1-2', 'Arun Prakash'),
|
||||
]).first;
|
||||
|
||||
await tester.pumpWidget(
|
||||
ScreenUtilInit(
|
||||
designSize: const Size(390, 1400),
|
||||
builder: (_, _) => MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: TripCard(
|
||||
trip: trip,
|
||||
riderLat: 11.0168,
|
||||
riderLng: 76.9558,
|
||||
acceptedIds: const {},
|
||||
rejectedIds: const {},
|
||||
selectedIds: const {},
|
||||
collectedIds: const {},
|
||||
onToggleSelect: (_) {},
|
||||
onSelectAll: (_) {},
|
||||
onStopTap: (_) {},
|
||||
onCallStop: (_) {},
|
||||
onNavigateStop: (_) {},
|
||||
onAdvanceStop: (_) {},
|
||||
onViewRoute: () {},
|
||||
onPreviewGroup: (_) {},
|
||||
onContinueStop: (_) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
for (var i = 0; i < 25; i++) {
|
||||
await tester.pump(const Duration(milliseconds: 80));
|
||||
}
|
||||
}
|
||||
|
||||
testWidgets('the trip brief and the route share one left edge', (
|
||||
tester,
|
||||
) async {
|
||||
await pump(tester);
|
||||
|
||||
// The brief's first ink is the hero numeral now — the caption sits to
|
||||
// its right — so the claim is measured on the numeral.
|
||||
final brief = tester.getRect(
|
||||
find
|
||||
.descendant(of: find.byType(TripBriefStrip), matching: find.text('2'))
|
||||
.first,
|
||||
);
|
||||
final route = tester.getRect(find.text('TODAY’S RUN'));
|
||||
|
||||
expect(
|
||||
brief.left,
|
||||
route.left,
|
||||
reason:
|
||||
'Home\'s two header rows must start on the same column. '
|
||||
'brief=${brief.left} route=${route.left} — check the horizontal '
|
||||
'padding in trip_brief_strip.dart against trip_card._timeline().',
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user