diff --git a/apps/mobile/packages/design_system/lib/src/ui_icons.dart b/apps/mobile/packages/design_system/lib/src/ui_icons.dart index 68d101e8..829553e9 100644 --- a/apps/mobile/packages/design_system/lib/src/ui_icons.dart +++ b/apps/mobile/packages/design_system/lib/src/ui_icons.dart @@ -237,4 +237,16 @@ class UiIcons { /// Timer icon static const IconData timer = _IconLib.timer; + + /// Coffee icon for breaks + static const IconData coffee = _IconLib.coffee; + + /// Wifi icon for NFC check-in + static const IconData wifi = _IconLib.wifi; + + /// X Circle icon for no-shows + static const IconData xCircle = _IconLib.xCircle; + + /// Ban icon for cancellations + static const IconData ban = _IconLib.ban; } 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 ed823b5e..6d33312b 100644 --- a/apps/mobile/packages/design_system/lib/src/ui_typography.dart +++ b/apps/mobile/packages/design_system/lib/src/ui_typography.dart @@ -579,4 +579,10 @@ extension TypographyColors on TextStyle { /// Active content color TextStyle get activeContentColor => copyWith(color: UiColors.textPrimary); + + /// Primary color + TextStyle get primary => copyWith(color: UiColors.primary); + + /// Accent color + TextStyle get accent => copyWith(color: UiColors.accent); } diff --git a/apps/mobile/packages/features/staff/authentication/lib/src/presentation/pages/get_started_page.dart b/apps/mobile/packages/features/staff/authentication/lib/src/presentation/pages/get_started_page.dart index 35750c80..fd65b050 100644 --- a/apps/mobile/packages/features/staff/authentication/lib/src/presentation/pages/get_started_page.dart +++ b/apps/mobile/packages/features/staff/authentication/lib/src/presentation/pages/get_started_page.dart @@ -1,3 +1,4 @@ +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; @@ -36,7 +37,7 @@ class GetStartedPage extends StatelessWidget { // Content Overlay Padding( - padding: const EdgeInsets.all(24.0), + padding: const EdgeInsets.all(UiConstants.space6), child: Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -44,7 +45,7 @@ class GetStartedPage extends StatelessWidget { // Main text and actions const GetStartedHeader(), - const SizedBox(height: 48), + const SizedBox(height: UiConstants.space10), // Actions GetStartedActions( @@ -52,7 +53,7 @@ class GetStartedPage extends StatelessWidget { onLoginPressed: onLoginPressed, ), - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), ], ), ), diff --git a/apps/mobile/packages/features/staff/authentication/lib/src/presentation/widgets/get_started_page/get_started_background.dart b/apps/mobile/packages/features/staff/authentication/lib/src/presentation/widgets/get_started_page/get_started_background.dart index 7c370683..1c36e3a8 100644 --- a/apps/mobile/packages/features/staff/authentication/lib/src/presentation/widgets/get_started_page/get_started_background.dart +++ b/apps/mobile/packages/features/staff/authentication/lib/src/presentation/widgets/get_started_page/get_started_background.dart @@ -8,7 +8,7 @@ class GetStartedBackground extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), // Logo Image.asset(UiImageAssets.logoBlue, height: 40), Expanded( @@ -18,9 +18,9 @@ class GetStartedBackground extends StatelessWidget { height: 288, decoration: BoxDecoration( shape: BoxShape.circle, - color: const Color(0xFF3A4A5A).withOpacity(0.05), + color: UiColors.bgSecondary.withValues(alpha: 0.5), ), - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(UiConstants.space2), child: ClipOval( child: Image.network( 'https://images.unsplash.com/photo-1577219491135-ce391730fb2c?w=400&h=400&fit=crop&crop=faces', @@ -50,7 +50,7 @@ class GetStartedBackground extends StatelessWidget { width: 8, height: 8, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.2), + color: UiColors.primary.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(4), ), ), @@ -59,7 +59,7 @@ class GetStartedBackground extends StatelessWidget { width: 8, height: 8, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.2), + color: UiColors.primary.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(4), ), ), diff --git a/apps/mobile/packages/features/staff/availability/lib/src/presentation/pages/availability_page.dart b/apps/mobile/packages/features/staff/availability/lib/src/presentation/pages/availability_page.dart index c07e0307..53e84cbc 100644 --- a/apps/mobile/packages/features/staff/availability/lib/src/presentation/pages/availability_page.dart +++ b/apps/mobile/packages/features/staff/availability/lib/src/presentation/pages/availability_page.dart @@ -79,10 +79,12 @@ class _AvailabilityPageState extends State { child: Column( children: [ Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, - spacing: 24, + spacing: UiConstants.space6, children: [ _buildQuickSet(context), _buildWeekNavigation(context, state), @@ -119,10 +121,10 @@ class _AvailabilityPageState extends State { Widget _buildQuickSet(BuildContext context) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.primary.withValues(alpha: 0.1), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -131,19 +133,19 @@ class _AvailabilityPageState extends State { 'Quick Set Availability', style: UiTypography.body2b, ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Row( children: [ Expanded(child: _buildQuickSetButton(context, 'All Week', 'all')), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: _buildQuickSetButton(context, 'Weekdays', 'weekdays'), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: _buildQuickSetButton(context, 'Weekends', 'weekends'), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: _buildQuickSetButton( context, @@ -179,7 +181,7 @@ class _AvailabilityPageState extends State { ), backgroundColor: UiColors.transparent, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), foregroundColor: isDestructive ? UiColors.destructive @@ -201,17 +203,17 @@ class _AvailabilityPageState extends State { final monthYear = DateFormat('MMMM yyyy').format(middleDate); return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.cardViewBackground, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( children: [ // Nav Header Padding( - padding: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.only(bottom: UiConstants.space4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -275,12 +277,12 @@ class _AvailabilityPageState extends State { onTap: () => context.read().add(SelectDate(day.date)), child: Container( margin: const EdgeInsets.symmetric(horizontal: 2), - padding: const EdgeInsets.symmetric(vertical: 12), + padding: const EdgeInsets.symmetric(vertical: UiConstants.space3), decoration: BoxDecoration( color: isSelected ? UiColors.primary : (isAvailable ? UiColors.tagSuccess : UiColors.bgSecondary), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all( color: isSelected ? UiColors.primary @@ -346,10 +348,10 @@ class _AvailabilityPageState extends State { final isAvailable = day.isAvailable; return Container( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), decoration: BoxDecoration( color: UiColors.cardViewBackground, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( @@ -380,7 +382,7 @@ class _AvailabilityPageState extends State { ], ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), // Time Slots (only from Domain) ...day.slots.map((slot) { @@ -464,11 +466,11 @@ class _AvailabilityPageState extends State { : null, child: AnimatedContainer( duration: const Duration(milliseconds: 200), - margin: const EdgeInsets.only(bottom: 12), - padding: const EdgeInsets.all(16), + margin: const EdgeInsets.only(bottom: UiConstants.space3), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: bgColor, - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all(color: borderColor, width: 2), ), child: Row( @@ -479,7 +481,7 @@ class _AvailabilityPageState extends State { height: 40, decoration: BoxDecoration( color: uiConfig['bg'], - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Icon( uiConfig['icon'], @@ -487,7 +489,7 @@ class _AvailabilityPageState extends State { size: 20, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), // Text Expanded( child: Column( @@ -539,20 +541,20 @@ class _AvailabilityPageState extends State { Widget _buildInfoCard() { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.primary.withValues(alpha: 0.05), - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, - spacing: 12, + spacing: UiConstants.space3, children: [ const Icon(UiIcons.clock, size: 20, color: UiColors.primary), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - spacing: 4, + spacing: UiConstants.space1, children: [ Text( 'Auto-Match uses your availability', diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/pages/clock_in_page.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/pages/clock_in_page.dart index 29df8a28..0164b396 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/pages/clock_in_page.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/pages/clock_in_page.dart @@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:intl/intl.dart'; import 'package:krow_domain/krow_domain.dart'; -import 'package:lucide_icons/lucide_icons.dart'; import '../bloc/clock_in_bloc.dart'; import '../bloc/clock_in_event.dart'; @@ -84,7 +83,9 @@ class _ClockInPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -103,12 +104,13 @@ class _ClockInPageState extends State { // Date Selector DateSelector( selectedDate: state.selectedDate, - onSelect: (DateTime date) => _bloc.add(DateSelected(date)), + onSelect: (DateTime date) => + _bloc.add(DateSelected(date)), shiftDates: [ DateFormat('yyyy-MM-dd').format(DateTime.now()), ], ), - const SizedBox(height: 20), + const SizedBox(height: UiConstants.space5), // Your Activity Header Text( @@ -117,7 +119,7 @@ class _ClockInPageState extends State { style: UiTypography.headline4m, ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), // Selected Shift Info Card if (todayShifts.isNotEmpty) @@ -128,14 +130,16 @@ class _ClockInPageState extends State { onTap: () => _bloc.add(ShiftSelected(shift)), child: Container( - padding: const EdgeInsets.all(12), - margin: - const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all( + UiConstants.space3, + ), + margin: const EdgeInsets.only( + bottom: UiConstants.space3, + ), decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular( - 12, - ), + borderRadius: + UiConstants.radiusLg, border: Border.all( color: shift.id == selectedShift?.id @@ -211,39 +215,41 @@ class _ClockInPageState extends State { ), // Swipe To Check In / Checked Out State / No Shift State - if (selectedShift != null && checkOutTime == null) ...[ - if (!isCheckedIn && - !_isCheckInAllowed(selectedShift)) - Container( - width: double.infinity, - padding: const EdgeInsets.all(24), - decoration: BoxDecoration( - color: UiColors.bgSecondary, - borderRadius: BorderRadius.circular(16), - ), - child: Column( - children: [ - const Icon( - LucideIcons.clock, - size: 48, - color: UiColors.iconThird, - ), - const SizedBox(height: 16), - Text( - "You're early!", - style: UiTypography.body1m.textSecondary, - ), - const SizedBox(height: 4), - Text( - "Check-in available at ${_getCheckInAvailabilityTime(selectedShift)}", - style: UiTypography.body2r.textSecondary, - textAlign: TextAlign.center, - ), - ], - ), - ) - else - SwipeToCheckIn( + if (selectedShift != null && + checkOutTime == null) ...[ + if (!isCheckedIn && + !_isCheckInAllowed(selectedShift)) + Container( + width: double.infinity, + padding: + const EdgeInsets.all(UiConstants.space6), + decoration: BoxDecoration( + color: UiColors.bgSecondary, + borderRadius: UiConstants.radiusLg, + ), + child: Column( + children: [ + const Icon( + UiIcons.clock, + size: 48, + color: UiColors.iconThird, + ), + const SizedBox(height: UiConstants.space4), + Text( + "You're early!", + style: UiTypography.body1m.textSecondary, + ), + const SizedBox(height: UiConstants.space1), + Text( + "Check-in available at ${_getCheckInAvailabilityTime(selectedShift)}", + style: UiTypography.body2r.textSecondary, + textAlign: TextAlign.center, + ), + ], + ), + ) + else + SwipeToCheckIn( isCheckedIn: isCheckedIn, mode: state.checkInMode, isLoading: @@ -264,14 +270,17 @@ class _ClockInPageState extends State { onCheckOut: () { showDialog( context: context, - builder: (BuildContext context) => LunchBreakDialog( - onComplete: () { - Navigator.of( - context, - ).pop(); // Close dialog first - _bloc.add(const CheckOutRequested()); - }, - ), + builder: (BuildContext context) => + LunchBreakDialog( + onComplete: () { + Navigator.of( + context, + ).pop(); // Close dialog first + _bloc.add( + const CheckOutRequested(), + ); + }, + ), ); }, ), @@ -279,12 +288,14 @@ class _ClockInPageState extends State { checkOutTime != null) ...[ // Shift Completed State Container( - padding: const EdgeInsets.all(24), + padding: const EdgeInsets.all(UiConstants.space6), decoration: BoxDecoration( color: UiColors.tagSuccess, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all( - color: UiColors.success.withValues(alpha: 0.3), + color: UiColors.success.withValues( + alpha: 0.3, + ), ), ), child: Column( @@ -297,17 +308,17 @@ class _ClockInPageState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.check, + UiIcons.check, color: UiColors.textSuccess, size: 24, ), ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Text( "Shift Completed!", style: UiTypography.body1b.textSuccess, ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( "Great work today", style: UiTypography.body2r.textSuccess, @@ -319,10 +330,10 @@ class _ClockInPageState extends State { // No Shift State Container( width: double.infinity, - padding: const EdgeInsets.all(24), + padding: const EdgeInsets.all(UiConstants.space6), decoration: BoxDecoration( color: UiColors.bgSecondary, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, ), child: Column( children: [ @@ -331,7 +342,7 @@ class _ClockInPageState extends State { style: UiTypography.body1m.textSecondary, textAlign: TextAlign.center, ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( "Accept a shift to clock in", style: UiTypography.body2r.textSecondary, @@ -344,14 +355,16 @@ class _ClockInPageState extends State { // Checked In Banner if (isCheckedIn && checkInTime != null) ...[ - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Container( - padding: const EdgeInsets.all(12), + padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( color: UiColors.tagSuccess, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all( - color: UiColors.success.withValues(alpha: 0.3), + color: UiColors.success.withValues( + alpha: 0.3, + ), ), ), child: Row( @@ -382,7 +395,7 @@ class _ClockInPageState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.check, + UiIcons.check, color: UiColors.textSuccess, ), ), @@ -419,10 +432,10 @@ class _ClockInPageState extends State { child: GestureDetector( onTap: () => _bloc.add(CheckInModeChanged(value)), child: Container( - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric(vertical: UiConstants.space2), decoration: BoxDecoration( color: isSelected ? UiColors.white : UiColors.transparent, - borderRadius: BorderRadius.circular(8), + borderRadius: UiConstants.radiusMd, boxShadow: isSelected ? [ BoxShadow( @@ -476,21 +489,23 @@ class _ClockInPageState extends State { width: 96, height: 96, decoration: BoxDecoration( - color: scanned ? UiColors.tagSuccess : UiColors.tagInProgress, + color: scanned + ? UiColors.tagSuccess + : UiColors.tagInProgress, shape: BoxShape.circle, ), child: Icon( - scanned ? LucideIcons.check : LucideIcons.nfc, + scanned ? UiIcons.check : UiIcons.nfc, size: 48, color: scanned ? UiColors.textSuccess : UiColors.primary, ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( scanned ? 'Processing check-in...' : 'Ready to scan', style: UiTypography.headline4m, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( scanned ? 'Please wait...' @@ -499,7 +514,7 @@ class _ClockInPageState extends State { style: UiTypography.body2r.textSecondary, ), if (!scanned) ...[ - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), SizedBox( width: double.infinity, height: 56, @@ -520,7 +535,7 @@ class _ClockInPageState extends State { // But this dialog is just a function call. // It's safer to just return a result }, - icon: const Icon(LucideIcons.nfc, size: 24), + icon: const Icon(UiIcons.nfc, size: 24), label: Text( 'Tap to Scan', style: UiTypography.headline4m.white, @@ -529,7 +544,7 @@ class _ClockInPageState extends State { backgroundColor: UiColors.primary, foregroundColor: UiColors.white, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), ), ), diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/attendance_card.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/attendance_card.dart index adc955bb..fc187fdb 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/attendance_card.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/attendance_card.dart @@ -1,6 +1,5 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; enum AttendanceType { checkin, checkout, breaks, days } @@ -24,10 +23,10 @@ class AttendanceCard extends StatelessWidget { final _AttendanceStyle styles = _getStyles(type); return Container( - padding: const EdgeInsets.all(12), + padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.bgSecondary), boxShadow: [ BoxShadow( @@ -46,11 +45,11 @@ class AttendanceCard extends StatelessWidget { height: 32, decoration: BoxDecoration( color: styles.bgColor, - borderRadius: BorderRadius.circular(8), + borderRadius: UiConstants.radiusMd, ), child: Icon(styles.icon, size: 16, color: styles.iconColor), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( title, style: UiTypography.titleUppercase4m.textSecondary, @@ -86,25 +85,25 @@ class AttendanceCard extends StatelessWidget { switch (type) { case AttendanceType.checkin: return _AttendanceStyle( - icon: LucideIcons.logIn, + icon: UiIcons.logIn, bgColor: UiColors.primary.withValues(alpha: 0.1), iconColor: UiColors.primary, ); case AttendanceType.checkout: return _AttendanceStyle( - icon: LucideIcons.logOut, + icon: UiIcons.logOut, bgColor: UiColors.foreground.withValues(alpha: 0.1), iconColor: UiColors.foreground, ); case AttendanceType.breaks: return _AttendanceStyle( - icon: LucideIcons.coffee, + icon: UiIcons.coffee, bgColor: UiColors.accent.withValues(alpha: 0.2), iconColor: UiColors.accentForeground, ); case AttendanceType.days: return _AttendanceStyle( - icon: LucideIcons.calendar, + icon: UiIcons.calendar, bgColor: UiColors.success.withValues(alpha: 0.1), iconColor: UiColors.textSuccess, ); diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/commute_tracker.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/commute_tracker.dart index 65474125..e251b6cb 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/commute_tracker.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/commute_tracker.dart @@ -1,7 +1,6 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:krow_domain/krow_domain.dart'; -import 'package:lucide_icons/lucide_icons.dart'; enum CommuteMode { lockedNoShift, @@ -158,8 +157,8 @@ class _CommuteTrackerState extends State { Widget _buildConsentCard() { return Container( - margin: const EdgeInsets.only(bottom: 20), - padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: UiConstants.space5), + padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, @@ -169,7 +168,7 @@ class _CommuteTrackerState extends State { UiColors.primary.withValues(alpha: 0.1), ], ), - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.05), @@ -192,12 +191,12 @@ class _CommuteTrackerState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.mapPin, + UiIcons.mapPin, size: 16, color: UiColors.white, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -206,7 +205,7 @@ class _CommuteTrackerState extends State { 'Enable Commute Tracking?', style: UiTypography.body2m.textPrimary, ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( 'Share location 1hr before shift so your manager can see you\'re on the way.', style: UiTypography.body4r.textSecondary, @@ -216,7 +215,7 @@ class _CommuteTrackerState extends State { ), ], ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Row( children: [ Expanded( @@ -225,13 +224,15 @@ class _CommuteTrackerState extends State { setState(() => _localHasConsent = false); }, style: OutlinedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space2, + ), side: const BorderSide(color: UiColors.border), ), child: Text('Not Now', style: UiTypography.footnote1m), ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: ElevatedButton( onPressed: () { @@ -239,7 +240,9 @@ class _CommuteTrackerState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space2, + ), ), child: Text( 'Enable', @@ -256,11 +259,11 @@ class _CommuteTrackerState extends State { Widget _buildPreShiftCard() { return Container( - margin: const EdgeInsets.only(bottom: 20), - padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: UiConstants.space5), + padding: const EdgeInsets.all(UiConstants.space3), decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.05), @@ -279,12 +282,12 @@ class _CommuteTrackerState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.navigation, + UiIcons.navigation, size: 16, color: UiColors.textSecondary, ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -295,11 +298,11 @@ class _CommuteTrackerState extends State { 'On My Way', style: UiTypography.body2m.textPrimary, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Row( children: [ const Icon( - LucideIcons.clock, + UiIcons.clock, size: 12, color: UiColors.textInactive, ), @@ -351,7 +354,7 @@ class _CommuteTrackerState extends State { Expanded( child: Center( child: Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -370,7 +373,7 @@ class _CommuteTrackerState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.navigation, + UiIcons.navigation, size: 48, color: UiColors.white, ), @@ -382,12 +385,12 @@ class _CommuteTrackerState extends State { setState(() {}); }, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( 'On My Way', style: UiTypography.displayMb.white, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( 'Your manager can see you\'re heading to the site', style: UiTypography.body2r.copyWith( @@ -395,15 +398,15 @@ class _CommuteTrackerState extends State { ), textAlign: TextAlign.center, ), - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), if (widget.distanceMeters != null) ...[ Container( width: double.infinity, constraints: const BoxConstraints(maxWidth: 300), - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), decoration: BoxDecoration( color: UiColors.white.withValues(alpha: 0.1), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all( color: UiColors.white.withValues(alpha: 0.2), ), @@ -416,7 +419,7 @@ class _CommuteTrackerState extends State { color: UiColors.primaryForeground.withValues(alpha: 0.8), ), ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( _formatDistance(widget.distanceMeters!), style: UiTypography.displayM.white, @@ -425,14 +428,14 @@ class _CommuteTrackerState extends State { ), ), if (widget.etaMinutes != null) ...[ - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Container( width: double.infinity, constraints: const BoxConstraints(maxWidth: 300), - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), decoration: BoxDecoration( color: UiColors.white.withValues(alpha: 0.1), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all( color: UiColors.white.withValues(alpha: 0.2), ), @@ -445,7 +448,7 @@ class _CommuteTrackerState extends State { color: UiColors.primaryForeground.withValues(alpha: 0.8), ), ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( '${widget.etaMinutes} min', style: UiTypography.headline1m.white, @@ -455,7 +458,7 @@ class _CommuteTrackerState extends State { ), ], ], - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), Text( 'Most app features are locked while commute mode is on. You\'ll be able to clock in once you arrive.', style: UiTypography.footnote1r.copyWith( @@ -469,7 +472,7 @@ class _CommuteTrackerState extends State { ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), child: OutlinedButton( onPressed: () { setState(() => _localIsCommuteOn = false); @@ -477,7 +480,9 @@ class _CommuteTrackerState extends State { style: OutlinedButton.styleFrom( foregroundColor: UiColors.white, side: BorderSide(color: UiColors.white.withValues(alpha: 0.3)), - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), minimumSize: const Size(double.infinity, 48), ), child: Text('Turn Off Commute Mode', style: UiTypography.buttonL), @@ -491,8 +496,8 @@ class _CommuteTrackerState extends State { Widget _buildArrivedCard() { return Container( - margin: const EdgeInsets.only(bottom: 20), - padding: const EdgeInsets.all(20), + margin: const EdgeInsets.only(bottom: UiConstants.space5), + padding: const EdgeInsets.all(UiConstants.space5), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, @@ -502,7 +507,7 @@ class _CommuteTrackerState extends State { UiColors.tagActive, ], ), - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.1), @@ -521,17 +526,17 @@ class _CommuteTrackerState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.checkCircle, + UiIcons.check, size: 32, color: UiColors.white, ), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( 'You\'ve Arrived! 🎉', style: UiTypography.headline3m.textPrimary, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( 'You\'re at the shift location. Ready to clock in?', style: UiTypography.body2r.textSecondary, diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/date_selector.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/date_selector.dart index 1e39eecf..2d849477 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/date_selector.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/date_selector.dart @@ -34,10 +34,12 @@ class DateSelector extends StatelessWidget { onTap: () => onSelect(date), child: AnimatedContainer( duration: const Duration(milliseconds: 200), - margin: const EdgeInsets.symmetric(horizontal: 4), + margin: const EdgeInsets.symmetric( + horizontal: UiConstants.space1, + ), decoration: BoxDecoration( color: isSelected ? UiColors.primary : UiColors.white, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, boxShadow: isSelected ? [ BoxShadow( @@ -55,7 +57,8 @@ class DateSelector extends StatelessWidget { DateFormat('d').format(date), style: UiTypography.title1m.copyWith( fontWeight: FontWeight.bold, - color: isSelected ? UiColors.white : UiColors.foreground, + color: + isSelected ? UiColors.white : UiColors.foreground, ), ), const SizedBox(height: 2), @@ -67,7 +70,7 @@ class DateSelector extends StatelessWidget { : UiColors.textInactive, ), ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), if (hasShift) Container( width: 6, diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/location_map_placeholder.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/location_map_placeholder.dart index 4ce26d6d..803d9f7a 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/location_map_placeholder.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/location_map_placeholder.dart @@ -1,6 +1,5 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; class LocationMapPlaceholder extends StatelessWidget { @@ -19,7 +18,7 @@ class LocationMapPlaceholder extends StatelessWidget { width: double.infinity, decoration: BoxDecoration( color: UiColors.border, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, image: DecorationImage( image: const NetworkImage( 'https://maps.googleapis.com/maps/api/staticmap?center=40.7128,-74.0060&zoom=15&size=600x300&maptype=roadmap&markers=color:red%7C40.7128,-74.0060&key=YOUR_API_KEY', @@ -37,9 +36,12 @@ class LocationMapPlaceholder extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(LucideIcons.mapPin, - size: 48, color: UiColors.iconSecondary), - const SizedBox(height: 8), + const Icon( + UiIcons.mapPin, + size: 48, + color: UiColors.iconSecondary, + ), + const SizedBox(height: UiConstants.space2), Text('Map View (GPS)', style: UiTypography.body2r.textSecondary), ], ), @@ -47,14 +49,17 @@ class LocationMapPlaceholder extends StatelessWidget { // Status Overlay Positioned( - bottom: 16, - left: 16, - right: 16, + bottom: UiConstants.space4, + left: UiConstants.space4, + right: UiConstants.space4, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space3, + ), decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.1), @@ -66,15 +71,13 @@ class LocationMapPlaceholder extends StatelessWidget { child: Row( children: [ Icon( - isVerified - ? LucideIcons.checkCircle - : LucideIcons.alertCircle, + isVerified ? UiIcons.checkCircle : UiIcons.warning, color: isVerified ? UiColors.textSuccess : UiColors.destructive, size: 20, ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/lunch_break_modal.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/lunch_break_modal.dart index 524cad92..83f3d58a 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/lunch_break_modal.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/lunch_break_modal.dart @@ -1,6 +1,5 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; class LunchBreakDialog extends StatefulWidget { const LunchBreakDialog({super.key, required this.onComplete}); @@ -48,7 +47,9 @@ class _LunchBreakDialogState extends State { Widget build(BuildContext context) { return Dialog( backgroundColor: UiColors.white, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.space6), + ), child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: _buildCurrentStep(), @@ -75,7 +76,7 @@ class _LunchBreakDialogState extends State { Widget _buildStep1() { return Padding( - padding: const EdgeInsets.all(24), + padding: const EdgeInsets.all(UiConstants.space6), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -87,18 +88,18 @@ class _LunchBreakDialogState extends State { shape: BoxShape.circle, ), child: const Icon( - LucideIcons.coffee, + UiIcons.coffee, size: 40, color: UiColors.iconSecondary, ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( "Did You Take\na Lunch?", textAlign: TextAlign.center, style: UiTypography.headline1m.textPrimary, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Row( children: [ Expanded( @@ -110,10 +111,12 @@ class _LunchBreakDialogState extends State { }); }, child: Container( - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), decoration: BoxDecoration( border: Border.all(color: UiColors.border), - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, color: UiColors.transparent, ), alignment: Alignment.center, @@ -124,7 +127,7 @@ class _LunchBreakDialogState extends State { ), ), ), - const SizedBox(width: 16), + const SizedBox(width: UiConstants.space4), Expanded( child: ElevatedButton( onPressed: () { @@ -135,9 +138,11 @@ class _LunchBreakDialogState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), ), child: Text( @@ -156,169 +161,183 @@ class _LunchBreakDialogState extends State { Widget _buildStep2() { // Time input return Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "When did you take lunch?", - style: UiTypography.headline4m, - ), - const SizedBox(height: 24), - // Mock Inputs - Row( - children: [ - Expanded( - child: DropdownButtonFormField( - isExpanded: true, - value: _breakStart, - items: _timeOptions - .map((String t) => DropdownMenuItem( - value: t, - child: Text(t, style: UiTypography.body3r))) - .toList(), - onChanged: (String? v) => setState(() => _breakStart = v), - decoration: const InputDecoration( - labelText: 'Start', - contentPadding: - EdgeInsets.symmetric(horizontal: 10, vertical: 8), + padding: const EdgeInsets.all(UiConstants.space6), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "When did you take lunch?", + style: UiTypography.headline4m, + ), + const SizedBox(height: UiConstants.space6), + // Mock Inputs + Row( + children: [ + Expanded( + child: DropdownButtonFormField( + isExpanded: true, + value: _breakStart, + items: _timeOptions + .map( + (String t) => DropdownMenuItem( + value: t, + child: Text(t, style: UiTypography.body3r), + ), + ) + .toList(), + onChanged: (String? v) => setState(() => _breakStart = v), + decoration: const InputDecoration( + labelText: 'Start', + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, ), ), ), - const SizedBox(width: 10), - Expanded( - child: DropdownButtonFormField( - isExpanded: true, - value: _breakEnd, - items: _timeOptions - .map((String t) => DropdownMenuItem( - value: t, - child: Text(t, style: UiTypography.body3r))) - .toList(), - onChanged: (String? v) => setState(() => _breakEnd = v), - decoration: const InputDecoration( - labelText: 'End', - contentPadding: - EdgeInsets.symmetric(horizontal: 10, vertical: 8), - ), - ), - ), - ], - ), - - const SizedBox(height: 24), - ElevatedButton( - onPressed: () { - setState(() => _step = 3); - }, - style: ElevatedButton.styleFrom( - backgroundColor: UiColors.primary, - minimumSize: const Size(double.infinity, 48), ), - child: Text("Next", style: UiTypography.body1m.white), + const SizedBox(width: 10), + Expanded( + child: DropdownButtonFormField( + isExpanded: true, + value: _breakEnd, + items: _timeOptions + .map( + (String t) => DropdownMenuItem( + value: t, + child: Text(t, style: UiTypography.body3r), + ), + ) + .toList(), + onChanged: (String? v) => setState(() => _breakEnd = v), + decoration: const InputDecoration( + labelText: 'End', + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, + ), + ), + ), + ), + ], + ), + + const SizedBox(height: UiConstants.space6), + ElevatedButton( + onPressed: () { + setState(() => _step = 3); + }, + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + minimumSize: const Size(double.infinity, 48), ), - ], - )); + child: Text("Next", style: UiTypography.body1m.white), + ), + ], + ), + ); } Widget _buildStep2b() { // No lunch reason return Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - "Why didn't you take lunch?", - style: UiTypography.headline4m, + padding: const EdgeInsets.all(UiConstants.space6), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + "Why didn't you take lunch?", + style: UiTypography.headline4m, + ), + const SizedBox(height: UiConstants.space4), + ..._noLunchReasons.map( + (String reason) => RadioListTile( + title: Text(reason, style: UiTypography.body2r), + value: reason, + groupValue: _noLunchReason, + onChanged: (String? val) => setState(() => _noLunchReason = val), + activeColor: UiColors.primary, ), - const SizedBox(height: 16), - ..._noLunchReasons.map((String reason) => RadioListTile( - title: Text(reason, style: UiTypography.body2r), - value: reason, - groupValue: _noLunchReason, - onChanged: (String? val) => - setState(() => _noLunchReason = val), - activeColor: UiColors.primary, - )), + ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: () { - setState(() => _step = 3); - }, - style: ElevatedButton.styleFrom( - backgroundColor: UiColors.primary, - minimumSize: const Size(double.infinity, 48), - ), - child: Text("Next", style: UiTypography.body1m.white), + const SizedBox(height: UiConstants.space6), + ElevatedButton( + onPressed: () { + setState(() => _step = 3); + }, + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + minimumSize: const Size(double.infinity, 48), ), - ], - )); + child: Text("Next", style: UiTypography.body1m.white), + ), + ], + ), + ); } Widget _buildStep3() { // Additional Notes return Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Additional Notes", - style: UiTypography.headline4m, - ), - const SizedBox(height: 16), - TextField( - onChanged: (String v) => _additionalNotes = v, - style: UiTypography.body2r, - decoration: const InputDecoration( - hintText: 'Add any details...', - border: OutlineInputBorder(), - ), - maxLines: 3, + padding: const EdgeInsets.all(UiConstants.space6), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Additional Notes", + style: UiTypography.headline4m, + ), + const SizedBox(height: UiConstants.space4), + TextField( + onChanged: (String v) => _additionalNotes = v, + style: UiTypography.body2r, + decoration: const InputDecoration( + hintText: 'Add any details...', + border: OutlineInputBorder(), ), + maxLines: 3, + ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: () { - setState(() => _step = 4); - }, - style: ElevatedButton.styleFrom( - backgroundColor: UiColors.primary, - minimumSize: const Size(double.infinity, 48), - ), - child: Text("Submit", style: UiTypography.body1m.white), + const SizedBox(height: UiConstants.space6), + ElevatedButton( + onPressed: () { + setState(() => _step = 4); + }, + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + minimumSize: const Size(double.infinity, 48), ), - ], - )); + child: Text("Submit", style: UiTypography.body1m.white), + ), + ], + ), + ); } - + Widget _buildStep4() { // Success return Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(LucideIcons.checkCircle, - size: 64, color: UiColors.success), - const SizedBox(height: 24), - Text( - "Break Logged!", - style: UiTypography.headline1m, + padding: const EdgeInsets.all(UiConstants.space6), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(UiIcons.checkCircle, size: 64, color: UiColors.success), + const SizedBox(height: UiConstants.space6), + Text( + "Break Logged!", + style: UiTypography.headline1m, + ), + const SizedBox(height: UiConstants.space6), + ElevatedButton( + onPressed: widget.onComplete, + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + minimumSize: const Size(double.infinity, 48), ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: widget.onComplete, - style: ElevatedButton.styleFrom( - backgroundColor: UiColors.primary, - minimumSize: const Size(double.infinity, 48), - ), - child: Text("Close", style: UiTypography.body1m.white), - ), - ], - )); + child: Text("Close", style: UiTypography.body1m.white), + ), + ], + ), + ); } } diff --git a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/swipe_to_check_in.dart b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/swipe_to_check_in.dart index 23987440..bb79e4d3 100644 --- a/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/swipe_to_check_in.dart +++ b/apps/mobile/packages/features/staff/clock_in/lib/src/presentation/widgets/swipe_to_check_in.dart @@ -1,9 +1,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; class SwipeToCheckIn extends StatefulWidget { - const SwipeToCheckIn({ super.key, this.onCheckIn, @@ -73,8 +71,9 @@ class _SwipeToCheckInState extends State @override Widget build(BuildContext context) { - final Color baseColor = - widget.isCheckedIn ? UiColors.success : UiColors.primary; + final Color baseColor = widget.isCheckedIn + ? UiColors.success + : UiColors.primary; if (widget.mode == 'nfc') { return GestureDetector( @@ -93,7 +92,7 @@ class _SwipeToCheckInState extends State height: 56, decoration: BoxDecoration( color: baseColor, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: baseColor.withValues(alpha: 0.4), @@ -106,8 +105,8 @@ class _SwipeToCheckInState extends State child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(LucideIcons.wifi, color: UiColors.white), - const SizedBox(width: 12), + const Icon(UiIcons.wifi, color: UiColors.white), + const SizedBox(width: UiConstants.space3), Text( widget.isLoading ? (widget.isCheckedIn @@ -129,10 +128,12 @@ class _SwipeToCheckInState extends State // Calculate background color based on drag final double progress = _dragValue / maxDrag; - final Color startColor = - widget.isCheckedIn ? UiColors.success : UiColors.primary; - final Color endColor = - widget.isCheckedIn ? UiColors.primary : UiColors.success; + final Color startColor = widget.isCheckedIn + ? UiColors.success + : UiColors.primary; + final Color endColor = widget.isCheckedIn + ? UiColors.primary + : UiColors.success; final Color currentColor = Color.lerp(startColor, endColor, progress) ?? startColor; @@ -140,7 +141,7 @@ class _SwipeToCheckInState extends State height: 56, decoration: BoxDecoration( color: currentColor, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.1), @@ -173,14 +174,16 @@ class _SwipeToCheckInState extends State left: 4 + _dragValue, top: 4, child: GestureDetector( - onHorizontalDragUpdate: (DragUpdateDetails d) => _onDragUpdate(d, maxWidth), - onHorizontalDragEnd: (DragEndDetails d) => _onDragEnd(d, maxWidth), + onHorizontalDragUpdate: (DragUpdateDetails d) => + _onDragUpdate(d, maxWidth), + onHorizontalDragEnd: (DragEndDetails d) => + _onDragEnd(d, maxWidth), child: Container( width: _handleSize, height: _handleSize, decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.1), @@ -191,9 +194,7 @@ class _SwipeToCheckInState extends State ), child: Center( child: Icon( - _isComplete - ? LucideIcons.check - : LucideIcons.arrowRight, + _isComplete ? UiIcons.check : UiIcons.arrowRight, color: startColor, ), ), diff --git a/apps/mobile/packages/features/staff/payments/lib/src/presentation/pages/payments_page.dart b/apps/mobile/packages/features/staff/payments/lib/src/presentation/pages/payments_page.dart index 7801eed1..56ed57b0 100644 --- a/apps/mobile/packages/features/staff/payments/lib/src/presentation/pages/payments_page.dart +++ b/apps/mobile/packages/features/staff/payments/lib/src/presentation/pages/payments_page.dart @@ -1,7 +1,7 @@ +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_modular/flutter_modular.dart'; -import 'package:lucide_icons/lucide_icons.dart'; import 'package:intl/intl.dart'; import 'package:krow_domain/krow_domain.dart'; import '../blocs/payments/payments_bloc.dart'; @@ -33,12 +33,22 @@ class _PaymentsPageState extends State { return BlocProvider.value( value: _bloc, child: Scaffold( + backgroundColor: UiColors.background, body: BlocBuilder( builder: (BuildContext context, PaymentsState state) { if (state is PaymentsLoading) { - return const Center(child: CircularProgressIndicator()); + return Center( + child: CircularProgressIndicator( + color: UiColors.primary, + ), + ); } else if (state is PaymentsError) { - return Center(child: Text('Error: ${state.message}')); + return Center( + child: Text( + 'Error: ${state.message}', + style: UiTypography.body2r.textError, + ), + ); } else if (state is PaymentsLoaded) { return _buildContent(context, state); } @@ -55,63 +65,57 @@ class _PaymentsPageState extends State { children: [ // Header Section with Gradient Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( gradient: LinearGradient( - colors: [Color(0xFF0032A0), Color(0xFF333F48)], + colors: [ + UiColors.primary, + UiColors.primary.withValues(alpha: 0.8), + ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), padding: EdgeInsets.fromLTRB( - 20, - MediaQuery.of(context).padding.top + 24, - 20, - 32, + UiConstants.space5, + MediaQuery.of(context).padding.top + UiConstants.space6, + UiConstants.space5, + UiConstants.space8, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( "Earnings", - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, - ), + style: UiTypography.displayMb.white, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), // Main Balance Center( child: Column( children: [ - const Text( + Text( "Total Earnings", - style: TextStyle( - color: Color(0xFFF8E08E), - fontSize: 14, + style: UiTypography.body2r.copyWith( + color: UiColors.accent, ), ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( "\$${state.summary.totalEarnings.toStringAsFixed(0).replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},')}", - style: const TextStyle( - fontSize: 36, - fontWeight: FontWeight.bold, - color: Colors.white, - ), + style: UiTypography.displayL.white, ), ], ), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), // Period Tabs Container( - padding: const EdgeInsets.all(4), + padding: const EdgeInsets.all(UiConstants.space1), decoration: BoxDecoration( - color: Colors.white.withOpacity(0.2), - borderRadius: BorderRadius.circular(12), + color: UiColors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Row( children: [ @@ -127,9 +131,9 @@ class _PaymentsPageState extends State { // Main Content - Offset upwards Transform.translate( - offset: const Offset(0, -16), + offset: const Offset(0, -UiConstants.space4), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -138,76 +142,75 @@ class _PaymentsPageState extends State { payments: state.history, period: state.activePeriod, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), // Quick Stats Row( children: [ Expanded( child: PaymentStatsCard( - icon: LucideIcons.trendingUp, - iconColor: const Color(0xFF059669), + icon: UiIcons.chart, + iconColor: UiColors.success, label: "This Week", amount: "\$${state.summary.weeklyEarnings}", ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: PaymentStatsCard( - icon: LucideIcons.calendar, - iconColor: const Color(0xFF2563EB), + icon: UiIcons.calendar, + iconColor: UiColors.primary, label: "This Month", amount: "\$${state.summary.monthlyEarnings.toStringAsFixed(0)}", ), ), ], ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), // Pending Pay - if(state.summary.pendingEarnings > 0) PendingPayCard( - amount: state.summary.pendingEarnings, - onCashOut: () { - Modular.to.pushNamed('/early-pay'); - }, - ), - const SizedBox(height: 24), - - + if (state.summary.pendingEarnings > 0) + PendingPayCard( + amount: state.summary.pendingEarnings, + onCashOut: () { + Modular.to.pushNamed('/early-pay'); + }, + ), + const SizedBox(height: UiConstants.space6), // Recent Payments - if (state.history.isNotEmpty) Column( - children: [ - const Text( - "Recent Payments", - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFF0F172A), + if (state.history.isNotEmpty) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Recent Payments", + style: UiTypography.body2m.textPrimary, ), - ), - const SizedBox(height: 12), - Column( - children: state.history.map((StaffPayment payment) { - return Padding( - padding: const EdgeInsets.only(bottom: 8), - child: PaymentHistoryItem( - amount: payment.amount, - title: "Shift Payment", - location: "Varies", - address: "Payment ID: ${payment.id}", - date: payment.paidAt != null - ? DateFormat('E, MMM d').format(payment.paidAt!) - : 'Pending', - workedTime: "Completed", - hours: 0, - rate: 0.0, - status: payment.status.name.toUpperCase(), - ), - ); - }).toList(), - ), - ], - ), + const SizedBox(height: UiConstants.space3), + Column( + children: state.history.map((StaffPayment payment) { + return Padding( + padding: const EdgeInsets.only( + bottom: UiConstants.space2), + child: PaymentHistoryItem( + amount: payment.amount, + title: "Shift Payment", + location: "Varies", + address: "Payment ID: ${payment.id}", + date: payment.paidAt != null + ? DateFormat('E, MMM d') + .format(payment.paidAt!) + : 'Pending', + workedTime: "Completed", + hours: 0, + rate: 0.0, + status: payment.status.name.toUpperCase(), + ), + ); + }).toList(), + ), + ], + ), const SizedBox(height: 100), ], @@ -225,19 +228,17 @@ class _PaymentsPageState extends State { child: GestureDetector( onTap: () => _bloc.add(ChangePeriodEvent(value)), child: Container( - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric(vertical: UiConstants.space2), decoration: BoxDecoration( - color: isSelected ? Colors.white : Colors.transparent, - borderRadius: BorderRadius.circular(8), + color: isSelected ? UiColors.white : Colors.transparent, + borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), ), child: Center( child: Text( label, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: isSelected ? const Color(0xFF0032A0) : Colors.white, - ), + style: isSelected + ? UiTypography.body2m.copyWith(color: UiColors.primary) + : UiTypography.body2m.white, ), ), ), diff --git a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/earnings_graph.dart b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/earnings_graph.dart index 960bb7c7..18a8ac89 100644 --- a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/earnings_graph.dart +++ b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/earnings_graph.dart @@ -1,3 +1,4 @@ +import 'package:design_system/design_system.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -25,26 +26,30 @@ class EarningsGraph extends StatelessWidget { return Container( height: 200, decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + child: Center( + child: Text( + "No sufficient data for graph", + style: UiTypography.body2r.textSecondary, + ), ), - child: const Center(child: Text("No sufficient data for graph")), ); } final List spots = _generateSpots(validPayments); - final double maxX = spots.isNotEmpty ? spots.last.x : 0.0; final double maxY = spots.isNotEmpty ? spots.map((FlSpot s) => s.y).reduce((double a, double b) => a > b ? a : b) : 0.0; return Container( height: 220, - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), offset: const Offset(0, 4), blurRadius: 12, ), @@ -53,15 +58,11 @@ class EarningsGraph extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( "Earnings Trend", - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFF0F172A), - ), + style: UiTypography.body2b.textPrimary, ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Expanded( child: LineChart( LineChartData( @@ -79,7 +80,7 @@ class EarningsGraph extends StatelessWidget { padding: const EdgeInsets.only(top: 8.0), child: Text( DateFormat('d').format(validPayments[index].paidAt!), - style: const TextStyle(fontSize: 10, color: Colors.grey), + style: UiTypography.footnote1r.textSecondary, ), ); } @@ -96,13 +97,13 @@ class EarningsGraph extends StatelessWidget { LineChartBarData( spots: spots, isCurved: true, - color: const Color(0xFF0032A0), + color: UiColors.primary, barWidth: 3, isStrokeCapRound: true, dotData: const FlDotData(show: false), belowBarData: BarAreaData( show: true, - color: const Color(0xFF0032A0).withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), ), ), ], @@ -121,7 +122,7 @@ class EarningsGraph extends StatelessWidget { List _generateSpots(List data) { // Generate spots based on index in the list for simplicity in this demo // Real implementation would map to actual dates on X-axis - return List.generate(data.length, (int index) { + return List.generate(data.length, (int index) { return FlSpot(index.toDouble(), data[index].amount); }); } diff --git a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_history_item.dart b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_history_item.dart index b64b78a9..e068caee 100644 --- a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_history_item.dart +++ b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_history_item.dart @@ -1,5 +1,5 @@ +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; class PaymentHistoryItem extends StatelessWidget { @@ -28,13 +28,13 @@ class PaymentHistoryItem extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -50,23 +50,20 @@ class PaymentHistoryItem extends StatelessWidget { width: 6, height: 6, decoration: const BoxDecoration( - color: Color(0xFF3B82F6), // blue-500 + color: UiColors.primary, shape: BoxShape.circle, ), ), const SizedBox(width: 6), - const Text( + Text( "PAID", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w700, - color: Color(0xFF2563EB), // blue-600 - letterSpacing: 0.5, + style: UiTypography.titleUppercase4b.copyWith( + color: UiColors.primary, ), ), ], ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -76,16 +73,16 @@ class PaymentHistoryItem extends StatelessWidget { width: 44, height: 44, decoration: BoxDecoration( - color: const Color(0xFFF1F5F9), // slate-100 - borderRadius: BorderRadius.circular(12), + color: UiColors.secondary, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: const Icon( - LucideIcons.dollarSign, - color: Color(0xFF334155), // slate-700 + UiIcons.chart, + color: UiColors.mutedForeground, size: 24, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), // Content Expanded( @@ -101,18 +98,11 @@ class PaymentHistoryItem extends StatelessWidget { children: [ Text( title, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFF0F172A), // slate-900 - ), + style: UiTypography.body2b.textPrimary, ), Text( location, - style: const TextStyle( - fontSize: 12, - color: Color(0xFF475569), // slate-600 - ), + style: UiTypography.body3r.textSecondary, ), ], ), @@ -122,75 +112,59 @@ class PaymentHistoryItem extends StatelessWidget { children: [ Text( "\$${amount.toStringAsFixed(0)}", - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Color(0xFF0F172A), // slate-900 - ), + style: UiTypography.headline4m.textPrimary, ), Text( "\$${rate.toStringAsFixed(0)}/hr · ${hours}h", - style: const TextStyle( - fontSize: 10, - color: Color(0xFF64748B), // slate-500 - ), + style: UiTypography.footnote1r.textSecondary, ), ], ), ], ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), // Date and Time Row( children: [ const Icon( - LucideIcons.calendar, + UiIcons.calendar, size: 12, - color: Color(0xFF64748B), + color: UiColors.mutedForeground, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( date, - style: const TextStyle( - fontSize: 12, - color: Color(0xFF64748B), - ), + style: UiTypography.body3r.textSecondary, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), const Icon( - LucideIcons.clock, + UiIcons.clock, size: 12, - color: Color(0xFF64748B), + color: UiColors.mutedForeground, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( workedTime, - style: const TextStyle( - fontSize: 12, - color: Color(0xFF64748B), - ), + style: UiTypography.body3r.textSecondary, ), ], ), - const SizedBox(height: 4), + const SizedBox(height: 1), // Address Row( children: [ const Icon( - LucideIcons.mapPin, + UiIcons.mapPin, size: 12, - color: Color(0xFF64748B), + color: UiColors.mutedForeground, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Expanded( child: Text( address, - style: const TextStyle( - fontSize: 12, - color: Color(0xFF64748B), - ), + style: UiTypography.body3r.textSecondary, maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_stats_card.dart b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_stats_card.dart index 77673455..e49174d5 100644 --- a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_stats_card.dart +++ b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/payment_stats_card.dart @@ -1,7 +1,7 @@ +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; class PaymentStatsCard extends StatelessWidget { - const PaymentStatsCard({ super.key, required this.icon, @@ -9,6 +9,7 @@ class PaymentStatsCard extends StatelessWidget { required this.label, required this.amount, }); + final IconData icon; final Color iconColor; final String label; @@ -17,13 +18,13 @@ class PaymentStatsCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -35,24 +36,17 @@ class PaymentStatsCard extends StatelessWidget { Row( children: [ Icon(icon, size: 16, color: iconColor), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( label, - style: const TextStyle( - fontSize: 12, - color: Color(0xFF64748B), // slate-500 - ), + style: UiTypography.body3r.textSecondary, ), ], ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( amount, - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Color(0xFF0F172A), // slate-900 - ), + style: UiTypography.headline1m.textPrimary, ), ], ), diff --git a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/pending_pay_card.dart b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/pending_pay_card.dart index 54a56f39..fe49fbf8 100644 --- a/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/pending_pay_card.dart +++ b/apps/mobile/packages/features/staff/payments/lib/src/presentation/widgets/pending_pay_card.dart @@ -1,5 +1,5 @@ +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; class PendingPayCard extends StatelessWidget { @@ -14,17 +14,13 @@ class PendingPayCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.all(14), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - gradient: const LinearGradient( - colors: [Color(0xFFEFF6FF), Color(0xFFEFF6FF)], // blue-50 to blue-50 - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - borderRadius: BorderRadius.circular(16), + color: UiColors.tagInProgress, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -36,63 +32,34 @@ class PendingPayCard extends StatelessWidget { Row( children: [ Container( - width: 40, - height: 40, + width: UiConstants.space10, + height: UiConstants.space10, decoration: BoxDecoration( - color: const Color(0xFFE8F0FF), - borderRadius: BorderRadius.circular(8), + color: UiColors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), ), child: const Icon( - LucideIcons.dollarSign, - color: Color(0xFF0047FF), + UiIcons.chart, + color: UiColors.primary, size: 20, ), ), - const SizedBox(width: 10), + const SizedBox(width: UiConstants.space3), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( "Pending", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF0F172A), // slate-900 - fontSize: 14, - ), + style: UiTypography.body2b.textPrimary, ), Text( "\$${amount.toStringAsFixed(0)} available", - style: const TextStyle( - fontSize: 12, - color: Color(0xFF475569), // slate-600 - fontWeight: FontWeight.w500, - ), + style: UiTypography.body3m.textSecondary, ), ], ), ], ), - /* - ElevatedButton.icon( - onPressed: onCashOut, - icon: const Icon(LucideIcons.zap, size: 14), - label: const Text("Early Pay"), - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF0047FF), - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), - elevation: 4, - shadowColor: Colors.black.withOpacity(0.2), - textStyle: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - ), - ), - ), - */ ], ), ); diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart index c92e8a11..2bd2f638 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart @@ -1,22 +1,21 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart' hide ReadContext; import 'package:flutter_modular/flutter_modular.dart'; -import 'package:core_localization/core_localization.dart'; -import 'package:design_system/design_system.dart'; +import 'package:krow_core/core.dart'; import 'package:krow_domain/krow_domain.dart'; import '../blocs/profile_cubit.dart'; import '../blocs/profile_state.dart'; -import 'package:krow_core/core.dart'; +import '../widgets/language_selector_bottom_sheet.dart'; import '../widgets/logout_button.dart'; +import '../widgets/profile_header.dart'; import '../widgets/profile_menu_grid.dart'; import '../widgets/profile_menu_item.dart'; -import '../widgets/profile_header.dart'; import '../widgets/reliability_score_bar.dart'; import '../widgets/reliability_stats_card.dart'; -import '../widgets/reliability_stats_card.dart'; import '../widgets/section_title.dart'; -import '../widgets/language_selector_bottom_sheet.dart'; /// The main Staff Profile page. /// @@ -68,17 +67,15 @@ class StaffProfilePage extends StatelessWidget { }, builder: (context, state) { // Show loading spinner if status is loading - if (state.status == ProfileStatus.loading) { - return const Center(child: CircularProgressIndicator()); - } + if (state.status == ProfileStatus.loading) { + return const Center(child: CircularProgressIndicator()); + } - if (state.status == ProfileStatus.error) { + if (state.status == ProfileStatus.error) { return Center( child: Text( state.errorMessage ?? 'An error occurred', - style: UiTypography.body1r.copyWith( - color: UiColors.destructive, - ), + style: UiTypography.body1r.textError, ), ); } @@ -121,7 +118,6 @@ class StaffProfilePage extends StatelessWidget { SectionTitle(i18n.sections.onboarding), ProfileMenuGrid( crossAxisCount: 3, - children: [ ProfileMenuItem( icon: UiIcons.user, @@ -181,18 +177,23 @@ class StaffProfilePage extends StatelessWidget { ), const SizedBox(height: UiConstants.space6), SectionTitle( - i18n.header.title.contains("Perfil") ? "Ajustes" : "Settings", + i18n.header.title.contains("Perfil") + ? "Ajustes" + : "Settings", ), ProfileMenuGrid( crossAxisCount: 3, children: [ ProfileMenuItem( icon: UiIcons.globe, - label: i18n.header.title.contains("Perfil") ? "Idioma" : "Language", + label: i18n.header.title.contains("Perfil") + ? "Idioma" + : "Language", onTap: () { showModalBottomSheet( context: context, - builder: (context) => const LanguageSelectorBottomSheet(), + builder: (context) => + const LanguageSelectorBottomSheet(), ); }, ), diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/language_selector_bottom_sheet.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/language_selector_bottom_sheet.dart index 057a17c9..06c4bda9 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/language_selector_bottom_sheet.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/language_selector_bottom_sheet.dart @@ -1,7 +1,6 @@ import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_modular/flutter_modular.dart'; /// A bottom sheet that allows the user to select their preferred language. @@ -15,10 +14,12 @@ class LanguageSelectorBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.all(UiConstants.space6), - decoration: BoxDecoration( + padding: const EdgeInsets.all(UiConstants.space6), + decoration: const BoxDecoration( color: UiColors.background, - borderRadius: BorderRadius.vertical(top: Radius.circular(UiConstants.radiusBase)), + borderRadius: BorderRadius.vertical( + top: Radius.circular(UiConstants.radiusBase), + ), ), child: Column( mainAxisSize: MainAxisSize.min, @@ -29,19 +30,19 @@ class LanguageSelectorBottomSheet extends StatelessWidget { style: UiTypography.headline4m, textAlign: TextAlign.center, ), - SizedBox(height: UiConstants.space6), + const SizedBox(height: UiConstants.space6), _buildLanguageOption( context, label: 'English', locale: AppLocale.en, ), - SizedBox(height: UiConstants.space4), + const SizedBox(height: UiConstants.space4), _buildLanguageOption( context, label: 'Español', locale: AppLocale.es, ), - SizedBox(height: UiConstants.space6), + const SizedBox(height: UiConstants.space6), ], ), ); @@ -62,21 +63,23 @@ class LanguageSelectorBottomSheet extends StatelessWidget { onTap: () { // Dispatch the ChangeLocale event to the LocaleBloc Modular.get().add(ChangeLocale(locale.flutterLocale)); - + // Close the bottom sheet Navigator.pop(context); - + // Force a rebuild of the entire app to reflect locale change instantly if not handled by root widget // (Usually handled by BlocBuilder at the root, but this ensures settings are updated) }, borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), child: Container( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: UiConstants.space4, horizontal: UiConstants.space4, ), decoration: BoxDecoration( - color: isSelected ? UiColors.primary.withValues(alpha: 0.1) : UiColors.background, + color: isSelected + ? UiColors.primary.withValues(alpha: 0.1) + : UiColors.background, borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), border: Border.all( color: isSelected ? UiColors.primary : UiColors.border, @@ -88,12 +91,10 @@ class LanguageSelectorBottomSheet extends StatelessWidget { children: [ Text( label, - style: isSelected - ? UiTypography.body1b.copyWith(color: UiColors.primary) - : UiTypography.body1r, + style: isSelected ? UiTypography.body1b.primary : UiTypography.body1r, ), if (isSelected) - Icon( + const Icon( UiIcons.check, color: UiColors.primary, size: 24.0, diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/logout_button.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/logout_button.dart index 3e81c641..a76e14f6 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/logout_button.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/logout_button.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; /// The sign-out button widget. /// @@ -14,31 +13,33 @@ class LogoutButton extends StatelessWidget { @override Widget build(BuildContext context) { final i18n = t.staff.profile.header; - + return Container( width: double.infinity, decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Material( color: const Color(0x00000000), child: InkWell( onTap: onTap, - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: UiConstants.radiusLg, child: Padding( - padding: EdgeInsets.symmetric(vertical: UiConstants.space4), + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(LucideIcons.logOut, color: UiColors.destructive, size: 20), - SizedBox(width: UiConstants.space2), + const Icon( + UiIcons.logOut, + color: UiColors.destructive, + size: 20, + ), + const SizedBox(width: UiConstants.space2), Text( i18n.sign_out, - style: UiTypography.body1m.copyWith( - color: UiColors.destructive, - ), + style: UiTypography.body1m.textError, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_header.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_header.dart index 9d15de3e..bee90690 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_header.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_header.dart @@ -34,13 +34,13 @@ class ProfileHeader extends StatelessWidget { return Container( width: double.infinity, - padding: EdgeInsets.fromLTRB( + padding: const EdgeInsets.fromLTRB( UiConstants.space5, UiConstants.space5, UiConstants.space5, UiConstants.space16, ), - decoration: BoxDecoration( + decoration: const BoxDecoration( color: UiColors.primary, borderRadius: BorderRadius.vertical( bottom: Radius.circular(UiConstants.space6), @@ -56,22 +56,20 @@ class ProfileHeader extends StatelessWidget { children: [ Text( i18n.title, - style: UiTypography.headline4m.copyWith( - color: UiColors.primaryForeground, - ), + style: UiTypography.headline4m.textSecondary, ), GestureDetector( onTap: onSignOutTap, child: Text( i18n.sign_out, style: UiTypography.body2m.copyWith( - color: UiColors.primaryForeground.withOpacity(0.8), + color: UiColors.primaryForeground.withValues(alpha: 0.8), ), ), ), ], ), - SizedBox(height: UiConstants.space8), + const SizedBox(height: UiConstants.space8), // Avatar Section Stack( alignment: Alignment.bottomRight, @@ -79,7 +77,7 @@ class ProfileHeader extends StatelessWidget { Container( width: 112, height: 112, - padding: EdgeInsets.all(UiConstants.space1), + padding: const EdgeInsets.all(UiConstants.space1), decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( @@ -87,13 +85,13 @@ class ProfileHeader extends StatelessWidget { end: Alignment.bottomRight, colors: [ UiColors.accent, - UiColors.accent.withOpacity(0.5), + UiColors.accent.withValues(alpha: 0.5), UiColors.primaryForeground, ], ), boxShadow: [ BoxShadow( - color: UiColors.foreground.withOpacity(0.2), + color: UiColors.foreground.withValues(alpha: 0.2), blurRadius: 10, offset: const Offset(0, 4), ), @@ -103,7 +101,7 @@ class ProfileHeader extends StatelessWidget { decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( - color: UiColors.primaryForeground.withOpacity(0.2), + color: UiColors.primaryForeground.withValues(alpha: 0.2), width: 4, ), ), @@ -123,16 +121,16 @@ class ProfileHeader extends StatelessWidget { end: Alignment.bottomRight, colors: [ UiColors.accent, - UiColors.accent.withOpacity(0.7), + UiColors.accent.withValues(alpha: 0.7), ], ), ), alignment: Alignment.center, child: Text( - fullName.isNotEmpty ? fullName[0].toUpperCase() : 'K', - style: UiTypography.displayM.copyWith( - color: UiColors.primary, - ), + fullName.isNotEmpty + ? fullName[0].toUpperCase() + : 'K', + style: UiTypography.displayM.primary, ), ) : null, @@ -148,7 +146,7 @@ class ProfileHeader extends StatelessWidget { border: Border.all(color: UiColors.primary, width: 2), boxShadow: [ BoxShadow( - color: UiColors.foreground.withOpacity(0.1), + color: UiColors.foreground.withValues(alpha: 0.1), blurRadius: 4, ), ], @@ -161,28 +159,24 @@ class ProfileHeader extends StatelessWidget { ), ], ), - SizedBox(height: UiConstants.space4), + const SizedBox(height: UiConstants.space4), Text( fullName, - style: UiTypography.headline3m.copyWith( - color: UiColors.primaryForeground, - ), + style: UiTypography.headline3m.textPlaceholder, ), - SizedBox(height: UiConstants.space1), + const SizedBox(height: UiConstants.space1), Container( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: UiConstants.space3, vertical: UiConstants.space1, ), decoration: BoxDecoration( - color: UiColors.accent.withOpacity(0.2), + color: UiColors.accent.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(UiConstants.space5), ), child: Text( level, - style: UiTypography.footnote1b.copyWith( - color: UiColors.accent, - ), + style: UiTypography.footnote1b.accent, ), ), ], diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_menu_item.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_menu_item.dart index 6fafeaa9..d61fac6f 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_menu_item.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/profile_menu_item.dart @@ -25,10 +25,10 @@ class ProfileMenuItem extends StatelessWidget { child: Container( decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), - padding: EdgeInsets.all(UiConstants.space2), + padding: const EdgeInsets.all(UiConstants.space2), child: AspectRatio( aspectRatio: 1.0, child: Stack( @@ -42,24 +42,23 @@ class ProfileMenuItem extends StatelessWidget { width: 36, height: 36, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.08), - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + color: UiColors.primary.withValues(alpha: 0.08), + borderRadius: UiConstants.radiusLg, ), alignment: Alignment.center, child: Icon(icon, color: UiColors.primary, size: 20), ), - SizedBox(height: UiConstants.space1), + const SizedBox(height: UiConstants.space1), Padding( - padding: EdgeInsets.symmetric(horizontal: UiConstants.space1), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space1, + ), child: Text( label, textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, - style: UiTypography.footnote1m.copyWith( - color: UiColors.foreground, - height: 1.2, - ), + style: UiTypography.footnote1m.textSecondary, ), ), ], @@ -76,16 +75,18 @@ class ProfileMenuItem extends StatelessWidget { shape: BoxShape.circle, color: completed! ? UiColors.primary - : UiColors.primary.withOpacity(0.1), + : UiColors.primary.withValues(alpha: 0.1), ), alignment: Alignment.center, child: completed! - ? const Icon(Icons.check, size: 10, color: UiColors.primaryForeground) + ? const Icon( + UiIcons.check, + size: 10, + color: UiColors.primaryForeground, + ) : Text( "!", - style: UiTypography.footnote2b.copyWith( - color: UiColors.primary, - ), + style: UiTypography.footnote2b.primary, ), ), ), diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_score_bar.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_score_bar.dart index 4fa8838b..82c0e4ea 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_score_bar.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_score_bar.dart @@ -19,10 +19,10 @@ class ReliabilityScoreBar extends StatelessWidget { final score = (reliabilityScore ?? 0) / 100; return Container( - padding: EdgeInsets.all(UiConstants.space4), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.1), - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + color: UiColors.primary.withValues(alpha: 0.1), + borderRadius: UiConstants.radiusLg, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -32,19 +32,15 @@ class ReliabilityScoreBar extends StatelessWidget { children: [ Text( i18n.title, - style: UiTypography.body2m.copyWith( - color: UiColors.primary, - ), + style: UiTypography.body2m.primary, ), Text( "${reliabilityScore ?? 0}%", - style: UiTypography.headline4m.copyWith( - color: UiColors.primary, - ), + style: UiTypography.headline4m.primary, ), ], ), - SizedBox(height: UiConstants.space2), + const SizedBox(height: UiConstants.space2), ClipRRect( borderRadius: BorderRadius.circular(UiConstants.space1), child: LinearProgressIndicator( @@ -55,12 +51,10 @@ class ReliabilityScoreBar extends StatelessWidget { ), ), Padding( - padding: EdgeInsets.only(top: UiConstants.space2), + padding: const EdgeInsets.only(top: UiConstants.space2), child: Text( i18n.description, - style: UiTypography.footnote2r.copyWith( - color: UiColors.mutedForeground, - ), + style: UiTypography.footnote2r.textSecondary, ), ), ], diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_stats_card.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_stats_card.dart index 05594a60..b883e003 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_stats_card.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/reliability_stats_card.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:lucide_icons/lucide_icons.dart'; import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; /// Displays the staff member's reliability statistics (Shifts, Rating, On Time, etc.). /// @@ -24,14 +23,14 @@ class ReliabilityStatsCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.all(UiConstants.space4), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), boxShadow: [ BoxShadow( - color: UiColors.foreground.withOpacity(0.05), + color: UiColors.foreground.withValues(alpha: 0.05), blurRadius: 4, offset: const Offset(0, 1), ), @@ -42,31 +41,31 @@ class ReliabilityStatsCard extends StatelessWidget { children: [ _buildStatItem( context, - LucideIcons.briefcase, + UiIcons.briefcase, "${totalShifts ?? 0}", "Shifts", ), _buildStatItem( context, - LucideIcons.star, + UiIcons.star, (averageRating ?? 0.0).toStringAsFixed(1), "Rating", ), _buildStatItem( context, - LucideIcons.clock, + UiIcons.clock, "${onTimeRate ?? 0}%", "On Time", ), _buildStatItem( context, - LucideIcons.xCircle, + UiIcons.xCircle, "${noShowCount ?? 0}", "No Shows", ), _buildStatItem( context, - LucideIcons.ban, + UiIcons.ban, "${cancellationCount ?? 0}", "Cancel.", ), @@ -88,26 +87,22 @@ class ReliabilityStatsCard extends StatelessWidget { width: 40, height: 40, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), ), alignment: Alignment.center, child: Icon(icon, size: 20, color: UiColors.primary), ), - SizedBox(height: UiConstants.space1), + const SizedBox(height: UiConstants.space1), Text( value, - style: UiTypography.body1b.copyWith( - color: UiColors.foreground, - ), + style: UiTypography.body1b.textSecondary, ), FittedBox( fit: BoxFit.scaleDown, child: Text( label, - style: UiTypography.footnote2r.copyWith( - color: UiColors.mutedForeground, - ), + style: UiTypography.footnote2r.textSecondary, ), ), ], diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/section_title.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/section_title.dart index 89167c61..3cd0c9e0 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/section_title.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/section_title.dart @@ -13,14 +13,11 @@ class SectionTitle extends StatelessWidget { Widget build(BuildContext context) { return Container( width: double.infinity, - padding: EdgeInsets.only(left: UiConstants.space1), - margin: EdgeInsets.only(bottom: UiConstants.space3), + padding: const EdgeInsets.only(left: UiConstants.space1), + margin: const EdgeInsets.only(bottom: UiConstants.space3), child: Text( title.toUpperCase(), - style: UiTypography.footnote1b.copyWith( - color: UiColors.mutedForeground, - letterSpacing: 0.5, - ), + style: UiTypography.footnote1b.textSecondary, ), ); } diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/pages/certificates_page.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/pages/certificates_page.dart index f9ac8f85..cd28047d 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/pages/certificates_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/pages/certificates_page.dart @@ -53,7 +53,7 @@ class CertificatesPage extends StatelessWidget { Transform.translate( offset: const Offset(0, -48), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), child: Column( children: [ ...documents.map((StaffDocument doc) => CertificateCard( @@ -70,11 +70,11 @@ class CertificatesPage extends StatelessWidget { ); }, )), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), AddCertificateCard( onTap: () => _showUploadModal(context, null), ), - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), ], ), ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/add_certificate_card.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/add_certificate_card.dart index 315e91ec..8e0634a1 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/add_certificate_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/add_certificate_card.dart @@ -12,37 +12,36 @@ class AddCertificateCard extends StatelessWidget { return GestureDetector( onTap: onTap, child: Container( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, - colors: [Colors.grey[50]!, Colors.grey[100]!], // Keep prototype style + colors: [ + UiColors.bgSecondary.withValues(alpha: 0.5), + UiColors.bgSecondary, + ], ), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all( - color: Colors.grey[300]!, + color: UiColors.border, style: BorderStyle.solid, ), ), child: Row( children: [ const Icon(UiIcons.add, color: UiColors.primary, size: 24), - const SizedBox(width: 16), + const SizedBox(width: UiConstants.space4), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( t.staff_certificates.add_more.title, - style: UiTypography.body1b.copyWith( // 16px Bold - color: UiColors.textPrimary, - ), + style: UiTypography.body1b.textPrimary, ), Text( t.staff_certificates.add_more.subtitle, - style: UiTypography.body3r.copyWith( // 12px Regular - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_card.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_card.dart index c1cca227..c798f97a 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_card.dart @@ -1,8 +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:core_localization/core_localization.dart'; class CertificateCard extends StatelessWidget { final StaffDocument document; @@ -39,13 +39,13 @@ class CertificateCard extends StatelessWidget { final _CertificateUiProps uiProps = _getUiProps(document.documentId); return Container( - margin: const EdgeInsets.only(bottom: 16), + margin: const EdgeInsets.only(bottom: UiConstants.space4), decoration: BoxDecoration( color: UiColors.white, - borderRadius: BorderRadius.circular(UiConstants.space4), + borderRadius: UiConstants.radiusLg, boxShadow: [ BoxShadow( - color: UiColors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 4, offset: const Offset(0, 2), ), @@ -57,11 +57,14 @@ class CertificateCard extends StatelessWidget { children: [ if (isExpiring || isExpired) Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space2, + ), decoration: BoxDecoration( - color: const Color(0xFFF9E547).withOpacity(0.2), // Yellow tint - border: const Border( - bottom: BorderSide(color: Color(0x66F9E547)), + color: UiColors.accent.withValues(alpha: 0.2), // Yellow tint + border: Border( + bottom: BorderSide(color: UiColors.accent.withValues(alpha: 0.4)), ), ), child: Row( @@ -76,16 +79,14 @@ class CertificateCard extends StatelessWidget { isExpired ? t.staff_certificates.card.expired : t.staff_certificates.card.expires_in_days(days: _daysUntilExpiry(document.expiryDate)), - style: UiTypography.body3m.copyWith( // 12px Medium - color: UiColors.textPrimary, - ), + style: UiTypography.body3m.textPrimary, ), ], ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(UiConstants.space5), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -96,8 +97,8 @@ class CertificateCard extends StatelessWidget { width: 64, height: 64, decoration: BoxDecoration( - color: uiProps.color.withOpacity(0.1), - borderRadius: BorderRadius.circular(16), + color: uiProps.color.withValues(alpha: 0.1), + borderRadius: UiConstants.radiusLg, ), child: Center( child: Icon( @@ -137,7 +138,7 @@ class CertificateCard extends StatelessWidget { ), ], ), - const SizedBox(width: 16), + const SizedBox(width: UiConstants.space4), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -151,16 +152,12 @@ class CertificateCard extends StatelessWidget { children: [ Text( document.name, - style: UiTypography.body1m.copyWith( // 16px Medium - color: UiColors.textPrimary, - ), + style: UiTypography.body1m.textPrimary, ), const SizedBox(height: 2), Text( document.description ?? '', // Optional description - style: UiTypography.body3r.copyWith( // 12px Regular - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ), @@ -172,7 +169,7 @@ class CertificateCard extends StatelessWidget { ), ], ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), if (showComplete) _buildCompleteStatus(document.expiryDate), @@ -186,9 +183,11 @@ class CertificateCard extends StatelessWidget { style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, + ), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space3, ), - padding: const EdgeInsets.symmetric(vertical: 12), elevation: 0, ), child: Row( @@ -202,9 +201,7 @@ class CertificateCard extends StatelessWidget { const SizedBox(width: 8), Text( t.staff_certificates.card.upload_button, - style: UiTypography.body2m.copyWith( // 14px Medium - color: UiColors.white, - ), + style: UiTypography.body2m.white, ), ], ), @@ -212,7 +209,7 @@ class CertificateCard extends StatelessWidget { ), if (showComplete || isExpiring || isExpired) ...[ - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), SizedBox( width: double.infinity, child: OutlinedButton.icon( @@ -223,13 +220,15 @@ class CertificateCard extends StatelessWidget { foregroundColor: UiColors.textPrimary, side: const BorderSide(color: UiColors.border), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, + ), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space3, ), - padding: const EdgeInsets.symmetric(vertical: 12), ), ), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), SizedBox( width: double.infinity, child: TextButton.icon( @@ -238,9 +237,11 @@ class CertificateCard extends StatelessWidget { label: Text(t.staff_certificates.card.remove), style: TextButton.styleFrom( foregroundColor: UiColors.destructive, - padding: const EdgeInsets.symmetric(vertical: 12), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space3, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), ), ), @@ -274,16 +275,14 @@ class CertificateCard extends StatelessWidget { const SizedBox(width: 8), Text( t.staff_certificates.card.verified, - style: UiTypography.body2m.copyWith( - color: UiColors.primary, - ), + style: UiTypography.body2m.textPrimary, ), ], ), if (expiryDate != null) Text( t.staff_certificates.card.exp(date: DateFormat('MMM d, yyyy').format(expiryDate)), - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ], ); diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_upload_modal.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_upload_modal.dart index 852038a2..5651d6af 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_upload_modal.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificate_upload_modal.dart @@ -6,7 +6,8 @@ import 'package:flutter/material.dart'; class CertificateUploadModal extends StatelessWidget { /// The document being edited, or null for a new upload. // ignore: unused_field - final dynamic document; // Using dynamic for now as we don't import domain here to avoid direct coupling if possible, but actually we should import domain. + final dynamic + document; // Using dynamic for now as we don't import domain here to avoid direct coupling if possible, but actually we should import domain. // Ideally, widgets should be dumb. Let's import domain. final VoidCallback onSave; @@ -24,13 +25,13 @@ class CertificateUploadModal extends StatelessWidget { return Container( height: MediaQuery.of(context).size.height * 0.75, decoration: const BoxDecoration( - color: Colors.white, + color: UiColors.bgPopup, borderRadius: BorderRadius.only( - topLeft: Radius.circular(24), - topRight: Radius.circular(24), + topLeft: Radius.circular(UiConstants.radiusBase), + topRight: Radius.circular(UiConstants.radiusBase), ), ), - padding: const EdgeInsets.all(24), + padding: const EdgeInsets.all(UiConstants.space6), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -39,7 +40,7 @@ class CertificateUploadModal extends StatelessWidget { children: [ Text( t.staff_certificates.upload_modal.title, - style: UiTypography.headline3m.copyWith(color: UiColors.textPrimary), + style: UiTypography.headline3m.textPrimary, ), IconButton( onPressed: onCancel, @@ -47,35 +48,42 @@ class CertificateUploadModal extends StatelessWidget { ), ], ), - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), Text( t.staff_certificates.upload_modal.expiry_label, style: UiTypography.body1m, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space3, + ), decoration: BoxDecoration( border: Border.all(color: UiColors.border), - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), child: Row( children: [ - const Icon(UiIcons.calendar, size: 20, color: UiColors.textSecondary), - const SizedBox(width: 12), + const Icon( + UiIcons.calendar, + size: 20, + color: UiColors.textSecondary, + ), + const SizedBox(width: UiConstants.space3), Text( t.staff_certificates.upload_modal.select_date, - style: UiTypography.body1m.copyWith(color: UiColors.textSecondary), + style: UiTypography.body1m.textSecondary, ), ], ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( t.staff_certificates.upload_modal.upload_file, style: UiTypography.body1m, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Expanded( child: Container( width: double.infinity, @@ -84,16 +92,16 @@ class CertificateUploadModal extends StatelessWidget { color: UiColors.border, style: BorderStyle.solid, ), - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, color: UiColors.background, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( - padding: const EdgeInsets.all(16), - decoration: const BoxDecoration( - color: Color(0xFFEFF6FF), // Light blue + padding: const EdgeInsets.all(UiConstants.space4), + decoration: BoxDecoration( + color: UiColors.tagActive, shape: BoxShape.circle, ), child: const Icon( @@ -102,7 +110,7 @@ class CertificateUploadModal extends StatelessWidget { color: UiColors.primary, ), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( t.staff_certificates.upload_modal.drag_drop, style: UiTypography.body1m, @@ -110,43 +118,51 @@ class CertificateUploadModal extends StatelessWidget { const SizedBox(height: 4), Text( t.staff_certificates.upload_modal.supported_formats, - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ], ), ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Row( children: [ Expanded( child: OutlinedButton( onPressed: onCancel, style: OutlinedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), side: const BorderSide(color: UiColors.border), ), - child: Text(t.staff_certificates.upload_modal.cancel, - style: UiTypography.body1m.copyWith(color: UiColors.textPrimary)), + child: Text( + t.staff_certificates.upload_modal.cancel, + style: UiTypography.body1m.textPrimary, + ), ), ), - const SizedBox(width: 16), + const SizedBox(width: UiConstants.space4), Expanded( child: ElevatedButton( onPressed: onSave, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), elevation: 0, ), - child: Text(t.staff_certificates.upload_modal.save, - style: UiTypography.body1m.copyWith(color: Colors.white)), + child: Text( + t.staff_certificates.upload_modal.save, + style: UiTypography.body1m.white, + ), ), ), ], diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificates_header.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificates_header.dart index 0d07100f..49555db9 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificates_header.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/presentation/widgets/certificates_header.dart @@ -20,13 +20,21 @@ class CertificatesHeader extends StatelessWidget { final int progressPercent = totalCount == 0 ? 0 : (progressValue * 100).round(); return Container( - padding: const EdgeInsets.fromLTRB(20, 60, 20, 80), + padding: const EdgeInsets.fromLTRB( + UiConstants.space5, + 60, + UiConstants.space5, + 80, + ), // Keeping gradient as per prototype layout requirement decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, - colors: [UiColors.primary, Color(0xFF1E40AF)], // Using Primary and a darker shade + colors: [ + UiColors.primary, + Color(0xFF1E40AF), + ], // Using Primary and a darker shade ), ), child: Column( @@ -39,7 +47,7 @@ class CertificatesHeader extends StatelessWidget { width: 40, height: 40, decoration: BoxDecoration( - color: UiColors.white.withOpacity(0.1), + color: UiColors.white.withValues(alpha: 0.1), shape: BoxShape.circle, ), child: const Icon( @@ -49,16 +57,14 @@ class CertificatesHeader extends StatelessWidget { ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Text( t.staff_certificates.title, - style: UiTypography.headline3m.copyWith( // 18px Bold - color: UiColors.white, - ), + style: UiTypography.headline3m.white, ), ], ), - const SizedBox(height: 32), + const SizedBox(height: UiConstants.space8), Row( children: [ SizedBox( @@ -70,53 +76,48 @@ class CertificatesHeader extends StatelessWidget { CircularProgressIndicator( value: progressValue, strokeWidth: 8, - backgroundColor: UiColors.white.withOpacity(0.2), + backgroundColor: UiColors.white.withValues(alpha: 0.2), valueColor: const AlwaysStoppedAnimation( - Color(0xFFF9E547), // Yellow from prototype + UiColors.accent, // Yellow from prototype ), ), Center( child: Text( '$progressPercent%', - style: UiTypography.display1b.copyWith( // 26px Bold - color: UiColors.white, - ), + style: UiTypography.display1b.white, ), ), ], ), ), - const SizedBox(width: 24), + const SizedBox(width: UiConstants.space6), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( t.staff_certificates.progress.title, - style: UiTypography.body1b.copyWith( // 16px Bold - color: UiColors.white, - ), + style: UiTypography.body1b.white, ), const SizedBox(height: 4), Text( - t.staff_certificates.progress.verified_count(completed: completedCount, total: totalCount), - style: UiTypography.body3r.copyWith( // 12px Regular - color: UiColors.white.withOpacity(0.7), + t.staff_certificates.progress.verified_count( + completed: completedCount, total: totalCount), + style: UiTypography.body3r.copyWith( + color: UiColors.white.withValues(alpha: 0.7), ), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( children: [ const Icon( UiIcons.shield, - color: Color(0xFFF9E547), + color: UiColors.accent, size: 16, ), const SizedBox(width: 8), Text( t.staff_certificates.progress.active, - style: UiTypography.body3m.copyWith( // 12px Medium - color: const Color(0xFFF9E547), - ), + style: UiTypography.body3m.accent, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/pages/documents_page.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/pages/documents_page.dart index fb2e6526..28f95fcf 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/pages/documents_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/pages/documents_page.dart @@ -25,15 +25,14 @@ class DocumentsPage extends StatelessWidget { return Scaffold( appBar: AppBar( elevation: 0, + backgroundColor: UiColors.bgPopup, leading: IconButton( icon: const Icon(UiIcons.arrowLeft, color: UiColors.iconSecondary), onPressed: () => Modular.to.pop(), ), title: Text( t.staff_documents.title, - style: UiTypography.headline3m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline3m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), @@ -56,7 +55,7 @@ class DocumentsPage extends StatelessWidget { t.staff_documents.list.error( message: state.errorMessage ?? 'Unknown', ), - style: UiTypography.body1m.copyWith(color: UiColors.textError), + style: UiTypography.body1m.textError, ), ); } @@ -64,20 +63,23 @@ class DocumentsPage extends StatelessWidget { return Center( child: Text( t.staff_documents.list.empty, - style: UiTypography.body1m.copyWith(color: UiColors.textSecondary), + style: UiTypography.body1m.textSecondary, ), ); } return ListView( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + vertical: UiConstants.space6, + ), children: [ DocumentsProgressCard( completedCount: state.completedCount, totalCount: state.totalCount, progress: state.progress, ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), ...state.documents.map( (StaffDocument doc) => DocumentCard( document: doc, diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/document_card.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/document_card.dart index 764caa18..0331e566 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/document_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/document_card.dart @@ -1,7 +1,6 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:krow_domain/krow_domain.dart'; -import 'package:lucide_icons/lucide_icons.dart'; // ignore: depend_on_referenced_packages import 'package:core_localization/core_localization.dart'; @@ -18,11 +17,11 @@ class DocumentCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - margin: const EdgeInsets.only(bottom: 12), - padding: const EdgeInsets.all(16), + margin: const EdgeInsets.only(bottom: UiConstants.space3), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(8), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Row( @@ -32,7 +31,7 @@ class DocumentCard extends StatelessWidget { width: 40, height: 40, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: const Center( @@ -43,7 +42,7 @@ class DocumentCard extends StatelessWidget { ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -53,9 +52,7 @@ class DocumentCard extends StatelessWidget { children: [ Text( document.name, - style: UiTypography.body1m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body1m.textPrimary, ), _getStatusIcon(document.status), ], @@ -64,15 +61,13 @@ class DocumentCard extends StatelessWidget { if (document.description != null) Text( document.description!, - style: UiTypography.body2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body2r.textSecondary, ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Row( children: [ _buildStatusBadge(document.status), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildActionButton(document.status), ], ), @@ -114,27 +109,27 @@ class DocumentCard extends StatelessWidget { switch (status) { case DocumentStatus.verified: - bg = UiColors.textSuccess.withOpacity(0.2); + bg = UiColors.tagSuccess; text = UiColors.textSuccess; label = t.staff_documents.card.verified; break; case DocumentStatus.pending: - bg = UiColors.textWarning.withOpacity(0.2); + bg = UiColors.tagPending; text = UiColors.textWarning; label = t.staff_documents.card.pending; break; case DocumentStatus.missing: - bg = UiColors.textError.withOpacity(0.2); + bg = UiColors.textError.withValues(alpha: 0.1); text = UiColors.textError; label = t.staff_documents.card.missing; break; case DocumentStatus.rejected: - bg = UiColors.textError.withOpacity(0.2); + bg = UiColors.textError.withValues(alpha: 0.1); text = UiColors.textError; label = t.staff_documents.card.rejected; break; case DocumentStatus.expired: - bg = UiColors.textError.withOpacity(0.2); + bg = UiColors.textError.withValues(alpha: 0.1); text = UiColors.textError; label = t.staff_documents.card.rejected; // Or define "Expired" string break; @@ -165,7 +160,7 @@ class DocumentCard extends StatelessWidget { child: Row( children: [ Icon( - isVerified ? UiIcons.eye : LucideIcons.upload, + isVerified ? UiIcons.eye : UiIcons.upload, size: 16, color: UiColors.primary, ), @@ -174,9 +169,7 @@ class DocumentCard extends StatelessWidget { isVerified ? t.staff_documents.card.view : t.staff_documents.card.upload, - style: UiTypography.body3m.copyWith( - color: UiColors.primary, - ), + style: UiTypography.body3m.primary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/documents_progress_card.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/documents_progress_card.dart index 95395e08..50180fb6 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/documents_progress_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/presentation/widgets/documents_progress_card.dart @@ -24,10 +24,10 @@ class DocumentsProgressCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(8), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( @@ -37,16 +37,14 @@ class DocumentsProgressCard extends StatelessWidget { children: [ Text( t.staff_documents.verification_card.title, - style: UiTypography.body1m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body1m.textPrimary, ), Text( t.staff_documents.verification_card.progress( completed: completedCount, total: totalCount, ), - style: UiTypography.body2r.copyWith(color: UiColors.primary), + style: UiTypography.body2r.primary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_i9_page.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_i9_page.dart index fc513b7a..19affeb5 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_i9_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_i9_page.dart @@ -83,10 +83,13 @@ class _FormI9PageState extends State { if (state.status == FormI9Status.success) { // Success view is handled by state check in build or we can navigate } else if (state.status == FormI9Status.failure) { - final ScaffoldMessengerState messenger = ScaffoldMessenger.of(context); + final ScaffoldMessengerState messenger = + ScaffoldMessenger.of(context); messenger.hideCurrentSnackBar(); messenger.showSnackBar( - SnackBar(content: Text(state.errorMessage ?? 'An error occurred')), + SnackBar( + content: Text(state.errorMessage ?? 'An error occurred'), + ), ); } }, @@ -100,7 +103,10 @@ class _FormI9PageState extends State { _buildHeader(context, state), Expanded( child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + vertical: UiConstants.space6, + ), child: _buildCurrentStep(context, state), ), ), @@ -118,9 +124,9 @@ class _FormI9PageState extends State { backgroundColor: UiColors.background, body: Center( child: Padding( - padding: const EdgeInsets.all(24.0), + padding: const EdgeInsets.all(UiConstants.space6), child: Container( - padding: const EdgeInsets.all(32), + padding: const EdgeInsets.all(UiConstants.space8), decoration: BoxDecoration( color: UiColors.bgPopup, borderRadius: BorderRadius.circular(24), @@ -132,40 +138,40 @@ class _FormI9PageState extends State { Container( width: 64, height: 64, - decoration: const BoxDecoration( - color: Color(0xFFDCFCE7), + decoration: BoxDecoration( + color: UiColors.tagSuccess, shape: BoxShape.circle, ), child: const Icon( UiIcons.success, - color: Color(0xFF16A34A), + color: UiColors.textSuccess, size: 32, ), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( 'Form I-9 Submitted!', - style: UiTypography.headline4m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline4m.textPrimary, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( 'Your employment eligibility verification has been submitted.', textAlign: TextAlign.center, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () => Modular.to.pop(true), style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - foregroundColor: UiColors.bgPopup, - padding: const EdgeInsets.symmetric(vertical: 16), + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), elevation: 0, ), @@ -183,7 +189,12 @@ class _FormI9PageState extends State { Widget _buildHeader(BuildContext context, FormI9State state) { return Container( color: UiColors.primary, - padding: const EdgeInsets.only(top: 60, bottom: 24, left: 20, right: 20), + padding: const EdgeInsets.only( + top: 60, + bottom: UiConstants.space6, + left: UiConstants.space5, + right: UiConstants.space5, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -193,31 +204,34 @@ class _FormI9PageState extends State { onTap: () => Modular.to.pop(), child: const Icon( UiIcons.arrowLeft, - color: UiColors.bgPopup, + color: UiColors.white, size: 24, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Form I-9', - style: UiTypography.headline4m.copyWith( - color: UiColors.bgPopup, - ), + style: UiTypography.headline4m.white, ), Text( 'Employment Eligibility Verification', - style: UiTypography.body3r.copyWith(color: UiColors.bgPopup.withOpacity(0.7)), + style: UiTypography.body3r.copyWith( + color: UiColors.white.withValues(alpha: 0.7), + ), ), ], ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Row( - children: _steps.asMap().entries.map((MapEntry> entry) { + children: _steps + .asMap() + .entries + .map((MapEntry> entry) { final int idx = entry.key; final bool isLast = idx == _steps.length - 1; return Expanded( @@ -228,8 +242,8 @@ class _FormI9PageState extends State { height: 4, decoration: BoxDecoration( color: idx <= state.currentStep - ? UiColors.bgPopup - : UiColors.bgPopup.withOpacity(0.3), + ? UiColors.white + : UiColors.white.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(2), ), ), @@ -240,20 +254,21 @@ class _FormI9PageState extends State { ); }).toList(), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Step ${state.currentStep + 1} of ${_steps.length}', - style: UiTypography.body3r.copyWith(color: UiColors.bgPopup.withOpacity(0.7)), + style: UiTypography.body3r.copyWith( + color: UiColors.white.withValues(alpha: 0.7), + ), ), Expanded( child: Text( _steps[state.currentStep]['title']!, textAlign: TextAlign.end, - style: UiTypography.body3m.copyWith( - color: UiColors.bgPopup, + style: UiTypography.body3m.white.copyWith( fontWeight: FontWeight.w500, ), ), @@ -292,8 +307,7 @@ class _FormI9PageState extends State { children: [ Text( label, - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, + style: UiTypography.body3m.textSecondary.copyWith( fontWeight: FontWeight.w500, ), ), @@ -305,26 +319,26 @@ class _FormI9PageState extends State { ), onChanged: onChanged, keyboardType: keyboardType, - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, decoration: InputDecoration( hintText: placeholder, - hintStyle: TextStyle(color: Colors.grey[400]), + hintStyle: const TextStyle(color: UiColors.textPlaceholder), filled: true, fillColor: UiColors.bgPopup, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 16, + horizontal: UiConstants.space4, + vertical: UiConstants.space4, ), border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.primary), ), ), @@ -455,15 +469,15 @@ class _FormI9PageState extends State { children: [ Text( 'State *', - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, + style: UiTypography.body3m.textSecondary.copyWith( fontWeight: FontWeight.w500, ), ), const SizedBox(height: 6), DropdownButtonFormField( value: state.state.isEmpty ? null : state.state, - onChanged: (String? val) => context.read().stateChanged(val ?? ''), + onChanged: (String? val) => + context.read().stateChanged(val ?? ''), items: _usStates.map((String stateAbbr) { return DropdownMenuItem( value: stateAbbr, @@ -473,13 +487,15 @@ class _FormI9PageState extends State { decoration: InputDecoration( filled: true, fillColor: UiColors.bgPopup, - contentPadding: const EdgeInsets.symmetric(horizontal: 16), + contentPadding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + ), border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), ), @@ -507,9 +523,9 @@ class _FormI9PageState extends State { children: [ Text( 'I attest, under penalty of perjury, that I am (check one of the following boxes):', - style: UiTypography.body2m.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2m.textPrimary, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), _buildRadioOption( context, state, @@ -578,15 +594,21 @@ class _FormI9PageState extends State { ); } - Widget _buildRadioOption(BuildContext context, FormI9State state, String value, String label, {Widget? child}) { + Widget _buildRadioOption( + BuildContext context, + FormI9State state, + String value, + String label, { + Widget? child, + }) { final bool isSelected = state.citizenshipStatus == value; return GestureDetector( onTap: () => context.read().citizenshipStatusChanged(value), child: Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all( color: isSelected ? UiColors.primary : UiColors.border, width: isSelected ? 2 : 1, @@ -602,18 +624,16 @@ class _FormI9PageState extends State { decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( - color: isSelected ? UiColors.primary : Colors.grey, + color: isSelected ? UiColors.primary : UiColors.border, width: isSelected ? 6 : 2, ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Text( label, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), ), ], @@ -630,10 +650,10 @@ class _FormI9PageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( @@ -643,15 +663,21 @@ class _FormI9PageState extends State { 'Summary', style: UiTypography.headline4m.copyWith(fontSize: 14), ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), _buildSummaryRow('Name', '${state.firstName} ${state.lastName}'), _buildSummaryRow('Address', '${state.address}, ${state.city}'), - _buildSummaryRow('SSN', '***-**-${state.ssn.length >= 4 ? state.ssn.substring(state.ssn.length - 4) : '****'}'), - _buildSummaryRow('Citizenship', _getReadableCitizenship(state.citizenshipStatus)), + _buildSummaryRow( + 'SSN', + '***-**-${state.ssn.length >= 4 ? state.ssn.substring(state.ssn.length - 4) : '****'}', + ), + _buildSummaryRow( + 'Citizenship', + _getReadableCitizenship(state.citizenshipStatus), + ), ], ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), CheckboxListTile( value: state.preparerUsed, onChanged: (bool? val) { @@ -660,29 +686,27 @@ class _FormI9PageState extends State { contentPadding: EdgeInsets.zero, title: Text( 'I used a preparer or translator', - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, ), controlAffinity: ListTileControlAffinity.leading, activeColor: UiColors.primary, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.amber[50], - borderRadius: BorderRadius.circular(12), + color: UiColors.accent.withValues(alpha: 0.1), + borderRadius: UiConstants.radiusLg, ), - child: const Text( + child: Text( 'I am aware that federal law provides for imprisonment and/or fines for false statements or use of false documents in connection with the completion of this form.', - style: TextStyle(fontSize: 12, color: Color(0xFFB45309)), + style: UiTypography.body3r.textWarning.copyWith(fontSize: 12), ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( 'Signature (type your full name) *', - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3m.textSecondary, ), const SizedBox(height: 6), TextField( @@ -690,44 +714,46 @@ class _FormI9PageState extends State { ..selection = TextSelection.fromPosition( TextPosition(offset: state.signature.length), ), - onChanged: (String val) => context.read().signatureChanged(val), + onChanged: (String val) => + context.read().signatureChanged(val), decoration: InputDecoration( hintText: 'Type your full name', filled: true, fillColor: UiColors.bgPopup, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 16, + horizontal: UiConstants.space4, + vertical: UiConstants.space4, ), border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.primary), ), ), style: const TextStyle(fontFamily: 'Cursive', fontSize: 18), ), - const SizedBox(height: 16), - Text( + const SizedBox(height: UiConstants.space4), + Text( 'Date', - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3m.textSecondary, ), const SizedBox(height: 6), Container( width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space4, + ), decoration: BoxDecoration( - color: const Color(0xFFF3F4F6), - borderRadius: BorderRadius.circular(12), + color: UiColors.bgSecondary, + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Text( @@ -747,15 +773,13 @@ class _FormI9PageState extends State { children: [ Text( label, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), Expanded( child: Text( value, textAlign: TextAlign.end, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), ), ], @@ -780,7 +804,7 @@ class _FormI9PageState extends State { Widget _buildFooter(BuildContext context, FormI9State state) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: const BoxDecoration( color: UiColors.bgPopup, border: Border(top: BorderSide(color: UiColors.border)), @@ -791,24 +815,30 @@ class _FormI9PageState extends State { if (state.currentStep > 0) Expanded( child: Padding( - padding: const EdgeInsets.only(right: 12), + padding: const EdgeInsets.only(right: UiConstants.space3), child: OutlinedButton( onPressed: () => _handleBack(context), style: OutlinedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), side: const BorderSide(color: UiColors.border), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(UiIcons.arrowLeft, size: 16, color: UiColors.textPrimary), + const Icon( + UiIcons.arrowLeft, + size: 16, + color: UiColors.textPrimary, + ), const SizedBox(width: 8), Text( 'Back', - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, ), ], ), @@ -818,16 +848,20 @@ class _FormI9PageState extends State { Expanded( flex: 2, child: ElevatedButton( - onPressed: (_canProceed(state) && state.status != FormI9Status.submitting) + onPressed: ( + _canProceed(state) && + state.status != FormI9Status.submitting) ? () => _handleNext(context, state.currentStep) : null, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - disabledBackgroundColor: Colors.grey[300], - foregroundColor: UiColors.bgPopup, - padding: const EdgeInsets.symmetric(vertical: 16), + disabledBackgroundColor: UiColors.bgSecondary, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), elevation: 0, ), @@ -836,7 +870,7 @@ class _FormI9PageState extends State { width: 20, height: 20, child: CircularProgressIndicator( - color: UiColors.bgPopup, + color: UiColors.white, strokeWidth: 2, ), ) @@ -850,7 +884,7 @@ class _FormI9PageState extends State { ), if (state.currentStep < _steps.length - 1) ...[ const SizedBox(width: 8), - const Icon(UiIcons.arrowRight, size: 16, color: UiColors.bgPopup), + const Icon(UiIcons.arrowRight, size: 16, color: UiColors.white), ], ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_w4_page.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_w4_page.dart index 7d147b91..c8969568 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_w4_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/form_w4_page.dart @@ -146,7 +146,10 @@ class _FormW4PageState extends State { _buildHeader(context, state), Expanded( child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + vertical: UiConstants.space6, + ), child: _buildCurrentStep(context, state), ), ), @@ -164,9 +167,9 @@ class _FormW4PageState extends State { backgroundColor: UiColors.background, body: Center( child: Padding( - padding: const EdgeInsets.all(24.0), + padding: const EdgeInsets.all(UiConstants.space6), child: Container( - padding: const EdgeInsets.all(32), + padding: const EdgeInsets.all(UiConstants.space8), decoration: BoxDecoration( color: UiColors.bgPopup, borderRadius: BorderRadius.circular(24), @@ -178,40 +181,40 @@ class _FormW4PageState extends State { Container( width: 64, height: 64, - decoration: const BoxDecoration( - color: Color(0xFFDCFCE7), + decoration: BoxDecoration( + color: UiColors.tagSuccess, shape: BoxShape.circle, ), child: const Icon( UiIcons.success, - color: Color(0xFF16A34A), + color: UiColors.textSuccess, size: 32, ), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( 'Form W-4 Submitted!', - style: UiTypography.headline4m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline4m.textPrimary, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( 'Your withholding certificate has been submitted to your employer.', textAlign: TextAlign.center, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () => Modular.to.pop(true), style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - foregroundColor: UiColors.bgPopup, - padding: const EdgeInsets.symmetric(vertical: 16), + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), elevation: 0, ), @@ -229,7 +232,12 @@ class _FormW4PageState extends State { Widget _buildHeader(BuildContext context, FormW4State state) { return Container( color: UiColors.primary, - padding: const EdgeInsets.only(top: 60, bottom: 24, left: 20, right: 20), + padding: const EdgeInsets.only( + top: 60, + bottom: UiConstants.space6, + left: UiConstants.space5, + right: UiConstants.space5, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -239,31 +247,34 @@ class _FormW4PageState extends State { onTap: () => Modular.to.pop(), child: const Icon( UiIcons.arrowLeft, - color: UiColors.bgPopup, + color: UiColors.white, size: 24, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Form W-4', - style: UiTypography.headline4m.copyWith( - color: UiColors.bgPopup, - ), + style: UiTypography.headline4m.white, ), Text( 'Employee\'s Withholding Certificate', - style: UiTypography.body3r.copyWith(color: UiColors.bgPopup.withOpacity(0.7)), + style: UiTypography.body3r.copyWith( + color: UiColors.white.withValues(alpha: 0.7), + ), ), ], ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Row( - children: _steps.asMap().entries.map((MapEntry> entry) { + children: _steps + .asMap() + .entries + .map((MapEntry> entry) { final int idx = entry.key; final bool isLast = idx == _steps.length - 1; return Expanded( @@ -274,8 +285,8 @@ class _FormW4PageState extends State { height: 4, decoration: BoxDecoration( color: idx <= state.currentStep - ? UiColors.bgPopup - : UiColors.bgPopup.withOpacity(0.3), + ? UiColors.white + : UiColors.white.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(2), ), ), @@ -286,18 +297,19 @@ class _FormW4PageState extends State { ); }).toList(), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Step ${state.currentStep + 1} of ${_steps.length}', - style: UiTypography.body3r.copyWith(color: UiColors.bgPopup.withOpacity(0.7)), + style: UiTypography.body3r.copyWith( + color: UiColors.white.withValues(alpha: 0.7), + ), ), Text( _steps[state.currentStep]['title']!, - style: UiTypography.body3m.copyWith( - color: UiColors.bgPopup, + style: UiTypography.body3m.white.copyWith( fontWeight: FontWeight.w500, ), ), @@ -339,8 +351,7 @@ class _FormW4PageState extends State { children: [ Text( label, - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, + style: UiTypography.body3m.textSecondary.copyWith( fontWeight: FontWeight.w500, ), ), @@ -352,26 +363,26 @@ class _FormW4PageState extends State { ), onChanged: onChanged, keyboardType: keyboardType, - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, decoration: InputDecoration( hintText: placeholder, - hintStyle: TextStyle(color: Colors.grey[400]), + hintStyle: const TextStyle(color: UiColors.textPlaceholder), filled: true, fillColor: UiColors.bgPopup, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 16, + horizontal: UiConstants.space4, + vertical: UiConstants.space4, ), border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.primary), ), ), @@ -438,25 +449,25 @@ class _FormW4PageState extends State { return Column( children: [ Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.blue[50], - borderRadius: BorderRadius.circular(12), + color: UiColors.tagActive, + borderRadius: UiConstants.radiusLg, ), child: Row( - children: const [ - Icon(UiIcons.info, color: Color(0xFF2563EB), size: 20), - SizedBox(width: 12), + children: [ + const Icon(UiIcons.info, color: UiColors.primary, size: 20), + const SizedBox(width: UiConstants.space3), Expanded( child: Text( 'Your filing status determines your standard deduction and tax rates.', - style: TextStyle(fontSize: 14, color: Color(0xFF1D4ED8)), + style: UiTypography.body2r.textPrimary, ), ), ], ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), _buildRadioOption( context, state, @@ -484,15 +495,21 @@ class _FormW4PageState extends State { ); } - Widget _buildRadioOption(BuildContext context, FormW4State state, String value, String label, String? subLabel) { + Widget _buildRadioOption( + BuildContext context, + FormW4State state, + String value, + String label, + String? subLabel, + ) { final bool isSelected = state.filingStatus == value; return GestureDetector( onTap: () => context.read().filingStatusChanged(value), child: Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all( color: isSelected ? UiColors.primary : UiColors.border, width: isSelected ? 2 : 1, @@ -508,29 +525,25 @@ class _FormW4PageState extends State { decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( - color: isSelected ? UiColors.primary : Colors.grey, + color: isSelected ? UiColors.primary : UiColors.border, width: isSelected ? 6 : 2, ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), if (subLabel != null) ...[ const SizedBox(height: 4), Text( subLabel, - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ], @@ -546,36 +559,32 @@ class _FormW4PageState extends State { return Column( children: [ Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.amber[50], - borderRadius: BorderRadius.circular(12), + color: UiColors.accent.withValues(alpha: 0.1), + borderRadius: UiConstants.radiusLg, ), - child: const Row( + child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon( + const Icon( UiIcons.help, - color: Color(0xFFD97706), + color: UiColors.accent, size: 20, ), - SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'When to complete this step?', - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF92400E), - fontSize: 14, - ), + style: UiTypography.body2m.accent, ), - SizedBox(height: 4), + const SizedBox(height: 4), Text( 'Complete this step only if you hold more than one job at a time, or are married filing jointly and your spouse also works.', - style: TextStyle(fontSize: 12, color: Color(0xFFB45309)), + style: UiTypography.body3r.accent, ), ], ), @@ -583,18 +592,17 @@ class _FormW4PageState extends State { ], ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), GestureDetector( - onTap: () => context.read().multipleJobsChanged(!state.multipleJobs), + onTap: () => + context.read().multipleJobsChanged(!state.multipleJobs), child: Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all( - color: state.multipleJobs - ? UiColors.primary - : UiColors.border, + color: state.multipleJobs ? UiColors.primary : UiColors.border, ), ), child: Row( @@ -604,20 +612,16 @@ class _FormW4PageState extends State { width: 24, height: 24, decoration: BoxDecoration( - color: state.multipleJobs - ? UiColors.primary - : UiColors.bgPopup, + color: state.multipleJobs ? UiColors.primary : UiColors.bgPopup, borderRadius: BorderRadius.circular(6), border: Border.all( - color: state.multipleJobs - ? UiColors.primary - : Colors.grey, + color: state.multipleJobs ? UiColors.primary : UiColors.border, ), ), child: state.multipleJobs ? const Icon( UiIcons.check, - color: UiColors.bgPopup, + color: UiColors.white, size: 16, ) : null, @@ -629,16 +633,12 @@ class _FormW4PageState extends State { children: [ Text( 'I have multiple jobs or my spouse works', - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), const SizedBox(height: 4), Text( 'Check this box if there are only two jobs total', - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ), @@ -651,7 +651,7 @@ class _FormW4PageState extends State { Text( 'If this does not apply, you can continue to the next step', textAlign: TextAlign.center, - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ], ); @@ -661,30 +661,30 @@ class _FormW4PageState extends State { return Column( children: [ Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.blue[50], // Same note about blue migration - borderRadius: BorderRadius.circular(12), + color: UiColors.tagActive, + borderRadius: UiConstants.radiusLg, ), - child: const Row( + child: Row( children: [ - Icon(UiIcons.info, color: Color(0xFF2563EB), size: 20), - SizedBox(width: 12), + const Icon(UiIcons.info, color: UiColors.primary, size: 20), + const SizedBox(width: UiConstants.space3), Expanded( child: Text( 'If your total income will be \$200,000 or less (\$400,000 if married filing jointly), you may claim credits for dependents.', - style: TextStyle(fontSize: 14, color: Color(0xFF1D4ED8)), + style: UiTypography.body2r.textPrimary, ), ), ], ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(16), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( @@ -715,10 +715,10 @@ class _FormW4PageState extends State { if (_totalCredits(state) > 0) ...[ const SizedBox(height: 16), Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: const Color(0xFFDCFCE7), - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -770,16 +770,12 @@ class _FormW4PageState extends State { Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: const Color(0xFFDCFCE7), - borderRadius: BorderRadius.circular(12), + color: UiColors.tagSuccess, + borderRadius: UiConstants.radiusLg, ), child: Text( badge, - style: const TextStyle( - fontSize: 10, - color: Color(0xFF15803D), - fontWeight: FontWeight.bold, - ), + style: UiTypography.footnote2b.textSuccess, ), ), ], @@ -834,7 +830,7 @@ class _FormW4PageState extends State { children: [ Text( 'These adjustments are optional. You can skip them if they don\'t apply.', - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), const SizedBox(height: 24), _buildTextField( @@ -848,7 +844,7 @@ class _FormW4PageState extends State { padding: const EdgeInsets.only(top: 4, bottom: 16), child: Text( 'Include interest, dividends, retirement income', - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ), @@ -863,7 +859,7 @@ class _FormW4PageState extends State { padding: const EdgeInsets.only(top: 4, bottom: 16), child: Text( 'If you expect to claim deductions other than the standard deduction', - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ), @@ -878,7 +874,7 @@ class _FormW4PageState extends State { padding: const EdgeInsets.only(top: 4, bottom: 16), child: Text( 'Any additional tax you want withheld each pay period', - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body3r.textSecondary, ), ), ], @@ -890,10 +886,10 @@ class _FormW4PageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Column( @@ -927,22 +923,20 @@ class _FormW4PageState extends State { ), const SizedBox(height: 24), Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.amber[50], - borderRadius: BorderRadius.circular(12), + color: UiColors.accent.withValues(alpha: 0.1), + borderRadius: UiConstants.radiusLg, ), - child: const Text( + child: Text( 'Under penalties of perjury, I declare that this certificate, to the best of my knowledge and belief, is true, correct, and complete.', - style: TextStyle(fontSize: 12, color: Color(0xFFB45309)), + style: UiTypography.body3r.textWarning.copyWith(fontSize: 12), ), ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), Text( 'Signature (type your full name) *', - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3m.textSecondary, ), const SizedBox(height: 6), TextField( @@ -950,44 +944,46 @@ class _FormW4PageState extends State { ..selection = TextSelection.fromPosition( TextPosition(offset: state.signature.length), ), - onChanged: (String val) => context.read().signatureChanged(val), + onChanged: (String val) => + context.read().signatureChanged(val), decoration: InputDecoration( hintText: 'Type your full name', filled: true, fillColor: UiColors.bgPopup, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 16, + horizontal: UiConstants.space4, + vertical: UiConstants.space4, ), border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.border), ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, borderSide: const BorderSide(color: UiColors.primary), ), ), style: const TextStyle(fontFamily: 'Cursive', fontSize: 18), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( 'Date', - style: UiTypography.body3m.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3m.textSecondary, ), const SizedBox(height: 6), Container( width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space4, + ), decoration: BoxDecoration( - color: const Color(0xFFF3F4F6), - borderRadius: BorderRadius.circular(12), + color: UiColors.bgSecondary, + borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), ), child: Text( @@ -1007,7 +1003,7 @@ class _FormW4PageState extends State { children: [ Text( label, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), Text( value, @@ -1035,7 +1031,7 @@ class _FormW4PageState extends State { Widget _buildFooter(BuildContext context, FormW4State state) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: const BoxDecoration( color: UiColors.bgPopup, border: Border(top: BorderSide(color: UiColors.border)), @@ -1046,24 +1042,30 @@ class _FormW4PageState extends State { if (state.currentStep > 0) Expanded( child: Padding( - padding: const EdgeInsets.only(right: 12), + padding: const EdgeInsets.only(right: UiConstants.space3), child: OutlinedButton( onPressed: () => _handleBack(context), style: OutlinedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), side: const BorderSide(color: UiColors.border), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(UiIcons.arrowLeft, size: 16, color: UiColors.textPrimary), + const Icon( + UiIcons.arrowLeft, + size: 16, + color: UiColors.textPrimary, + ), const SizedBox(width: 8), Text( 'Back', - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, ), ], ), @@ -1073,16 +1075,20 @@ class _FormW4PageState extends State { Expanded( flex: 2, child: ElevatedButton( - onPressed: (_canProceed(state) && state.status != FormW4Status.submitting) + onPressed: ( + _canProceed(state) && + state.status != FormW4Status.submitting) ? () => _handleNext(context, state.currentStep) : null, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - disabledBackgroundColor: Colors.grey[300], - foregroundColor: UiColors.bgPopup, - padding: const EdgeInsets.symmetric(vertical: 16), + disabledBackgroundColor: UiColors.bgSecondary, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + borderRadius: UiConstants.radiusLg, ), elevation: 0, ), @@ -1091,7 +1097,7 @@ class _FormW4PageState extends State { width: 20, height: 20, child: CircularProgressIndicator( - color: UiColors.bgPopup, + color: UiColors.white, strokeWidth: 2, ), ) @@ -1105,7 +1111,7 @@ class _FormW4PageState extends State { ), if (state.currentStep < _steps.length - 1) ...[ const SizedBox(width: 8), - const Icon(UiIcons.arrowRight, size: 16, color: UiColors.bgPopup), + const Icon(UiIcons.arrowRight, size: 16, color: UiColors.white), ], ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/tax_forms_page.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/tax_forms_page.dart index 923e7f24..b6957ca6 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/tax_forms_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms/lib/src/presentation/pages/tax_forms_page.dart @@ -21,7 +21,7 @@ class TaxFormsPage extends StatelessWidget { ), title: Text( 'Tax Documents', - style: UiTypography.headline3m.copyWith(color: UiColors.bgPopup), + style: UiTypography.headline3m.textSecondary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(24), @@ -37,7 +37,7 @@ class TaxFormsPage extends StatelessWidget { child: Text( 'Complete required forms to start working', style: UiTypography.body3r.copyWith( - color: UiColors.bgPopup.withOpacity(0.8), + color: UiColors.primaryForeground.withValues(alpha: 0.8), ), ), ), @@ -111,15 +111,11 @@ class TaxFormsPage extends StatelessWidget { children: [ Text( 'Document Progress', - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), Text( '$completedCount/$totalCount', - style: UiTypography.body2m.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body2m.textSecondary, ), ], ), @@ -171,7 +167,7 @@ class TaxFormsPage extends StatelessWidget { width: 48, height: 48, decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), borderRadius: UiConstants.radiusLg, ), child: Center(child: Text(icon, style: UiTypography.headline1m)), @@ -186,9 +182,7 @@ class TaxFormsPage extends StatelessWidget { children: [ Text( form.title, - style: UiTypography.headline4m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline4m.textPrimary, ), _buildStatusBadge(form.status), ], @@ -196,17 +190,14 @@ class TaxFormsPage extends StatelessWidget { const SizedBox(height: UiConstants.space1), Text( form.subtitle ?? '', - style: UiTypography.body2m.copyWith( + style: UiTypography.body2m.textSecondary.copyWith( fontWeight: FontWeight.w500, - color: UiColors.textSecondary, ), ), const SizedBox(height: UiConstants.space1), Text( form.description ?? '', - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ), @@ -247,9 +238,7 @@ class TaxFormsPage extends StatelessWidget { const SizedBox(width: UiConstants.space1), Text( 'Completed', - style: UiTypography.footnote2b.copyWith( - color: UiColors.textSuccess, - ), + style: UiTypography.footnote2b.textSuccess, ), ], ), @@ -271,9 +260,7 @@ class TaxFormsPage extends StatelessWidget { const SizedBox(width: UiConstants.space1), Text( 'In Progress', - style: UiTypography.footnote2b.copyWith( - color: UiColors.textWarning, - ), + style: UiTypography.footnote2b.textWarning, ), ], ), @@ -290,9 +277,7 @@ class TaxFormsPage extends StatelessWidget { ), child: Text( 'Not Started', - style: UiTypography.footnote2b.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote2b.textSecondary, ), ); } @@ -316,16 +301,12 @@ class TaxFormsPage extends StatelessWidget { children: [ Text( 'Why are these needed?', - style: UiTypography.headline4m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline4m.textPrimary, ), const SizedBox(height: UiConstants.space1), Text( 'I-9 and W-4 forms are required by federal law to verify your employment eligibility and set up correct tax withholding.', - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/pages/bank_account_page.dart b/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/pages/bank_account_page.dart index ffa8e21f..210e7502 100644 --- a/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/pages/bank_account_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/pages/bank_account_page.dart @@ -37,7 +37,7 @@ class BankAccountPage extends StatelessWidget { ), title: Text( strings.title, - style: UiTypography.headline3m.copyWith(color: UiColors.textPrimary), + style: UiTypography.headline3m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), @@ -143,7 +143,7 @@ class BankAccountPage extends StatelessWidget { return Container( padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.08), + color: UiColors.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Row( @@ -157,15 +157,12 @@ class BankAccountPage extends StatelessWidget { children: [ Text( strings.secure_title, - style: UiTypography.body2r.copyWith( // Was body2 - fontWeight: FontWeight.w500, - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), const SizedBox(height: 2), Text( strings.secure_subtitle, - style: UiTypography.body3r.copyWith(color: UiColors.textSecondary), // Was bodySmall + style: UiTypography.body3r.textSecondary, ), ], ), @@ -199,7 +196,7 @@ class BankAccountPage extends StatelessWidget { width: 48, height: 48, decoration: BoxDecoration( - color: primaryColor.withOpacity(0.1), + color: primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: const Center( @@ -216,10 +213,7 @@ class BankAccountPage extends StatelessWidget { children: [ Text( account.bankName, - style: UiTypography.body2r.copyWith( // Was body2 - fontWeight: FontWeight.w500, - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), Text( strings.account_ending( @@ -227,9 +221,7 @@ class BankAccountPage extends StatelessWidget { ? account.last4! : '----', ), - style: UiTypography.body2r.copyWith( // Was body2 - color: UiColors.textSecondary, - ), + style: UiTypography.body2r.textSecondary, ), ], ), @@ -239,7 +231,7 @@ class BankAccountPage extends StatelessWidget { Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: primaryColor.withOpacity(0.15), + color: primaryColor.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(20), ), child: Row( @@ -248,10 +240,7 @@ class BankAccountPage extends StatelessWidget { const SizedBox(width: 4), Text( strings.primary, - style: UiTypography.body3r.copyWith( // Was bodySmall - fontWeight: FontWeight.w500, - color: primaryColor, - ), + style: UiTypography.body3m.primary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/widgets/add_account_form.dart b/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/widgets/add_account_form.dart index a7ad00c9..4858511d 100644 --- a/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/widgets/add_account_form.dart +++ b/apps/mobile/packages/features/staff/profile_sections/finances/staff_bank_account/lib/src/presentation/widgets/add_account_form.dart @@ -43,7 +43,7 @@ class _AddAccountFormState extends State { children: [ Text( widget.strings.add_new_account, - style: UiTypography.headline4m.copyWith(color: UiColors.textPrimary), // Was header4 + style: UiTypography.headline4m.textPrimary, // Was header4 ), const SizedBox(height: UiConstants.space4), UiTextField( @@ -71,8 +71,7 @@ class _AddAccountFormState extends State { padding: const EdgeInsets.only(bottom: UiConstants.space2), child: Text( widget.strings.account_type, - style: UiTypography.body2r.copyWith( // Was body2 - color: UiColors.textSecondary, fontWeight: FontWeight.w500), + style: UiTypography.body2m.textSecondary, ), ), Row( @@ -122,7 +121,7 @@ class _AddAccountFormState extends State { padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: isSelected - ? UiColors.primary.withOpacity(0.05) + ? UiColors.primary.withValues(alpha: 0.05) : UiColors.bgPopup, // Was surface borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( @@ -133,8 +132,7 @@ class _AddAccountFormState extends State { child: Center( child: Text( label, - style: UiTypography.body2r.copyWith( // Was body2 - fontWeight: FontWeight.w600, + style: UiTypography.body2b.copyWith( color: isSelected ? UiColors.primary : UiColors.textSecondary, ), ), diff --git a/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/pages/time_card_page.dart b/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/pages/time_card_page.dart index 6805e7fa..02b670c4 100644 --- a/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/pages/time_card_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/pages/time_card_page.dart @@ -40,9 +40,7 @@ class _TimeCardPageState extends State { ), title: Text( t.staff_time_card.title, - style: UiTypography.headline4m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline4m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), diff --git a/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/widgets/timesheet_card.dart b/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/widgets/timesheet_card.dart index 4e8d7351..70f707e2 100644 --- a/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/widgets/timesheet_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/finances/time_card/lib/src/presentation/widgets/timesheet_card.dart @@ -19,22 +19,22 @@ class TimesheetCard extends StatelessWidget { switch (status) { case TimeCardStatus.approved: - statusBg = UiColors.textSuccess.withOpacity(0.12); + statusBg = UiColors.tagSuccess; statusColor = UiColors.textSuccess; statusText = t.staff_time_card.status.approved; break; case TimeCardStatus.disputed: - statusBg = UiColors.destructive.withOpacity(0.12); + statusBg = UiColors.destructive.withValues(alpha: 0.12); statusColor = UiColors.destructive; statusText = t.staff_time_card.status.disputed; break; case TimeCardStatus.paid: - statusBg = UiColors.primary.withOpacity(0.12); + statusBg = UiColors.primary.withValues(alpha: 0.12); statusColor = UiColors.primary; statusText = t.staff_time_card.status.paid; break; case TimeCardStatus.pending: - statusBg = UiColors.textWarning.withOpacity(0.12); + statusBg = UiColors.tagPending; statusColor = UiColors.textWarning; statusText = t.staff_time_card.status.pending; break; @@ -61,15 +61,11 @@ class TimesheetCard extends StatelessWidget { children: [ Text( timesheet.shiftTitle, - style: UiTypography.body1m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body1m.textPrimary, ), Text( timesheet.clientName, - style: UiTypography.body2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body2r.textSecondary, ), ], ), @@ -116,13 +112,11 @@ class TimesheetCard extends StatelessWidget { children: [ Text( '${timesheet.totalHours.toStringAsFixed(1)} ${t.staff_time_card.hours} @ \$${timesheet.hourlyRate.toStringAsFixed(2)}${t.staff_time_card.per_hr}', - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), Text( '\$${timesheet.totalPay.toStringAsFixed(2)}', - style: UiTypography.title2b.copyWith( - color: UiColors.primary, - ), + style: UiTypography.title2b.primary, ), ], ), @@ -163,7 +157,7 @@ class _IconText extends StatelessWidget { const SizedBox(width: UiConstants.space1), Text( text, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), ], ); diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_page.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_page.dart index 776f5f77..44cde53f 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_page.dart @@ -32,9 +32,7 @@ class AttirePage extends StatelessWidget { ), title: Text( t.staff_profile_attire.title, - style: UiTypography.headline3m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline3m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_info_card.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_info_card.dart index 656d1626..92606c1c 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_info_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_info_card.dart @@ -11,8 +11,8 @@ class AttireInfoCard extends StatelessWidget { return Container( padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.08), - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + color: UiColors.primary.withValues(alpha: 0.08), + borderRadius: UiConstants.radiusLg, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -26,16 +26,12 @@ class AttireInfoCard extends StatelessWidget { children: [ Text( t.staff_profile_attire.info_card.title, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, ), const SizedBox(height: 2), Text( t.staff_profile_attire.info_card.description, - style: UiTypography.body2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body2r.textSecondary, ), ], ), diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/pages/emergency_contact_screen.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/pages/emergency_contact_screen.dart index 3e3637cd..652ff125 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/pages/emergency_contact_screen.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/pages/emergency_contact_screen.dart @@ -23,12 +23,12 @@ class EmergencyContactScreen extends StatelessWidget { appBar: AppBar( elevation: 0, leading: IconButton( - icon: Icon(UiIcons.chevronLeft, color: UiColors.textSecondary), + icon: const Icon(UiIcons.chevronLeft, color: UiColors.textSecondary), onPressed: () => Modular.to.pop(), ), title: Text( 'Emergency Contact', - style: UiTypography.title1m.copyWith(color: UiColors.textPrimary), + style: UiTypography.title1m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), @@ -53,11 +53,11 @@ class EmergencyContactScreen extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - padding: EdgeInsets.all(UiConstants.space6), + padding: const EdgeInsets.all(UiConstants.space6), child: Column( children: [ const EmergencyContactInfoBanner(), - SizedBox(height: UiConstants.space6), + const SizedBox(height: UiConstants.space6), ...state.contacts.asMap().entries.map( (entry) => EmergencyContactFormItem( index: entry.key, @@ -66,7 +66,7 @@ class EmergencyContactScreen extends StatelessWidget { ), ), const EmergencyContactAddButton(), - SizedBox(height: UiConstants.space16), + const SizedBox(height: UiConstants.space16), ], ), ), diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_add_button.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_add_button.dart index 40f9b81e..769c709b 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_add_button.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_add_button.dart @@ -12,20 +12,20 @@ class EmergencyContactAddButton extends StatelessWidget { child: TextButton.icon( onPressed: () => context.read().add(EmergencyContactAdded()), - icon: Icon(UiIcons.add, size: 20.0), + icon: const Icon(UiIcons.add, size: 20.0), label: Text( 'Add Another Contact', style: UiTypography.title2b, ), style: TextButton.styleFrom( foregroundColor: UiColors.primary, - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: UiConstants.space6, vertical: UiConstants.space3, ), shape: RoundedRectangleBorder( borderRadius: UiConstants.radiusFull, - side: BorderSide(color: UiColors.primary), + side: const BorderSide(color: UiColors.primary), ), ), ), diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_form_item.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_form_item.dart index 8dbf2063..4117a5d3 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_form_item.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_form_item.dart @@ -19,8 +19,8 @@ class EmergencyContactFormItem extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.only(bottom: UiConstants.space4), - padding: EdgeInsets.all(UiConstants.space4), + margin: const EdgeInsets.only(bottom: UiConstants.space4), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( color: UiColors.bgPopup, borderRadius: UiConstants.radiusLg, @@ -30,33 +30,27 @@ class EmergencyContactFormItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(context), - SizedBox(height: UiConstants.space4), + const SizedBox(height: UiConstants.space4), _buildLabel('Full Name'), _buildTextField( initialValue: contact.name, hint: 'Contact name', icon: UiIcons.user, onChanged: (val) => context.read().add( - EmergencyContactUpdated( - index, - contact.copyWith(name: val), - ), - ), + EmergencyContactUpdated(index, contact.copyWith(name: val)), + ), ), - SizedBox(height: UiConstants.space4), + const SizedBox(height: UiConstants.space4), _buildLabel('Phone Number'), _buildTextField( initialValue: contact.phone, hint: '+1 (555) 000-0000', icon: UiIcons.phone, onChanged: (val) => context.read().add( - EmergencyContactUpdated( - index, - contact.copyWith(phone: val), - ), - ), + EmergencyContactUpdated(index, contact.copyWith(phone: val)), + ), ), - SizedBox(height: UiConstants.space4), + const SizedBox(height: UiConstants.space4), _buildLabel('Relationship'), _buildDropdown( context, @@ -65,11 +59,11 @@ class EmergencyContactFormItem extends StatelessWidget { onChanged: (val) { if (val != null) { context.read().add( - EmergencyContactUpdated( - index, - contact.copyWith(relationship: val), - ), - ); + EmergencyContactUpdated( + index, + contact.copyWith(relationship: val), + ), + ); } }, ), @@ -85,7 +79,7 @@ class EmergencyContactFormItem extends StatelessWidget { required ValueChanged onChanged, }) { return Container( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: UiConstants.space4, vertical: UiConstants.space2, ), @@ -99,13 +93,13 @@ class EmergencyContactFormItem extends StatelessWidget { value: value, isExpanded: true, dropdownColor: UiColors.bgPopup, - icon: Icon(UiIcons.chevronDown, color: UiColors.iconSecondary), + icon: const Icon(UiIcons.chevronDown, color: UiColors.iconSecondary), items: items.map((type) { return DropdownMenuItem( value: type, child: Text( _formatRelationship(type), - style: UiTypography.body1r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body1r.textPrimary, ), ); }).toList(), @@ -116,11 +110,15 @@ class EmergencyContactFormItem extends StatelessWidget { } String _formatRelationship(RelationshipType type) { - switch(type) { - case RelationshipType.family: return 'Family'; - case RelationshipType.spouse: return 'Spouse'; - case RelationshipType.friend: return 'Friend'; - case RelationshipType.other: return 'Other'; + switch (type) { + case RelationshipType.family: + return 'Family'; + case RelationshipType.spouse: + return 'Spouse'; + case RelationshipType.friend: + return 'Friend'; + case RelationshipType.other: + return 'Other'; } } @@ -128,22 +126,17 @@ class EmergencyContactFormItem extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - 'Contact ${index + 1}', - style: UiTypography.title2m.copyWith( - color: UiColors.textPrimary, - ), - ), + Text('Contact ${index + 1}', style: UiTypography.title2m.textPrimary), if (totalContacts > 1) IconButton( - icon: Icon( + icon: const Icon( UiIcons.delete, color: UiColors.textError, size: 20.0, ), - onPressed: () => context - .read() - .add(EmergencyContactRemoved(index)), + onPressed: () => context.read().add( + EmergencyContactRemoved(index), + ), ), ], ); @@ -151,13 +144,8 @@ class EmergencyContactFormItem extends StatelessWidget { Widget _buildLabel(String label) { return Padding( - padding: EdgeInsets.only(bottom: UiConstants.space2), - child: Text( - label, - style: UiTypography.body2m.copyWith( - color: UiColors.textSecondary, - ), - ), + padding: const EdgeInsets.only(bottom: UiConstants.space2), + child: Text(label, style: UiTypography.body2m.textSecondary), ); } @@ -169,16 +157,16 @@ class EmergencyContactFormItem extends StatelessWidget { }) { return TextFormField( initialValue: initialValue, - style: UiTypography.body1r.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body1r.textPrimary, decoration: InputDecoration( hintText: hint, - hintStyle: TextStyle(color: UiColors.textPlaceholder), + hintStyle: const TextStyle(color: UiColors.textPlaceholder), prefixIcon: Icon(icon, color: UiColors.textSecondary, size: 20.0), filled: true, fillColor: UiColors.bgPopup, - contentPadding: EdgeInsets.symmetric(vertical: UiConstants.space4), + contentPadding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + ), border: OutlineInputBorder( borderRadius: UiConstants.radiusLg, borderSide: BorderSide(color: UiColors.border), @@ -196,4 +184,3 @@ class EmergencyContactFormItem extends StatelessWidget { ); } } - diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_info_banner.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_info_banner.dart index 975529be..e8d26179 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_info_banner.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_info_banner.dart @@ -7,14 +7,14 @@ class EmergencyContactInfoBanner extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.all(UiConstants.space4), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: UiColors.accent.withOpacity(0.2), - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + color: UiColors.accent.withValues(alpha: 0.2), + borderRadius: UiConstants.radiusLg, ), child: Text( 'Please provide at least one emergency contact. This information will only be used in case of an emergency during your shifts.', - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, ), ); } diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_save_button.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_save_button.dart index e21e94f2..5f219cad 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_save_button.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/emergency_contact/lib/src/presentation/widgets/emergency_contact_save_button.dart @@ -30,19 +30,18 @@ class EmergencyContactSaveButton extends StatelessWidget { builder: (context, state) { final isLoading = state.status == EmergencyContactStatus.saving; return Container( - padding: EdgeInsets.all(UiConstants.space4), - decoration: BoxDecoration( + padding: const EdgeInsets.all(UiConstants.space4), + decoration: const BoxDecoration( color: UiColors.bgPopup, border: Border(top: BorderSide(color: UiColors.border)), ), child: SafeArea( child: UiButton.primary( fullWidth: true, - onPressed: state.isValid && !isLoading - ? () => _onSave(context) - : null, + onPressed: + state.isValid && !isLoading ? () => _onSave(context) : null, child: isLoading - ? SizedBox( + ? const SizedBox( height: 20.0, width: 20.0, child: CircularProgressIndicator( diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/experience/lib/src/presentation/pages/experience_page.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/experience/lib/src/presentation/pages/experience_page.dart index 65e19d44..cd3cada5 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/experience/lib/src/presentation/pages/experience_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/experience/lib/src/presentation/pages/experience_page.dart @@ -73,16 +73,16 @@ class ExperiencePage extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - padding: EdgeInsets.all(UiConstants.space5), + padding: const EdgeInsets.all(UiConstants.space5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExperienceSectionTitle(title: i18n.industries_title), Text( i18n.industries_subtitle, - style: UiTypography.body2m.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2m.textSecondary, ), - SizedBox(height: UiConstants.space3), + const SizedBox(height: UiConstants.space3), Wrap( spacing: UiConstants.space2, runSpacing: UiConstants.space2, @@ -90,23 +90,26 @@ class ExperiencePage extends StatelessWidget { .map( (i) => UiChip( label: _getIndustryLabel(i18n.industries, i), - isSelected: state.selectedIndustries.contains(i), - onTap: () => BlocProvider.of(context) - .add(ExperienceIndustryToggled(i)), - variant: state.selectedIndustries.contains(i) - ? UiChipVariant.primary - : UiChipVariant.secondary, + isSelected: + state.selectedIndustries.contains(i), + onTap: () => + BlocProvider.of(context) + .add(ExperienceIndustryToggled(i)), + variant: + state.selectedIndustries.contains(i) + ? UiChipVariant.primary + : UiChipVariant.secondary, ), ) .toList(), ), - SizedBox(height: UiConstants.space6), + const SizedBox(height: UiConstants.space6), ExperienceSectionTitle(title: i18n.skills_title), Text( i18n.skills_subtitle, - style: UiTypography.body2m.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2m.textSecondary, ), - SizedBox(height: UiConstants.space3), + const SizedBox(height: UiConstants.space3), Wrap( spacing: UiConstants.space2, runSpacing: UiConstants.space2, @@ -114,19 +117,22 @@ class ExperiencePage extends StatelessWidget { .map( (s) => UiChip( label: _getSkillLabel(i18n.skills, s), - isSelected: state.selectedSkills.contains(s.value), - onTap: () => BlocProvider.of(context) - .add(ExperienceSkillToggled(s.value)), - variant: state.selectedSkills.contains(s.value) - ? UiChipVariant.primary - : UiChipVariant.secondary, + isSelected: + state.selectedSkills.contains(s.value), + onTap: () => + BlocProvider.of(context) + .add(ExperienceSkillToggled(s.value)), + variant: + state.selectedSkills.contains(s.value) + ? UiChipVariant.primary + : UiChipVariant.secondary, ), ) .toList(), ), ], ), - ), + ), ), _buildSaveButton(context, state, i18n), ], @@ -148,9 +154,9 @@ class ExperiencePage extends StatelessWidget { children: [ Text( i18n.custom_skills_title, - style: UiTypography.body2m.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2m.textSecondary, ), - SizedBox(height: UiConstants.space2), + const SizedBox(height: UiConstants.space2), Wrap( spacing: UiConstants.space2, runSpacing: UiConstants.space2, @@ -165,10 +171,14 @@ class ExperiencePage extends StatelessWidget { ); } - Widget _buildSaveButton(BuildContext context, ExperienceState state, dynamic i18n) { + Widget _buildSaveButton( + BuildContext context, + ExperienceState state, + dynamic i18n, + ) { return Container( - padding: EdgeInsets.all(UiConstants.space4), - decoration: BoxDecoration( + padding: const EdgeInsets.all(UiConstants.space4), + decoration: const BoxDecoration( color: UiColors.bgPopup, border: Border(top: BorderSide(color: UiColors.border)), ), @@ -176,16 +186,21 @@ class ExperiencePage extends StatelessWidget { child: UiButton.primary( onPressed: state.status == ExperienceStatus.loading ? null - : () => BlocProvider.of(context).add(ExperienceSubmitted()), + : () => BlocProvider.of(context) + .add(ExperienceSubmitted()), fullWidth: true, - text: state.status == ExperienceStatus.loading ? null : i18n.save_button, + text: state.status == ExperienceStatus.loading + ? null + : i18n.save_button, child: state.status == ExperienceStatus.loading - ? SizedBox( + ? const SizedBox( height: 20.0, width: 20.0, child: CircularProgressIndicator( strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(UiColors.white), // UiColors.primaryForeground is white mostly + valueColor: AlwaysStoppedAnimation( + UiColors.white, + ), // UiColors.primaryForeground is white mostly ), ) : null, diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/pages/personal_info_page.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/pages/personal_info_page.dart index 50fae0a9..c28e3593 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/pages/personal_info_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/pages/personal_info_page.dart @@ -1,4 +1,3 @@ - import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; @@ -52,13 +51,16 @@ class PersonalInfoPage extends StatelessWidget { backgroundColor: UiColors.bgPopup, elevation: 0, leading: IconButton( - icon: const Icon(UiIcons.chevronLeft, color: UiColors.textSecondary), + icon: const Icon( + UiIcons.chevronLeft, + color: UiColors.textSecondary, + ), onPressed: () => Modular.to.pop(), tooltip: MaterialLocalizations.of(context).backButtonTooltip, ), title: Text( i18n.title, - style: UiTypography.title1m.copyWith(color: UiColors.textPrimary), + style: UiTypography.title1m.textPrimary, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), @@ -82,9 +84,7 @@ class PersonalInfoPage extends StatelessWidget { return Center( child: Text( 'Failed to load personal information', - style: UiTypography.body1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body1r.textSecondary, ), ); } diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/personal_info_form.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/personal_info_form.dart index ee4e84b5..6ae1fc46 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/personal_info_form.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/personal_info_form.dart @@ -93,7 +93,7 @@ class _FieldLabel extends StatelessWidget { Widget build(BuildContext context) { return Text( text, - style: UiTypography.body2m.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2m.textPrimary, ); } } @@ -101,7 +101,6 @@ class _FieldLabel extends StatelessWidget { /// A read-only field widget for displaying non-editable information. /// A read-only field widget for displaying non-editable information. class _ReadOnlyField extends StatelessWidget { - const _ReadOnlyField({required this.value}); final String value; @@ -120,7 +119,7 @@ class _ReadOnlyField extends StatelessWidget { ), child: Text( value, - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, ), ); } @@ -129,7 +128,6 @@ class _ReadOnlyField extends StatelessWidget { /// An editable text field widget. /// An editable text field widget. class _EditableField extends StatelessWidget { - const _EditableField({ required this.controller, required this.hint, @@ -150,10 +148,10 @@ class _EditableField extends StatelessWidget { enabled: enabled, keyboardType: keyboardType, autofillHints: autofillHints, - style: UiTypography.body2r.copyWith(color: UiColors.textPrimary), + style: UiTypography.body2r.textPrimary, decoration: InputDecoration( hintText: hint, - hintStyle: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + hintStyle: UiTypography.body2r.textSecondary, contentPadding: const EdgeInsets.symmetric( horizontal: UiConstants.space3, vertical: UiConstants.space3, diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/profile_photo_widget.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/profile_photo_widget.dart index dc681266..0abb3513 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/profile_photo_widget.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/presentation/widgets/profile_photo_widget.dart @@ -28,7 +28,8 @@ class ProfilePhotoWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final TranslationsStaffOnboardingPersonalInfoEn i18n = t.staff.onboarding.personal_info; + final TranslationsStaffOnboardingPersonalInfoEn i18n = + t.staff.onboarding.personal_info; return Column( children: [ @@ -41,7 +42,7 @@ class ProfilePhotoWidget extends StatelessWidget { height: 96, decoration: BoxDecoration( shape: BoxShape.circle, - color: UiColors.primary.withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), ), child: photoUrl != null ? ClipOval( @@ -53,9 +54,7 @@ class ProfilePhotoWidget extends StatelessWidget { : Center( child: Text( fullName.isNotEmpty ? fullName[0].toUpperCase() : '?', - style: UiTypography.displayL.copyWith( - color: UiColors.primary, - ), + style: UiTypography.displayL.primary, ), ), ), @@ -71,7 +70,7 @@ class ProfilePhotoWidget extends StatelessWidget { border: Border.all(color: UiColors.border), boxShadow: [ BoxShadow( - color: UiColors.textPrimary.withOpacity(0.1), + color: UiColors.textPrimary.withValues(alpha: 0.1), blurRadius: UiConstants.space1, offset: const Offset(0, 2), ), @@ -92,7 +91,7 @@ class ProfilePhotoWidget extends StatelessWidget { const SizedBox(height: UiConstants.space3), Text( i18n.change_photo_hint, - style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), + style: UiTypography.body2r.textSecondary, ), ], ); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart index 3a8f22c9..1b04a87c 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart @@ -64,10 +64,10 @@ class _ShiftDetailsPageState extends State { Widget _buildStatCard(IconData icon, String value, String label) { return Container( - padding: const EdgeInsets.symmetric(vertical: 16), + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), decoration: BoxDecoration( - color: const Color(0xFFF8FAFC), - borderRadius: BorderRadius.circular(16), + color: UiColors.background, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all(color: UiColors.border), ), child: Column( @@ -76,21 +76,19 @@ class _ShiftDetailsPageState extends State { width: 40, height: 40, decoration: const BoxDecoration( - color: Colors.white, + color: UiColors.white, shape: BoxShape.circle, ), child: Icon(icon, size: 20, color: UiColors.iconSecondary), ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Text( value, - style: UiTypography.title1m.copyWith(color: UiColors.textPrimary), + style: UiTypography.title1m.textPrimary, ), Text( label, - style: UiTypography.footnote2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote2r.textSecondary, ), ], ), @@ -99,29 +97,21 @@ class _ShiftDetailsPageState extends State { Widget _buildTimeBox(String label, String time) { return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: const Color(0xFFF8FAFC), - borderRadius: BorderRadius.circular(16), + color: UiColors.background, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Column( children: [ Text( label, - style: const TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: UiColors.textSecondary, - letterSpacing: 0.5, - ), + style: UiTypography.titleUppercase4b.textSecondary, ), - const SizedBox(height: 4), + const SizedBox(height: UiConstants.space1), Text( _formatTime(time), - style: UiTypography.display2m.copyWith( - fontSize: 20, - color: UiColors.textPrimary, - ), + style: UiTypography.headline2m.textPrimary, ), ], ), @@ -149,7 +139,7 @@ class _ShiftDetailsPageState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(state.message), - backgroundColor: UiColors.tagSuccess, + backgroundColor: UiColors.success, ), ); Modular.to.toShifts(selectedDate: state.shiftDate); @@ -158,7 +148,7 @@ class _ShiftDetailsPageState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(state.message), - backgroundColor: const Color(0xFFEF4444), + backgroundColor: UiColors.destructive, ), ); } @@ -203,7 +193,7 @@ class _ShiftDetailsPageState extends State { children: [ Expanded( child: SingleChildScrollView( - padding: const EdgeInsets.all(20.0), + padding: const EdgeInsets.all(UiConstants.space5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -211,16 +201,11 @@ class _ShiftDetailsPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( "VENDOR", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: UiColors.textSecondary, - letterSpacing: 0.5, - ), + style: UiTypography.titleUppercase4b.textSecondary, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( children: [ SizedBox( @@ -229,7 +214,7 @@ class _ShiftDetailsPageState extends State { child: displayShift.logoUrl != null ? ClipRRect( borderRadius: BorderRadius.circular( - 6, + UiConstants.radiusMdValue, ), child: Image.network( displayShift.logoUrl!, @@ -244,33 +229,26 @@ class _ShiftDetailsPageState extends State { ), ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( displayShift.clientName, - style: UiTypography.headline5m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline5m.textPrimary, ), ], ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), // Date Section Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( "SHIFT DATE", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: UiColors.textSecondary, - letterSpacing: 0.5, - ), + style: UiTypography.titleUppercase4b.textSecondary, ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( children: [ const Icon( @@ -278,104 +256,44 @@ class _ShiftDetailsPageState extends State { size: 20, color: UiColors.primary, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( _formatDate(displayShift.date), - style: UiTypography.headline5m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.headline5m.textPrimary, ), ], ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), // Worker Capacity / Open Slots if ((displayShift.requiredSlots ?? 0) > 0) Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: const Color(0xFFF0FDF4), // green-50 - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: const Color(0xFFBBF7D0), - ), // green-200 + color: UiColors.success.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: Row( children: [ const Icon( - Icons.people_alt_outlined, - size: 20, - color: Color(0xFF15803D), - ), // green-700, using Material Icon as generic fallback - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - "$openSlots spots remaining", - style: UiTypography.body2b.copyWith( - color: const Color(0xFF15803D), - ), - ), - Text( - "${displayShift.filledSlots ?? 0} filled out of ${displayShift.requiredSlots}", - style: UiTypography.body3r.copyWith( - color: const Color(0xFF166534), - ), - ), - ], - ), + UiIcons.users, + size: 16, + color: UiColors.success, ), - SizedBox( - width: 60, - child: LinearProgressIndicator( - value: (displayShift.requiredSlots! > 0) - ? (displayShift.filledSlots ?? 0) / - displayShift.requiredSlots! - : 0, - backgroundColor: Colors.white, - color: const Color(0xFF15803D), - minHeight: 6, - borderRadius: BorderRadius.circular(3), - ), + const SizedBox(width: UiConstants.space2), + Text( + "$openSlots slots remaining", + style: UiTypography.footnote1m.textSuccess, ), ], ), ), - const SizedBox(height: 24), - // Stats Grid - GridView.count( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - crossAxisCount: 3, - crossAxisSpacing: 12, - childAspectRatio: 0.85, - children: [ - _buildStatCard( - UiIcons.dollar, - "\$${estimatedTotal.toStringAsFixed(0)}", - "Total Pay", - ), - _buildStatCard( - UiIcons.dollar, - "\$${displayShift.hourlyRate.toInt()}", - "Per Hour", - ), - _buildStatCard( - UiIcons.clock, - "${duration.toInt()}h", - "Duration", - ), - ], - ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), - // Shift Timing + // Time Section Row( children: [ Expanded( @@ -384,7 +302,7 @@ class _ShiftDetailsPageState extends State { displayShift.startTime, ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space4), Expanded( child: _buildTimeBox( "END TIME", @@ -393,129 +311,142 @@ class _ShiftDetailsPageState extends State { ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space6), - // Location - Column( - crossAxisAlignment: CrossAxisAlignment.start, + // Quick Info Grid + Row( children: [ - const Text( - "LOCATION", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: UiColors.textSecondary, - letterSpacing: 0.5, + Expanded( + child: _buildStatCard( + UiIcons.dollar, + "\$${displayShift.hourlyRate.toStringAsFixed(0)}/hr", + "Base Rate", ), ), - const SizedBox(height: 8), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - displayShift.location.isEmpty - ? "TBD" - : displayShift.location, - style: UiTypography.title1m.copyWith( - color: UiColors.textPrimary, - ), - ), - Text( - displayShift.location.isEmpty - ? "TBD" - : displayShift.locationAddress, - style: UiTypography.title1m.copyWith( - color: UiColors.textPrimary, - ), - ), - ], + const SizedBox(width: UiConstants.space4), + Expanded( + child: _buildStatCard( + UiIcons.clock, + "${duration.toInt()} hours", + "Duration", + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: _buildStatCard( + UiIcons.wallet, + "\$${estimatedTotal.toStringAsFixed(0)}", + "Est. Total", + ), ), ], ), - const SizedBox(height: 24), + const SizedBox(height: UiConstants.space8), - // Additional Info - if (displayShift.description != null) ...[ - SizedBox( - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - "ADDITIONAL INFO", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: UiColors.textSecondary, - letterSpacing: 0.5, - ), - ), - const SizedBox(height: 8), - Text( - displayShift.description!, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), - ), - ], + // Location Section + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "LOCATION", + style: UiTypography.titleUppercase4b.textSecondary, ), - ), - ], - const SizedBox(height: 20), - if (displayShift.status != 'confirmed' && - displayShift.hasApplied != true && - (displayShift.requiredSlots == null || - displayShift.filledSlots == null || - displayShift.filledSlots! < - displayShift.requiredSlots!)) - Row( - children: [ - Expanded( - child: OutlinedButton( - onPressed: () => _declineShift( - context, - displayShift!.id, - ), - style: OutlinedButton.styleFrom( - foregroundColor: const Color(0xFFEF4444), - side: const BorderSide( - color: Color(0xFFEF4444), - ), - padding: const EdgeInsets.symmetric( - vertical: 16, - ), - ), - child: const Text("Decline"), - ), + const SizedBox(height: UiConstants.space3), + Container( + padding: const EdgeInsets.all(UiConstants.space4), + decoration: BoxDecoration( + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + border: Border.all(color: UiColors.border), ), - const SizedBox(width: 16), - Expanded( - child: ElevatedButton( - onPressed: () => _bookShift( - context, - displayShift!, + child: Column( + children: [ + Row( + children: [ + const Icon( + UiIcons.mapPin, + color: UiColors.primary, + size: 20, + ), + const SizedBox(width: UiConstants.space3), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + displayShift.location, + style: UiTypography.body2b.textPrimary, + ), + Text( + displayShift.locationAddress, + style: UiTypography.body3r.textSecondary, + ), + ], + ), + ), + ], ), - style: ElevatedButton.styleFrom( - backgroundColor: const Color( - 0xFF10B981, + const SizedBox(height: UiConstants.space4), + const Divider(), + const SizedBox(height: UiConstants.space2), + TextButton.icon( + onPressed: () {}, + icon: const Icon( + UiIcons.arrowRight, + size: 16, ), - foregroundColor: Colors.white, - padding: const EdgeInsets.symmetric( - vertical: 16, + label: const Text("Open in Maps"), + style: TextButton.styleFrom( + foregroundColor: UiColors.primary, + padding: EdgeInsets.zero, ), ), - child: const Text("Book Shift"), - ), + ], ), - ], - ), - SizedBox( - height: MediaQuery.of(context).padding.bottom + 10, + ), + ], ), + const SizedBox(height: UiConstants.space8), + + // Description / Instructions + if ((displayShift.description ?? '').isNotEmpty) ...[ + Text( + "JOB DESCRIPTION", + style: UiTypography.titleUppercase4b.textSecondary, + ), + const SizedBox(height: UiConstants.space2), + Text( + displayShift.description!, + style: UiTypography.body2r.textSecondary, + ), + const SizedBox(height: UiConstants.space8), + ], ], ), ), ), + // Bottom Action Bar + Container( + padding: EdgeInsets.fromLTRB( + UiConstants.space5, + UiConstants.space4, + UiConstants.space5, + MediaQuery.of(context).padding.bottom + UiConstants.space4, + ), + decoration: BoxDecoration( + color: UiColors.white, + border: Border(top: BorderSide(color: UiColors.border)), + boxShadow: [ + BoxShadow( + color: UiColors.black.withValues(alpha: 0.05), + blurRadius: 10, + offset: const Offset(0, -4), + ), + ], + ), + child: _buildBottomButton(displayShift, context), + ), ], ), ); @@ -552,7 +483,7 @@ class _ShiftDetailsPageState extends State { ); }, style: TextButton.styleFrom( - foregroundColor: const Color(0xFF10B981), + foregroundColor: UiColors.success, ), child: const Text('Book'), ), @@ -581,7 +512,7 @@ class _ShiftDetailsPageState extends State { ).add(DeclineShiftDetailsEvent(id)); }, style: TextButton.styleFrom( - foregroundColor: const Color(0xFFEF4444), + foregroundColor: UiColors.destructive, ), child: const Text('Decline'), ), @@ -608,29 +539,23 @@ class _ShiftDetailsPageState extends State { width: 36, child: CircularProgressIndicator(), ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), Text( shift.title, - style: UiTypography.body2b.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2b.textPrimary, textAlign: TextAlign.center, ), const SizedBox(height: 6), Text( '${_formatDate(shift.date)} • ${_formatTime(shift.startTime)} - ${_formatTime(shift.endTime)}', - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, textAlign: TextAlign.center, ), if (shift.clientName.isNotEmpty) ...[ const SizedBox(height: 6), Text( shift.clientName, - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, textAlign: TextAlign.center, ), ], @@ -647,4 +572,150 @@ class _ShiftDetailsPageState extends State { Navigator.of(context, rootNavigator: true).pop(); _actionDialogOpen = false; } + + Widget _buildBottomButton(Shift shift, BuildContext context) { + final String status = shift.status ?? 'open'; + + if (status == 'confirmed') { + return Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: () => _openCancelDialog(context), + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.destructive, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + elevation: 0, + ), + child: Text("CANCEL SHIFT", style: UiTypography.body2b.white), + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: ElevatedButton( + onPressed: () => Modular.to.toClockIn(), + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.success, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + elevation: 0, + ), + child: Text("CLOCK IN", style: UiTypography.body2b.white), + ), + ), + ], + ); + } + + if (status == 'pending') { + return Row( + children: [ + Expanded( + child: OutlinedButton( + onPressed: () => BlocProvider.of(context).add(DeclineShiftDetailsEvent(shift.id)), + style: OutlinedButton.styleFrom( + foregroundColor: UiColors.destructive, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + side: const BorderSide(color: UiColors.destructive), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + ), + child: Text("DECLINE", style: UiTypography.body2b.textError), + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: ElevatedButton( + onPressed: () => BlocProvider.of(context).add(BookShiftDetailsEvent(shift.id, roleId: shift.roleId)), + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + elevation: 0, + ), + child: Text("ACCEPT SHIFT", style: UiTypography.body2b.white), + ), + ), + ], + ); + } + + if (status == 'open' || status == 'available') { + return Row( + children: [ + Expanded( + child: OutlinedButton( + onPressed: () => _declineShift(context, shift.id), + style: OutlinedButton.styleFrom( + foregroundColor: UiColors.textSecondary, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + side: const BorderSide(color: UiColors.border), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + ), + child: Text("DECLINE", style: UiTypography.body2b.textSecondary), + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: ElevatedButton( + onPressed: () => _bookShift(context, shift), + style: ElevatedButton.styleFrom( + backgroundColor: UiColors.primary, + foregroundColor: UiColors.white, + padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + ), + elevation: 0, + ), + child: Text("APPLY NOW", style: UiTypography.body2b.white), + ), + ), + ], + ); + } + + return const SizedBox(); + } + + void _openCancelDialog(BuildContext context) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: const Text('Cancel Shift'), + content: const Text('Are you sure you want to cancel this shift?'), + actions: [ + TextButton( + onPressed: () => Modular.to.pop(), + child: const Text('No'), + ), + TextButton( + onPressed: () { + Modular.to.pop(); + BlocProvider.of(context).add( + DeclineShiftDetailsEvent(widget.shiftId), + ); + }, + style: TextButton.styleFrom( + foregroundColor: UiColors.destructive, + ), + child: const Text('Yes, cancel it'), + ), + ], + ), + ); + } } diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart index 3d86039d..9f4caa2e 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart @@ -7,7 +7,6 @@ import '../blocs/shifts/shifts_bloc.dart'; import '../widgets/tabs/my_shifts_tab.dart'; import '../widgets/tabs/find_shifts_tab.dart'; import '../widgets/tabs/history_shifts_tab.dart'; -import '../styles/shifts_styles.dart'; class ShiftsPage extends StatefulWidget { final String? initialTab; @@ -107,29 +106,25 @@ class _ShiftsPageState extends State { // Note: Calendar logic moved to MyShiftsTab return Scaffold( - backgroundColor: AppColors.krowBackground, + backgroundColor: UiColors.background, body: Column( children: [ // Header (Blue) Container( - color: AppColors.krowBlue, + color: UiColors.primary, padding: EdgeInsets.fromLTRB( - 20, - MediaQuery.of(context).padding.top + 10, - 20, - 20, + UiConstants.space5, + MediaQuery.of(context).padding.top + UiConstants.space2, + UiConstants.space5, + UiConstants.space5, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - spacing: 16, + spacing: UiConstants.space4, children: [ - const Text( + Text( "Shifts", - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white, - ), + style: UiTypography.display1b.white, ), // Tabs @@ -143,17 +138,16 @@ class _ShiftsPageState extends State { showCount: myShiftsLoaded, enabled: !blockTabsForFind, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildTab( "find", "Find Shifts", UiIcons.search, - availableJobs - .length, // Passed unfiltered count as badge? Or logic inside? Pass availableJobs. + availableJobs.length, showCount: availableLoaded, enabled: baseLoaded, ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildTab( "history", "History", @@ -245,12 +239,15 @@ class _ShiftsPageState extends State { } }, child: Container( - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8), + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space2, + horizontal: UiConstants.space2, + ), decoration: BoxDecoration( color: isActive - ? Colors.white - : Colors.white.withAlpha((0.2 * 255).round()), - borderRadius: BorderRadius.circular(8), + ? UiColors.white + : UiColors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -260,23 +257,17 @@ class _ShiftsPageState extends State { icon, size: 14, color: !enabled - ? Colors.white.withAlpha((0.5 * 255).round()) + ? UiColors.white.withValues(alpha: 0.5) : isActive - ? AppColors.krowBlue - : Colors.white, + ? UiColors.primary + : UiColors.white, ), - const SizedBox(width: 6), + const SizedBox(width: UiConstants.space1), Flexible( child: Text( label, - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: !enabled - ? Colors.white.withAlpha((0.5 * 255).round()) - : isActive - ? AppColors.krowBlue - : Colors.white, + style: (isActive ? UiTypography.body3m.copyWith(color: UiColors.primary) : UiTypography.body3m.white).copyWith( + color: !enabled ? UiColors.white.withValues(alpha: 0.5) : null, ), overflow: TextOverflow.ellipsis, ), @@ -285,23 +276,21 @@ class _ShiftsPageState extends State { const SizedBox(width: 4), Container( padding: const EdgeInsets.symmetric( - horizontal: 6, + horizontal: UiConstants.space1, vertical: 2, ), constraints: const BoxConstraints(minWidth: 18), decoration: BoxDecoration( color: isActive - ? AppColors.krowBlue.withAlpha((0.1 * 255).round()) - : Colors.white.withAlpha((0.2 * 255).round()), - borderRadius: BorderRadius.circular(999), + ? UiColors.primary.withValues(alpha: 0.1) + : UiColors.white.withValues(alpha: 0.2), + borderRadius: UiConstants.radiusFull, ), child: Center( child: Text( "$count", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: isActive ? AppColors.krowBlue : Colors.white, + style: UiTypography.footnote1b.copyWith( + color: isActive ? UiColors.primary : UiColors.white, ), ), ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart index 2b07e2a0..9ca03298 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart @@ -118,14 +118,14 @@ class _MyShiftCardState extends State { Modular.to.pushShiftDetails(widget.shift); }, child: Container( - margin: const EdgeInsets.only(bottom: 12), + margin: const EdgeInsets.only(bottom: UiConstants.space3), decoration: BoxDecoration( - color: Colors.white, + color: UiColors.white, borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -142,7 +142,7 @@ class _MyShiftCardState extends State { // Status Badge if (statusText.isNotEmpty) Padding( - padding: const EdgeInsets.only(bottom: 8), + padding: const EdgeInsets.only(bottom: UiConstants.space2), child: Row( children: [ if (statusIcon != null) @@ -173,14 +173,14 @@ class _MyShiftCardState extends State { ), // Shift Type Badge for available/pending shifts if (status == 'open' || status == 'pending') ...[ - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2, ), decoration: BoxDecoration( - color: UiColors.primary.withOpacity(0.1), + color: UiColors.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(4), ), child: Text( @@ -205,20 +205,20 @@ class _MyShiftCardState extends State { decoration: BoxDecoration( gradient: LinearGradient( colors: [ - UiColors.primary.withOpacity(0.09), - UiColors.primary.withOpacity(0.03), + UiColors.primary.withValues(alpha: 0.09), + UiColors.primary.withValues(alpha: 0.03), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( - color: UiColors.primary.withOpacity(0.09), + color: UiColors.primary.withValues(alpha: 0.09), ), ), child: widget.shift.logoUrl != null ? ClipRRect( - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), child: Image.network( widget.shift.logoUrl!, fit: BoxFit.contain, @@ -232,7 +232,7 @@ class _MyShiftCardState extends State { ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), // Details Expanded( @@ -249,42 +249,34 @@ class _MyShiftCardState extends State { children: [ Text( widget.shift.title, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, overflow: TextOverflow.ellipsis, ), Text( widget.shift.clientName, - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, overflow: TextOverflow.ellipsis, ), ], ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( "\$${estimatedTotal.toStringAsFixed(0)}", - style: UiTypography.title1m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.title1m.textPrimary, ), Text( "\$${widget.shift.hourlyRate.toInt()}/hr · ${duration.toInt()}h", - style: UiTypography.footnote2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote2r.textSecondary, ), ], ), ], ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), // Date & Time - Multi-Day or Single Day if (widget.shift.durationDays != null && @@ -332,11 +324,9 @@ class _MyShiftCardState extends State { const SizedBox(width: 4), Text( _formatDate(widget.shift.date), - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), const Icon( UiIcons.clock, size: 12, @@ -345,9 +335,7 @@ class _MyShiftCardState extends State { const SizedBox(width: 4), Text( "${_formatTime(widget.shift.startTime)} - ${_formatTime(widget.shift.endTime)}", - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, ), ], ), @@ -368,9 +356,7 @@ class _MyShiftCardState extends State { widget.shift.locationAddress.isNotEmpty ? widget.shift.locationAddress : widget.shift.location, - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, overflow: TextOverflow.ellipsis, ), ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_assignment_card.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_assignment_card.dart index d46eb14a..086571e2 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_assignment_card.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_assignment_card.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:krow_domain/krow_domain.dart'; import 'package:design_system/design_system.dart'; -import 'package:core_localization/core_localization.dart'; class ShiftAssignmentCard extends StatelessWidget { final Shift shift; @@ -66,12 +65,12 @@ class ShiftAssignmentCard extends StatelessWidget { return Container( decoration: BoxDecoration( - color: Colors.white, + color: UiColors.white, borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: UiColors.black.withValues(alpha: 0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -81,7 +80,7 @@ class ShiftAssignmentCard extends StatelessWidget { children: [ // Header Padding( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -97,20 +96,20 @@ class ShiftAssignmentCard extends StatelessWidget { decoration: BoxDecoration( gradient: LinearGradient( colors: [ - UiColors.primary.withOpacity(0.09), - UiColors.primary.withOpacity(0.03), + UiColors.primary.withValues(alpha: 0.09), + UiColors.primary.withValues(alpha: 0.03), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( - color: UiColors.primary.withOpacity(0.09), + color: UiColors.primary.withValues(alpha: 0.09), ), ), child: shift.logoUrl != null ? ClipRRect( - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), child: Image.network( shift.logoUrl!, fit: BoxFit.contain, @@ -124,7 +123,7 @@ class ShiftAssignmentCard extends StatelessWidget { ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), // Details Expanded( @@ -140,42 +139,34 @@ class ShiftAssignmentCard extends StatelessWidget { children: [ Text( shift.title, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.textPrimary, overflow: TextOverflow.ellipsis, ), Text( shift.clientName, - style: UiTypography.body3r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.body3r.textSecondary, overflow: TextOverflow.ellipsis, ), ], ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( "\$${totalPay.toStringAsFixed(0)}", - style: UiTypography.title1m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.title1m.textPrimary, ), Text( "\$${shift.hourlyRate.toInt()}/hr · ${hours.toInt()}h", - style: UiTypography.footnote2r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote2r.textSecondary, ), ], ), ], ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), // Date & Time Row( @@ -188,11 +179,9 @@ class ShiftAssignmentCard extends StatelessWidget { const SizedBox(width: 4), Text( _formatDate(shift.date), - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), const Icon( UiIcons.clock, size: 12, @@ -201,9 +190,7 @@ class ShiftAssignmentCard extends StatelessWidget { const SizedBox(width: 4), Text( "${_formatTime(shift.startTime)} - ${_formatTime(shift.endTime)}", - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, ), ], ), @@ -223,9 +210,7 @@ class ShiftAssignmentCard extends StatelessWidget { shift.locationAddress.isNotEmpty ? shift.locationAddress : shift.location, - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), + style: UiTypography.footnote1r.textSecondary, overflow: TextOverflow.ellipsis, ), ), @@ -240,38 +225,55 @@ class ShiftAssignmentCard extends StatelessWidget { ), ), - Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + // Actions + Container( + padding: const EdgeInsets.all(UiConstants.space2), + decoration: const BoxDecoration( + color: UiColors.secondary, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(UiConstants.radiusBase), + bottomRight: Radius.circular(UiConstants.radiusBase), + ), + ), child: Row( children: [ Expanded( - child: OutlinedButton( + child: TextButton( onPressed: onDecline, - style: OutlinedButton.styleFrom( - foregroundColor: UiColors.iconSecondary, - side: const BorderSide(color: UiColors.border), - padding: const EdgeInsets.symmetric(vertical: 14), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + style: TextButton.styleFrom( + foregroundColor: UiColors.destructive, + ), + child: Text( + "Decline", // Fallback if translation is broken + style: UiTypography.body2m.textError, ), - child: Text(t.staff_shifts.action.decline), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space2), Expanded( child: ElevatedButton( - onPressed: onConfirm, + onPressed: isConfirming ? null : onConfirm, style: ElevatedButton.styleFrom( backgroundColor: UiColors.primary, - foregroundColor: Colors.white, + foregroundColor: UiColors.white, elevation: 0, - padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(UiConstants.radiusMdValue), ), ), - child: Text(t.staff_shifts.action.confirm), + child: isConfirming + ? const SizedBox( + height: 16, + width: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + color: UiColors.white, + ), + ) + : Text( + "Accept", // Fallback + style: UiTypography.body2m.white, + ), ), ), ], diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart index 1b75a48c..6422c312 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart @@ -2,7 +2,6 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:krow_domain/krow_domain.dart'; -import '../../styles/shifts_styles.dart'; import '../my_shift_card.dart'; import '../shared/empty_state_view.dart'; @@ -27,22 +26,21 @@ class _FindShiftsTabState extends State { return GestureDetector( onTap: () => setState(() => _jobType = id), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space4, + vertical: UiConstants.space2, + ), decoration: BoxDecoration( - color: isSelected ? AppColors.krowBlue : Colors.white, - borderRadius: BorderRadius.circular(999), + color: isSelected ? UiColors.primary : UiColors.white, + borderRadius: UiConstants.radiusFull, border: Border.all( - color: isSelected ? AppColors.krowBlue : const Color(0xFFE2E8F0), + color: isSelected ? UiColors.primary : UiColors.border, ), ), child: Text( label, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: isSelected ? Colors.white : const Color(0xFF64748B), - ), + style: (isSelected ? UiTypography.footnote2m.white : UiTypography.footnote2m.textSecondary), ), ), ); @@ -73,8 +71,11 @@ class _FindShiftsTabState extends State { children: [ // Search and Filters Container( - color: Colors.white, - padding: const EdgeInsets.fromLTRB(20, 16, 20, 16), + color: UiColors.white, + padding: const EdgeInsets.symmetric( + horizontal: UiConstants.space5, + vertical: UiConstants.space4, + ), child: Column( children: [ // Search Bar @@ -83,12 +84,12 @@ class _FindShiftsTabState extends State { Expanded( child: Container( height: 48, - padding: const EdgeInsets.symmetric(horizontal: 12), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space3), decoration: BoxDecoration( - color: const Color(0xFFF8FAFC), - borderRadius: BorderRadius.circular(12), + color: UiColors.background, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( - color: const Color(0xFFE2E8F0), + color: UiColors.border, ), ), child: Row( @@ -96,20 +97,17 @@ class _FindShiftsTabState extends State { const Icon( UiIcons.search, size: 20, - color: Color(0xFF94A3B8), + color: UiColors.textInactive, ), - const SizedBox(width: 10), + const SizedBox(width: UiConstants.space2), Expanded( child: TextField( onChanged: (v) => setState(() => _searchQuery = v), - decoration: const InputDecoration( + decoration: InputDecoration( border: InputBorder.none, hintText: "Search jobs, location...", - hintStyle: TextStyle( - color: Color(0xFF94A3B8), - fontSize: 14, - ), + hintStyle: UiTypography.body2r.textPlaceholder, ), ), ), @@ -117,37 +115,37 @@ class _FindShiftsTabState extends State { ), ), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Container( height: 48, width: 48, decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( - color: const Color(0xFFE2E8F0), + color: UiColors.border, ), ), child: const Icon( UiIcons.filter, size: 18, - color: Color(0xFF64748B), + color: UiColors.textSecondary, ), ), ], ), - const SizedBox(height: 16), + const SizedBox(height: UiConstants.space4), // Filter Tabs SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ _buildFilterTab('all', 'All Jobs'), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildFilterTab('one-day', 'One Day'), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildFilterTab('multi-day', 'Multi-Day'), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), _buildFilterTab('long-term', 'Long Term'), ], ), @@ -158,19 +156,19 @@ class _FindShiftsTabState extends State { Expanded( child: filteredJobs.isEmpty - ? EmptyStateView( + ? const EmptyStateView( icon: UiIcons.search, title: "No jobs available", subtitle: "Check back later", ) : SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), child: Column( children: [ - const SizedBox(height: 20), + const SizedBox(height: UiConstants.space5), ...filteredJobs.map( (shift) => Padding( - padding: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.only(bottom: UiConstants.space3), child: MyShiftCard( shift: shift, ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/history_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/history_shifts_tab.dart index 75f78284..6b325194 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/history_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/history_shifts_tab.dart @@ -17,7 +17,7 @@ class HistoryShiftsTab extends StatelessWidget { @override Widget build(BuildContext context) { if (historyShifts.isEmpty) { - return EmptyStateView( + return const EmptyStateView( icon: UiIcons.clock, title: "No shift history", subtitle: "Completed shifts appear here", @@ -25,13 +25,13 @@ class HistoryShiftsTab extends StatelessWidget { } return SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), child: Column( children: [ - const SizedBox(height: 20), + const SizedBox(height: UiConstants.space5), ...historyShifts.map( (shift) => Padding( - padding: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.only(bottom: UiConstants.space3), child: GestureDetector( onTap: () => Modular.to.pushShiftDetails(shift), child: MyShiftCard( diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/my_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/my_shifts_tab.dart index d2aecd1f..f184df7c 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/my_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/my_shifts_tab.dart @@ -1,14 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; -import 'package:lucide_icons/lucide_icons.dart'; import 'package:design_system/design_system.dart'; import 'package:krow_domain/krow_domain.dart'; import '../../blocs/shifts/shifts_bloc.dart'; import '../my_shift_card.dart'; import '../shift_assignment_card.dart'; import '../shared/empty_state_view.dart'; -import '../../styles/shifts_styles.dart'; class MyShiftsTab extends StatefulWidget { final List myShifts; @@ -118,14 +116,14 @@ class _MyShiftsTabState extends State { Navigator.of(context).pop(); context.read().add(AcceptShiftEvent(id)); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Shift confirmed!'), - backgroundColor: Color(0xFF10B981), + SnackBar( + content: const Text('Shift confirmed!'), + backgroundColor: UiColors.success, ), ); }, style: TextButton.styleFrom( - foregroundColor: const Color(0xFF10B981), + foregroundColor: UiColors.success, ), child: const Text('Accept'), ), @@ -152,14 +150,14 @@ class _MyShiftsTabState extends State { Navigator.of(context).pop(); context.read().add(DeclineShiftEvent(id)); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Shift declined.'), - backgroundColor: Color(0xFFEF4444), + SnackBar( + content: const Text('Shift declined.'), + backgroundColor: UiColors.destructive, ), ); }, style: TextButton.styleFrom( - foregroundColor: const Color(0xFFEF4444), + foregroundColor: UiColors.destructive, ), child: const Text('Decline'), ), @@ -212,12 +210,15 @@ class _MyShiftsTabState extends State { children: [ // Calendar Selector Container( - color: Colors.white, - padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16), + color: UiColors.white, + padding: const EdgeInsets.symmetric( + vertical: UiConstants.space4, + horizontal: UiConstants.space4, + ), child: Column( children: [ Padding( - padding: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.only(bottom: UiConstants.space3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -225,7 +226,7 @@ class _MyShiftsTabState extends State { icon: const Icon( UiIcons.chevronLeft, size: 20, - color: AppColors.krowCharcoal, + color: UiColors.textPrimary, ), onPressed: () => setState(() { _weekOffset--; @@ -237,17 +238,13 @@ class _MyShiftsTabState extends State { ), Text( DateFormat('MMMM yyyy').format(weekStartDate), - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: AppColors.krowCharcoal, - ), + style: UiTypography.title1m.textPrimary, ), IconButton( icon: const Icon( UiIcons.chevronRight, size: 20, - color: AppColors.krowCharcoal, + color: UiColors.textPrimary, ), onPressed: () => setState(() { _weekOffset++; @@ -284,13 +281,13 @@ class _MyShiftsTabState extends State { height: 60, decoration: BoxDecoration( color: isSelected - ? AppColors.krowBlue - : Colors.white, - borderRadius: BorderRadius.circular(12), + ? UiColors.primary + : UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase), border: Border.all( color: isSelected - ? AppColors.krowBlue - : AppColors.krowBorder, + ? UiColors.primary + : UiColors.border, width: 1, ), ), @@ -299,31 +296,25 @@ class _MyShiftsTabState extends State { children: [ Text( date.day.toString().padLeft(2, '0'), - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: isSelected - ? Colors.white - : AppColors.krowCharcoal, - ), + style: isSelected + ? UiTypography.body1b.white + : UiTypography.body1b.textPrimary, ), Text( DateFormat('E').format(date), - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w500, - color: isSelected - ? Colors.white.withOpacity(0.8) - : AppColors.krowMuted, + style: (isSelected + ? UiTypography.footnote2m.white + : UiTypography.footnote2m.textSecondary).copyWith( + color: isSelected ? UiColors.white.withValues(alpha: 0.8) : null, ), ), if (hasShifts && !isSelected) Container( - margin: const EdgeInsets.only(top: 4), + margin: const EdgeInsets.only(top: UiConstants.space1), width: 4, height: 4, decoration: const BoxDecoration( - color: AppColors.krowBlue, + color: UiColors.primary, shape: BoxShape.circle, ), ), @@ -338,22 +329,22 @@ class _MyShiftsTabState extends State { ], ), ), - const Divider(height: 1, color: AppColors.krowBorder), + const Divider(height: 1, color: UiColors.border), Expanded( child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), child: Column( children: [ - const SizedBox(height: 20), + const SizedBox(height: UiConstants.space5), if (widget.pendingAssignments.isNotEmpty) ...[ _buildSectionHeader( "Awaiting Confirmation", - const Color(0xFFF59E0B), + UiColors.textWarning, ), ...widget.pendingAssignments.map( (shift) => Padding( - padding: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.only(bottom: UiConstants.space4), child: ShiftAssignmentCard( shift: shift, onConfirm: () => _confirmShift(shift.id), @@ -362,14 +353,14 @@ class _MyShiftsTabState extends State { ), ), ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), ], if (visibleCancelledShifts.isNotEmpty) ...[ - _buildSectionHeader("Cancelled Shifts", AppColors.krowMuted), + _buildSectionHeader("Cancelled Shifts", UiColors.textSecondary), ...visibleCancelledShifts.map( (shift) => Padding( - padding: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.only(bottom: UiConstants.space4), child: _buildCancelledCard( title: shift.title, client: shift.clientName, @@ -383,15 +374,15 @@ class _MyShiftsTabState extends State { ), ), ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), ], // Confirmed Shifts if (visibleMyShifts.isNotEmpty) ...[ - _buildSectionHeader("Confirmed Shifts", AppColors.krowMuted), + _buildSectionHeader("Confirmed Shifts", UiColors.textSecondary), ...visibleMyShifts.map( (shift) => Padding( - padding: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.only(bottom: UiConstants.space3), child: MyShiftCard(shift: shift), ), ), @@ -417,7 +408,7 @@ class _MyShiftsTabState extends State { Widget _buildSectionHeader(String title, Color dotColor) { return Padding( - padding: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.only(bottom: UiConstants.space4), child: Row( children: [ Container( @@ -425,16 +416,12 @@ class _MyShiftsTabState extends State { height: 8, decoration: BoxDecoration(color: dotColor, shape: BoxShape.circle), ), - const SizedBox(width: 8), + const SizedBox(width: UiConstants.space2), Text( title, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: dotColor == AppColors.krowMuted - ? AppColors.krowMuted - : dotColor, - ), + style: (dotColor == UiColors.textSecondary + ? UiTypography.body2b.textSecondary + : UiTypography.body2b.copyWith(color: dotColor)), ), ], ), @@ -455,11 +442,11 @@ class _MyShiftsTabState extends State { return GestureDetector( onTap: onTap, child: Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.all(UiConstants.space4), decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - border: Border.all(color: AppColors.krowBorder), + color: UiColors.white, + borderRadius: BorderRadius.circular(UiConstants.radiusBase + 4), + border: Border.all(color: UiColors.border), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -470,33 +457,25 @@ class _MyShiftsTabState extends State { width: 6, height: 6, decoration: const BoxDecoration( - color: Color(0xFFEF4444), + color: UiColors.destructive, shape: BoxShape.circle, ), ), const SizedBox(width: 6), - const Text( + Text( "CANCELLED", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.bold, - color: Color(0xFFEF4444), - ), + style: UiTypography.footnote2b.textError, ), if (isLastMinute) ...[ const SizedBox(width: 4), - const Text( + Text( "• 4hr compensation", - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w500, - color: Color(0xFF10B981), - ), + style: UiTypography.footnote2m.textSuccess, ), ], ], ), - const SizedBox(height: 12), + const SizedBox(height: UiConstants.space3), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -504,18 +483,18 @@ class _MyShiftsTabState extends State { width: 44, height: 44, decoration: BoxDecoration( - color: AppColors.krowBlue.withOpacity(0.05), - borderRadius: BorderRadius.circular(12), + color: UiColors.primary.withValues(alpha: 0.05), + borderRadius: BorderRadius.circular(UiConstants.radiusBase), ), child: const Center( child: Icon( - LucideIcons.briefcase, - color: AppColors.krowBlue, + UiIcons.briefcase, + color: UiColors.primary, size: 20, ), ), ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -529,18 +508,11 @@ class _MyShiftsTabState extends State { children: [ Text( title, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: AppColors.krowCharcoal, - ), + style: UiTypography.body2b.textPrimary, ), Text( client, - style: const TextStyle( - fontSize: 12, - color: AppColors.krowMuted, - ), + style: UiTypography.footnote1r.textSecondary, ), ], ), @@ -550,52 +522,39 @@ class _MyShiftsTabState extends State { children: [ Text( pay, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppColors.krowCharcoal, - ), + style: UiTypography.headline4m.textPrimary, ), Text( rate, - style: const TextStyle( - fontSize: 10, - color: AppColors.krowMuted, - ), + style: UiTypography.footnote2r.textSecondary, ), ], ), ], ), - const SizedBox(height: 8), + const SizedBox(height: UiConstants.space2), Row( children: [ const Icon( - LucideIcons.calendar, + UiIcons.calendar, size: 12, - color: AppColors.krowMuted, + color: UiColors.textSecondary, ), const SizedBox(width: 4), Text( date, - style: const TextStyle( - fontSize: 12, - color: AppColors.krowMuted, - ), + style: UiTypography.footnote1r.textSecondary, ), - const SizedBox(width: 12), + const SizedBox(width: UiConstants.space3), const Icon( - LucideIcons.clock, + UiIcons.clock, size: 12, - color: AppColors.krowMuted, + color: UiColors.textSecondary, ), const SizedBox(width: 4), Text( time, - style: const TextStyle( - fontSize: 12, - color: AppColors.krowMuted, - ), + style: UiTypography.footnote1r.textSecondary, ), ], ), @@ -603,18 +562,15 @@ class _MyShiftsTabState extends State { Row( children: [ const Icon( - LucideIcons.mapPin, + UiIcons.mapPin, size: 12, - color: AppColors.krowMuted, + color: UiColors.textSecondary, ), const SizedBox(width: 4), Expanded( child: Text( address, - style: const TextStyle( - fontSize: 12, - color: AppColors.krowMuted, - ), + style: UiTypography.footnote1r.textSecondary, overflow: TextOverflow.ellipsis, ), ),