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:
2026-08-22 05:40:35 +05:30
parent c8350563d9
commit d7348e253f
387 changed files with 80693 additions and 12272 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
// Active Delivery Banner Widget for Home Page
// ignore_for_file: unused_import
import 'package:flutter/material.dart';
import 'package:miler/xpress/views/helpers/constants/Colorconstants.dart';
import 'package:miler/xpress/views/helpers/constants/Font_constant.dart';
class ActiveDeliveryBanner extends StatelessWidget {
final List<Map<String, dynamic>> activeDeliveries;
final Function(Map<String, dynamic>) onTap;
const ActiveDeliveryBanner({
super.key,
required this.activeDeliveries,
required this.onTap,
});
String _getDeliveryAddress(Map<String, dynamic> delivery) {
final address =
delivery['deliveryaddress'] ??
delivery['DeliveryAddress'] ??
delivery['address'] ??
'';
if (address.toString().length > 40) {
return '${address.toString().substring(0, 40)}...';
}
return address.toString();
}
@override
Widget build(BuildContext context) {
if (activeDeliveries.isEmpty) {
return const SizedBox.shrink();
}
// Show first active delivery (or show count if multiple)
final delivery = activeDeliveries.first;
final count = activeDeliveries.length;
return Container(
margin: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => onTap(delivery),
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
child: Row(
children: [
// Active indicator icon
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
Icons.two_wheeler,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 12),
// Delivery info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Text(
count > 1
? '$count Active Deliveries'
: 'Active Delivery',
style: TextStyle(
color: Colors.white,
fontSize: 19,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
),
),
if (count > 1) ...[
const SizedBox(width: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.3),
borderRadius: BorderRadius.circular(12),
),
child: Text(
'$count',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
],
],
),
const SizedBox(height: 4),
Text(
_getDeliveryAddress(delivery),
style: TextStyle(
color: Colors.white.withOpacity(0.9),
fontSize: 17,
fontFamily: FontConstants.fontFamily,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
// Arrow icon
const Icon(
Icons.arrow_forward_ios,
color: Colors.white,
size: 20,
),
],
),
),
),
),
);
}
}