From f453f8aadd1962fa50d58cb2361ca4666ef19849 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Mon, 23 Feb 2026 12:14:28 -0500 Subject: [PATCH] feat: Refine badge and status indicator styling across various client features, including updated colors, borders, and typography, and remove unused action buttons. --- .../design_system/lib/src/ui_typography.dart | 17 ++ .../src/presentation/pages/billing_page.dart | 11 - .../widgets/coverage_quick_stats.dart | 5 +- .../widgets/coverage_shift_list.dart | 176 ++++++++-------- .../widgets/order_edit_sheet.dart | 197 +++++++----------- .../presentation/widgets/view_order_card.dart | 70 ++++--- 6 files changed, 218 insertions(+), 258 deletions(-) diff --git a/apps/mobile/packages/design_system/lib/src/ui_typography.dart b/apps/mobile/packages/design_system/lib/src/ui_typography.dart index b12fd24a..16c0162b 100644 --- a/apps/mobile/packages/design_system/lib/src/ui_typography.dart +++ b/apps/mobile/packages/design_system/lib/src/ui_typography.dart @@ -205,6 +205,14 @@ class UiTypography { color: UiColors.textPrimary, ); + /// Headline 3 Bold - Font: Instrument Sans, Size: 22, Height: 1.5 (#121826) + static final TextStyle headline3b = _primaryBase.copyWith( + fontWeight: FontWeight.w600, + fontSize: 20, + height: 1.5, + color: UiColors.textPrimary, + ); + /// Headline 4 Medium - Font: Instrument Sans, Size: 22, Height: 1.5 (#121826) static final TextStyle headline4m = _primaryBase.copyWith( fontWeight: FontWeight.w500, @@ -354,6 +362,15 @@ class UiTypography { color: UiColors.textPrimary, ); + /// Body 3 Bold - Font: Instrument Sans, Size: 14, Height: 1.5, Spacing: -0.1 (#121826) + static final TextStyle body3b = _primaryBase.copyWith( + fontWeight: FontWeight.w700, + fontSize: 12, + height: 1.5, + letterSpacing: -0.1, + color: UiColors.textPrimary, + ); + /// Body 4 Regular - Font: Instrument Sans, Size: 14, Height: 1.5, Spacing: 0.05 (#121826) static final TextStyle body4r = _primaryBase.copyWith( fontWeight: FontWeight.w400, diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/billing_page.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/billing_page.dart index 6eca010f..3eaf50bd 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/billing_page.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/billing_page.dart @@ -88,10 +88,6 @@ class _BillingViewState extends State { controller: _scrollController, slivers: [ SliverAppBar( - // ... (APP BAR CODE REMAINS UNCHANGED, BUT I MUST INCLUDE IT OR CHUNK IT CORRECTLY) - // Since I cannot see the headers in this chunk, I will target the _buildContent method instead - // to avoid messing up the whole file structure. - // Wait, I can just replace the build method wrapper. pinned: true, expandedHeight: 200.0, backgroundColor: UiColors.primary, @@ -227,13 +223,6 @@ class _BillingViewState extends State { crossAxisAlignment: CrossAxisAlignment.start, spacing: UiConstants.space4, children: [ - UiButton.primary( - text: 'View Pending Timesheets', - leadingIcon: UiIcons.clock, - onPressed: () => Modular.to.pushNamed('${ClientPaths.billing}/timesheets'), - fullWidth: true, - ), - const SizedBox(height: UiConstants.space2), if (state.pendingInvoices.isNotEmpty) ...[ PendingInvoicesSection(invoices: state.pendingInvoices), ], diff --git a/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_quick_stats.dart b/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_quick_stats.dart index 31e3fd42..e2b90af2 100644 --- a/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_quick_stats.dart +++ b/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_quick_stats.dart @@ -77,10 +77,11 @@ class _StatCard extends StatelessWidget { return Container( padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( - color: UiColors.bgMenu, + color: color.withAlpha(10), borderRadius: UiConstants.radiusLg, border: Border.all( - color: UiColors.border, + color: color, + width: 0.75, ), ), child: Column( diff --git a/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_shift_list.dart b/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_shift_list.dart index 563d4036..e675719b 100644 --- a/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_shift_list.dart +++ b/apps/mobile/packages/features/client/client_coverage/lib/src/presentation/widgets/coverage_shift_list.dart @@ -1,11 +1,8 @@ +import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:krow_domain/krow_domain.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import '../blocs/coverage_bloc.dart'; -import '../blocs/coverage_event.dart'; -import 'package:core_localization/core_localization.dart'; /// List of shifts with their workers. /// @@ -235,19 +232,6 @@ class _ShiftHeader extends StatelessWidget { total: total, coveragePercent: coveragePercent, ), - if (current < total) - Padding( - padding: const EdgeInsets.only(left: UiConstants.space2), - child: UiButton.primary( - text: 'Repost', - size: UiButtonSize.small, - onPressed: () { - ReadContext(context).read().add( - CoverageRepostShiftRequested(shiftId: shiftId), - ); - }, - ), - ), ], ), ); @@ -278,14 +262,14 @@ class _CoverageBadge extends StatelessWidget { Color text; if (coveragePercent >= 100) { - bg = UiColors.textSuccess; - text = UiColors.primaryForeground; + bg = UiColors.textSuccess.withAlpha(40); + text = UiColors.textSuccess; } else if (coveragePercent >= 80) { - bg = UiColors.textWarning; - text = UiColors.primaryForeground; + bg = UiColors.textWarning.withAlpha(40); + text = UiColors.textWarning; } else { - bg = UiColors.destructive; - text = UiColors.destructiveForeground; + bg = UiColors.destructive.withAlpha(40); + text = UiColors.destructive; } return Container( @@ -295,11 +279,12 @@ class _CoverageBadge extends StatelessWidget { ), decoration: BoxDecoration( color: bg, - borderRadius: UiConstants.radiusFull, + border: Border.all(color: text, width: 0.75), + borderRadius: UiConstants.radiusMd, ), child: Text( '$current/$total', - style: UiTypography.body3m.copyWith( + style: UiTypography.body3b.copyWith( color: text, ), ), @@ -335,92 +320,101 @@ class _WorkerRow extends StatelessWidget { String statusText; Color badgeBg; Color badgeText; + Color badgeBorder; String badgeLabel; switch (worker.status) { case CoverageWorkerStatus.checkedIn: - bg = UiColors.textSuccess.withOpacity(0.1); + bg = UiColors.textSuccess.withAlpha(26); border = UiColors.textSuccess; - textBg = UiColors.textSuccess.withOpacity(0.2); + textBg = UiColors.textSuccess.withAlpha(51); textColor = UiColors.textSuccess; icon = UiIcons.success; statusText = '✓ Checked In at ${formatTime(worker.checkInTime)}'; - badgeBg = UiColors.textSuccess; - badgeText = UiColors.primaryForeground; + badgeBg = UiColors.textSuccess.withAlpha(40); + badgeText = UiColors.textSuccess; + badgeBorder = badgeText; badgeLabel = 'On Site'; case CoverageWorkerStatus.confirmed: if (worker.checkInTime == null) { - bg = UiColors.textWarning.withOpacity(0.1); + bg = UiColors.textWarning.withAlpha(26); border = UiColors.textWarning; - textBg = UiColors.textWarning.withOpacity(0.2); + textBg = UiColors.textWarning.withAlpha(51); textColor = UiColors.textWarning; icon = UiIcons.clock; statusText = 'En Route - Expected $shiftStartTime'; - badgeBg = UiColors.textWarning; - badgeText = UiColors.primaryForeground; + badgeBg = UiColors.textWarning.withAlpha(40); + badgeText = UiColors.textWarning; + badgeBorder = badgeText; badgeLabel = 'En Route'; } else { - bg = UiColors.muted.withOpacity(0.1); + bg = UiColors.muted.withAlpha(26); border = UiColors.border; - textBg = UiColors.muted.withOpacity(0.2); + textBg = UiColors.muted.withAlpha(51); textColor = UiColors.textSecondary; icon = UiIcons.success; statusText = 'Confirmed'; - badgeBg = UiColors.muted; - badgeText = UiColors.textPrimary; + badgeBg = UiColors.textSecondary.withAlpha(40); + badgeText = UiColors.textSecondary; + badgeBorder = badgeText; badgeLabel = 'Confirmed'; } case CoverageWorkerStatus.late: - bg = UiColors.destructive.withOpacity(0.1); + bg = UiColors.destructive.withAlpha(26); border = UiColors.destructive; - textBg = UiColors.destructive.withOpacity(0.2); + textBg = UiColors.destructive.withAlpha(51); textColor = UiColors.destructive; icon = UiIcons.warning; statusText = '⚠ Running Late'; - badgeBg = UiColors.destructive; - badgeText = UiColors.destructiveForeground; + badgeBg = UiColors.destructive.withAlpha(40); + badgeText = UiColors.destructive; + badgeBorder = badgeText; badgeLabel = 'Late'; case CoverageWorkerStatus.checkedOut: - bg = UiColors.muted.withOpacity(0.1); + bg = UiColors.muted.withAlpha(26); border = UiColors.border; - textBg = UiColors.muted.withOpacity(0.2); + textBg = UiColors.muted.withAlpha(51); textColor = UiColors.textSecondary; icon = UiIcons.success; statusText = 'Checked Out'; - badgeBg = UiColors.muted; - badgeText = UiColors.textPrimary; + badgeBg = UiColors.textSecondary.withAlpha(40); + badgeText = UiColors.textSecondary; + badgeBorder = badgeText; badgeLabel = 'Done'; case CoverageWorkerStatus.noShow: - bg = UiColors.destructive.withOpacity(0.1); + bg = UiColors.destructive.withAlpha(26); border = UiColors.destructive; - textBg = UiColors.destructive.withOpacity(0.2); + textBg = UiColors.destructive.withAlpha(51); textColor = UiColors.destructive; icon = UiIcons.warning; statusText = 'No Show'; - badgeBg = UiColors.destructive; - badgeText = UiColors.destructiveForeground; + badgeBg = UiColors.destructive.withAlpha(40); + badgeText = UiColors.destructive; + badgeBorder = badgeText; badgeLabel = 'No Show'; case CoverageWorkerStatus.completed: - bg = UiColors.textSuccess.withOpacity(0.1); - border = UiColors.textSuccess; - textBg = UiColors.textSuccess.withOpacity(0.2); + bg = UiColors.iconSuccess.withAlpha(26); + border = UiColors.iconSuccess; + textBg = UiColors.iconSuccess.withAlpha(51); textColor = UiColors.textSuccess; icon = UiIcons.success; statusText = 'Completed'; - badgeBg = UiColors.textSuccess; - badgeText = UiColors.primaryForeground; + badgeBg = UiColors.textSuccess.withAlpha(40); + badgeText = UiColors.textSuccess; + badgeBorder = badgeText; badgeLabel = 'Completed'; case CoverageWorkerStatus.pending: case CoverageWorkerStatus.accepted: case CoverageWorkerStatus.rejected: - bg = UiColors.muted.withOpacity(0.1); + bg = UiColors.muted.withAlpha(26); border = UiColors.border; - textBg = UiColors.muted.withOpacity(0.2); + textBg = UiColors.muted.withAlpha(51); textColor = UiColors.textSecondary; icon = UiIcons.clock; statusText = worker.status.name.toUpperCase(); - badgeBg = UiColors.muted; - badgeText = UiColors.textPrimary; + badgeBg = UiColors.textSecondary.withAlpha(40); + badgeText = UiColors.textSecondary; + badgeBorder = badgeText; badgeLabel = worker.status.name[0].toUpperCase() + worker.status.name.substring(1); } @@ -493,40 +487,42 @@ class _WorkerRow extends StatelessWidget { ), ), Column( - spacing: UiConstants.space2, - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: UiConstants.space2, - vertical: UiConstants.space1 / 2, - ), - decoration: BoxDecoration( - color: badgeBg, - borderRadius: UiConstants.radiusFull, - ), - child: Text( - badgeLabel, - style: UiTypography.footnote2b.copyWith( - color: badgeText, - ), + spacing: UiConstants.space2, + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space2, + vertical: UiConstants.space1 / 2, + ), + decoration: BoxDecoration( + color: badgeBg, + borderRadius: UiConstants.radiusMd, + border: Border.all(color: badgeBorder, width: 0.5), + ), + child: Text( + badgeLabel, + style: UiTypography.footnote2b.copyWith( + color: badgeText, ), ), - if (worker.status == CoverageWorkerStatus.checkedIn) - UiButton.primary( - text: context.t.client_coverage.worker_row.verify, - size: UiButtonSize.small, - onPressed: () { - UiSnackbar.show( - context, - message: context.t.client_coverage.worker_row.verified_message( - name: worker.name, - ), - type: UiSnackbarType.success, - ); - }, - ), - ], - ), + ), + if (worker.status == CoverageWorkerStatus.checkedIn) + UiButton.primary( + text: context.t.client_coverage.worker_row.verify, + size: UiButtonSize.small, + onPressed: () { + UiSnackbar.show( + context, + message: + context.t.client_coverage.worker_row.verified_message( + name: worker.name, + ), + type: UiSnackbarType.success, + ); + }, + ), + ], + ), ], ), ); diff --git a/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/order_edit_sheet.dart b/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/order_edit_sheet.dart index e7b9efa5..5d1606fa 100644 --- a/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/order_edit_sheet.dart +++ b/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/order_edit_sheet.dart @@ -28,11 +28,7 @@ class _ShiftRoleKey { /// A sophisticated bottom sheet for editing an existing order, /// following the Unified Order Flow prototype and matching OneTimeOrderView. class OrderEditSheet extends StatefulWidget { - const OrderEditSheet({ - required this.order, - this.onUpdated, - super.key, - }); + const OrderEditSheet({required this.order, this.onUpdated, super.key}); final OrderItem order; final VoidCallback? onUpdated; @@ -57,7 +53,8 @@ class OrderEditSheetState extends State { List _vendors = const []; Vendor? _selectedVendor; List<_RoleOption> _roles = const <_RoleOption>[]; - List _hubs = const []; + List _hubs = + const []; dc.ListTeamHubsByOwnerIdTeamHubs? _selectedHub; String? _shiftId; @@ -111,8 +108,10 @@ class OrderEditSheetState extends State { try { final QueryResult< - dc.ListShiftRolesByBusinessAndOrderData, - dc.ListShiftRolesByBusinessAndOrderVariables> result = await _dataConnect + dc.ListShiftRolesByBusinessAndOrderData, + dc.ListShiftRolesByBusinessAndOrderVariables + > + result = await _dataConnect .listShiftRolesByBusinessAndOrder( businessId: businessId, orderId: widget.order.orderId, @@ -139,8 +138,9 @@ class OrderEditSheetState extends State { _orderNameController.text = firstShift.order.eventName ?? ''; _shiftId = shiftRoles.first.shiftId; - final List> positions = - shiftRoles.map((dc.ListShiftRolesByBusinessAndOrderShiftRoles role) { + final List> positions = shiftRoles.map(( + dc.ListShiftRolesByBusinessAndOrderShiftRoles role, + ) { return { 'shiftId': role.shiftId, 'roleId': role.roleId, @@ -158,13 +158,12 @@ class OrderEditSheetState extends State { positions.add(_emptyPosition()); } - final List<_ShiftRoleKey> originalShiftRoles = - shiftRoles - .map( - (dc.ListShiftRolesByBusinessAndOrderShiftRoles role) => - _ShiftRoleKey(shiftId: role.shiftId, roleId: role.roleId), - ) - .toList(); + final List<_ShiftRoleKey> originalShiftRoles = shiftRoles + .map( + (dc.ListShiftRolesByBusinessAndOrderShiftRoles role) => + _ShiftRoleKey(shiftId: role.shiftId, roleId: role.roleId), + ) + .toList(); await _loadVendorsAndSelect(firstShift.order.vendorId); final dc.ListShiftRolesByBusinessAndOrderShiftRolesShiftOrderTeamHub @@ -199,8 +198,10 @@ class OrderEditSheetState extends State { try { final QueryResult< - dc.ListTeamHubsByOwnerIdData, - dc.ListTeamHubsByOwnerIdVariables> result = await _dataConnect + dc.ListTeamHubsByOwnerIdData, + dc.ListTeamHubsByOwnerIdVariables + > + result = await _dataConnect .listTeamHubsByOwnerId(ownerId: businessId) .execute(); @@ -257,8 +258,9 @@ class OrderEditSheetState extends State { Future _loadVendorsAndSelect(String? selectedVendorId) async { try { - final QueryResult result = - await _dataConnect.listVendors().execute(); + final QueryResult result = await _dataConnect + .listVendors() + .execute(); final List vendors = result.data.vendors .map( (dc.ListVendorsVendors vendor) => Vendor( @@ -303,10 +305,13 @@ class OrderEditSheetState extends State { Future _loadRolesForVendor(String vendorId) async { try { - final QueryResult - result = await _dataConnect - .listRolesByVendorId(vendorId: vendorId) - .execute(); + final QueryResult< + dc.ListRolesByVendorIdData, + dc.ListRolesByVendorIdVariables + > + result = await _dataConnect + .listRolesByVendorId(vendorId: vendorId) + .execute(); final List<_RoleOption> roles = result.data.roles .map( (dc.ListRolesByVendorIdRoles role) => _RoleOption( @@ -350,8 +355,9 @@ class OrderEditSheetState extends State { } String _breakValueFromDuration(dc.EnumValue? breakType) { - final dc.BreakDuration? value = - breakType is dc.Known ? breakType.value : null; + final dc.BreakDuration? value = breakType is dc.Known + ? breakType.value + : null; switch (value) { case dc.BreakDuration.MIN_10: return 'MIN_10'; @@ -450,8 +456,9 @@ class OrderEditSheetState extends State { final DateTime date = _parseDate(_dateController.text); final DateTime start = _parseTime(date, pos['start_time'].toString()); final DateTime end = _parseTime(date, pos['end_time'].toString()); - final DateTime normalizedEnd = - end.isBefore(start) ? end.add(const Duration(days: 1)) : end; + final DateTime normalizedEnd = end.isBefore(start) + ? end.add(const Duration(days: 1)) + : end; final double hours = normalizedEnd.difference(start).inMinutes / 60.0; final double rate = _rateForRole(roleId); final int count = pos['count'] as int; @@ -481,8 +488,9 @@ class OrderEditSheetState extends State { int totalWorkers = 0; double shiftCost = 0; - final List<_ShiftRoleKey> remainingOriginal = - List<_ShiftRoleKey>.from(_originalShiftRoles); + final List<_ShiftRoleKey> remainingOriginal = List<_ShiftRoleKey>.from( + _originalShiftRoles, + ); for (final Map pos in _positions) { final String roleId = pos['roleId']?.toString() ?? ''; @@ -492,10 +500,14 @@ class OrderEditSheetState extends State { final String shiftId = pos['shiftId']?.toString() ?? _shiftId!; final int count = pos['count'] as int; - final DateTime start = _parseTime(orderDate, pos['start_time'].toString()); + final DateTime start = _parseTime( + orderDate, + pos['start_time'].toString(), + ); final DateTime end = _parseTime(orderDate, pos['end_time'].toString()); - final DateTime normalizedEnd = - end.isBefore(start) ? end.add(const Duration(days: 1)) : end; + final DateTime normalizedEnd = end.isBefore(start) + ? end.add(const Duration(days: 1)) + : end; final double hours = normalizedEnd.difference(start).inMinutes / 60.0; final double rate = _rateForRole(roleId); final double totalValue = rate * hours * count; @@ -516,11 +528,7 @@ class OrderEditSheetState extends State { .deleteShiftRole(shiftId: shiftId, roleId: originalRoleId) .execute(); await _dataConnect - .createShiftRole( - shiftId: shiftId, - roleId: roleId, - count: count, - ) + .createShiftRole(shiftId: shiftId, roleId: roleId, count: count) .startTime(_toTimestamp(start)) .endTime(_toTimestamp(normalizedEnd)) .hours(hours) @@ -542,11 +550,7 @@ class OrderEditSheetState extends State { } } else { await _dataConnect - .createShiftRole( - shiftId: shiftId, - roleId: roleId, - count: count, - ) + .createShiftRole(shiftId: shiftId, roleId: roleId, count: count) .startTime(_toTimestamp(start)) .endTime(_toTimestamp(normalizedEnd)) .hours(hours) @@ -601,54 +605,6 @@ class OrderEditSheetState extends State { }); } - Future _cancelOrder() async { - final bool? confirm = await showDialog( - context: context, - builder: (BuildContext context) => AlertDialog( - title: const Text('Cancel Order'), - content: const Text( - 'Are you sure you want to cancel this order? This action cannot be undone.', - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, false), - child: const Text('No, Keep It'), - ), - TextButton( - onPressed: () => Navigator.pop(context, true), - style: TextButton.styleFrom(foregroundColor: UiColors.destructive), - child: const Text('Yes, Cancel Order'), - ), - ], - ), - ); - - if (confirm != true) return; - - setState(() => _isLoading = true); - try { - await _dataConnect.deleteOrder(id: widget.order.orderId).execute(); - if (mounted) { - widget.onUpdated?.call(); - Navigator.pop(context); - UiSnackbar.show( - context, - message: 'Order cancelled successfully', - type: UiSnackbarType.success, - ); - } - } catch (e) { - if (mounted) { - setState(() => _isLoading = false); - UiSnackbar.show( - context, - message: 'Failed to cancel order', - type: UiSnackbarType.error, - ); - } - } - } - void _removePosition(int index) { if (_positions.length > 1) { setState(() => _positions.removeAt(index)); @@ -766,8 +722,7 @@ class OrderEditSheetState extends State { size: 18, color: UiColors.iconSecondary, ), - onChanged: - (dc.ListTeamHubsByOwnerIdTeamHubs? hub) { + onChanged: (dc.ListTeamHubsByOwnerIdTeamHubs? hub) { if (hub != null) { setState(() { _selectedHub = hub; @@ -775,18 +730,17 @@ class OrderEditSheetState extends State { }); } }, - items: _hubs.map( - (dc.ListTeamHubsByOwnerIdTeamHubs hub) { - return DropdownMenuItem< - dc.ListTeamHubsByOwnerIdTeamHubs>( - value: hub, - child: Text( - hub.hubName, - style: UiTypography.body2m.textPrimary, - ), - ); - }, - ).toList(), + items: _hubs.map((dc.ListTeamHubsByOwnerIdTeamHubs hub) { + return DropdownMenuItem< + dc.ListTeamHubsByOwnerIdTeamHubs + >( + value: hub, + child: Text( + hub.hubName, + style: UiTypography.body2m.textPrimary, + ), + ); + }).toList(), ), ), ), @@ -810,7 +764,11 @@ class OrderEditSheetState extends State { mainAxisSize: MainAxisSize.min, spacing: UiConstants.space2, children: [ - const Icon(UiIcons.add, size: 16, color: UiColors.primary), + const Icon( + UiIcons.add, + size: 16, + color: UiColors.primary, + ), Text( 'Add Position', style: UiTypography.body2m.primary, @@ -836,21 +794,12 @@ class OrderEditSheetState extends State { label: 'Review ${_positions.length} Positions', onPressed: () => setState(() => _showReview = true), ), - Padding( + const Padding( padding: EdgeInsets.fromLTRB( UiConstants.space5, 0, UiConstants.space5, - MediaQuery.of(context).padding.bottom + UiConstants.space2, - ), - child: UiButton.secondary( - text: 'Cancel Entire Order', - style: OutlinedButton.styleFrom( - foregroundColor: UiColors.destructive, - side: const BorderSide(color: UiColors.destructive), - ), - fullWidth: true, - onPressed: _cancelOrder, + 0, ), ), ], @@ -863,7 +812,9 @@ class OrderEditSheetState extends State { padding: const EdgeInsets.fromLTRB(20, 24, 20, 20), decoration: const BoxDecoration( color: UiColors.primary, - borderRadius: BorderRadius.vertical(top: Radius.circular(UiConstants.space6)), + borderRadius: BorderRadius.vertical( + top: Radius.circular(UiConstants.space6), + ), ), child: Row( children: [ @@ -1279,7 +1230,9 @@ class OrderEditSheetState extends State { height: MediaQuery.of(context).size.height * 0.95, decoration: const BoxDecoration( color: UiColors.bgSecondary, - borderRadius: BorderRadius.vertical(top: Radius.circular(UiConstants.space6)), + borderRadius: BorderRadius.vertical( + top: Radius.circular(UiConstants.space6), + ), ), child: Column( children: [ @@ -1515,7 +1468,9 @@ class OrderEditSheetState extends State { height: MediaQuery.of(context).size.height * 0.95, decoration: const BoxDecoration( color: UiColors.primary, - borderRadius: BorderRadius.vertical(top: Radius.circular(UiConstants.space6)), + borderRadius: BorderRadius.vertical( + top: Radius.circular(UiConstants.space6), + ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/view_order_card.dart b/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/view_order_card.dart index d09d4838..e4c215ac 100644 --- a/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/view_order_card.dart +++ b/apps/mobile/packages/features/client/orders/view_orders/lib/src/presentation/widgets/view_order_card.dart @@ -203,10 +203,7 @@ class _ViewOrderCardState extends State { ), const SizedBox(height: UiConstants.space3), // Title - Text( - order.title, - style: UiTypography.headline3m.textPrimary, - ), + Text(order.title, style: UiTypography.headline3b), Row( spacing: UiConstants.space1, children: [ @@ -224,7 +221,7 @@ class _ViewOrderCardState extends State { const SizedBox(height: UiConstants.space4), // Location (Hub name + Address) Row( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ const Padding( padding: EdgeInsets.only(top: 2), @@ -234,7 +231,7 @@ class _ViewOrderCardState extends State { color: UiColors.iconSecondary, ), ), - const SizedBox(width: UiConstants.space1), + const SizedBox(width: UiConstants.space2), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -242,8 +239,9 @@ class _ViewOrderCardState extends State { if (order.location.isNotEmpty) Text( order.location, - style: - UiTypography.footnote1b.textPrimary, + style: UiTypography + .footnote1b + .textSecondary, maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -294,27 +292,32 @@ class _ViewOrderCardState extends State { const SizedBox(height: UiConstants.space4), // Stats Row - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildStatItem( - icon: UiIcons.dollar, - value: '\$${cost.round()}', - label: t.client_view_orders.card.total, - ), - _buildStatDivider(), - _buildStatItem( - icon: UiIcons.clock, - value: hours.toStringAsFixed(1), - label: t.client_view_orders.card.hrs, - ), - _buildStatDivider(), - _buildStatItem( - icon: UiIcons.users, - value: '${order.workersNeeded}', - label: t.client_create_order.one_time.workers_label, - ), - ], + Padding( + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStatItem( + icon: UiIcons.dollar, + value: '\$${cost.round()}', + label: t.client_view_orders.card.total, + ), + _buildStatDivider(), + _buildStatItem( + icon: UiIcons.clock, + value: hours.toStringAsFixed(1), + label: t.client_view_orders.card.hrs, + ), + _buildStatDivider(), + _buildStatItem( + icon: UiIcons.users, + value: '${order.workersNeeded}', + label: t.client_create_order.one_time.workers_label, + ), + ], + ), ), const SizedBox(height: UiConstants.space5), @@ -486,16 +489,15 @@ class _ViewOrderCardState extends State { padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( color: UiColors.bgSecondary, - borderRadius: UiConstants.radiusMd, + borderRadius: UiConstants.radiusLg, ), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( label.toUpperCase(), style: UiTypography.titleUppercase4m.textSecondary, ), - const SizedBox(height: UiConstants.space1), Text(time, style: UiTypography.body1b.textPrimary), ], ), @@ -715,12 +717,12 @@ class _ViewOrderCardState extends State { required String label, }) { return Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Row( + Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: 14, color: UiColors.iconSecondary), - const SizedBox(width: 6), Text(value, style: UiTypography.body1b.textPrimary), ], ),