Refactor UI components to utilize design system colors and typography

- Removed deprecated app_colors.dart file.
- Updated AttendanceCard widget to use design system colors and typography.
- Refactored CommuteTracker widget for consistent styling with design system.
- Modified DateSelector widget to apply design system styles.
- Adjusted LocationMapPlaceholder widget to align with design system.
- Enhanced LunchBreakDialog with design system colors and typography.
- Updated SwipeToCheckIn widget to utilize design system for colors and text styles.
This commit is contained in:
Achintha Isuru
2026-02-10 16:05:05 -05:00
parent 8edfc72370
commit c6448ad5c1
8 changed files with 309 additions and 440 deletions

View File

@@ -9,7 +9,6 @@ import 'package:lucide_icons/lucide_icons.dart';
import '../bloc/clock_in_bloc.dart'; import '../bloc/clock_in_bloc.dart';
import '../bloc/clock_in_event.dart'; import '../bloc/clock_in_event.dart';
import '../bloc/clock_in_state.dart'; import '../bloc/clock_in_state.dart';
import '../theme/app_colors.dart';
import '../widgets/commute_tracker.dart'; import '../widgets/commute_tracker.dart';
import '../widgets/date_selector.dart'; import '../widgets/date_selector.dart';
import '../widgets/lunch_break_modal.dart'; import '../widgets/lunch_break_modal.dart';
@@ -39,9 +38,11 @@ class _ClockInPageState extends State<ClockInPage> {
listener: (BuildContext context, ClockInState state) { listener: (BuildContext context, ClockInState state) {
if (state.status == ClockInStatus.failure && if (state.status == ClockInStatus.failure &&
state.errorMessage != null) { state.errorMessage != null) {
ScaffoldMessenger.of( UiSnackbar.show(
context, context,
).showSnackBar(SnackBar(content: Text(state.errorMessage!))); message: state.errorMessage!,
type: UiSnackbarType.error,
);
} }
}, },
builder: (BuildContext context, ClockInState state) { builder: (BuildContext context, ClockInState state) {
@@ -110,14 +111,10 @@ class _ClockInPageState extends State<ClockInPage> {
const SizedBox(height: 20), const SizedBox(height: 20),
// Your Activity Header // Your Activity Header
const Text( Text(
"Your Activity", "Your Activity",
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: TextStyle( style: UiTypography.headline4m,
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColors.krowCharcoal,
),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -135,15 +132,15 @@ class _ClockInPageState extends State<ClockInPage> {
margin: margin:
const EdgeInsets.only(bottom: 12), const EdgeInsets.only(bottom: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: UiColors.white,
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
12, 12,
), ),
border: Border.all( border: Border.all(
color: shift.id == color: shift.id ==
selectedShift?.id selectedShift?.id
? AppColors.krowBlue ? UiColors.primary
: const Color(0xFFE2E8F0), : UiColors.border,
width: width:
shift.id == selectedShift?.id shift.id == selectedShift?.id
? 2 ? 2
@@ -164,34 +161,25 @@ class _ClockInPageState extends State<ClockInPage> {
selectedShift?.id selectedShift?.id
? "SELECTED SHIFT" ? "SELECTED SHIFT"
: "TODAY'S SHIFT", : "TODAY'S SHIFT",
style: TextStyle( style: UiTypography
fontSize: 10, .titleUppercase4b
fontWeight: .copyWith(
FontWeight.w600,
color: shift.id == color: shift.id ==
selectedShift?.id selectedShift?.id
? AppColors.krowBlue ? UiColors.primary
: AppColors : UiColors
.krowCharcoal, .textSecondary,
letterSpacing: 0.5,
), ),
), ),
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
shift.title, shift.title,
style: const TextStyle( style: UiTypography.body2b,
fontSize: 14,
fontWeight:
FontWeight.w600,
color: Color(0xFF1E293B),
),
), ),
Text( Text(
"${shift.clientName}${shift.location}", "${shift.clientName}${shift.location}",
style: const TextStyle( style: UiTypography.body3r
fontSize: 12, .textSecondary,
color: Color(0xFF64748B),
),
), ),
], ],
), ),
@@ -202,18 +190,14 @@ class _ClockInPageState extends State<ClockInPage> {
children: <Widget>[ children: <Widget>[
Text( Text(
"${_formatTime(shift.startTime)} - ${_formatTime(shift.endTime)}", "${_formatTime(shift.startTime)} - ${_formatTime(shift.endTime)}",
style: const TextStyle( style: UiTypography.body3m
fontSize: 12, .textSecondary,
fontWeight: FontWeight.w500,
color: Color(0xFF475569),
),
), ),
Text( Text(
"\$${shift.hourlyRate}/hr", "\$${shift.hourlyRate}/hr",
style: const TextStyle( style: UiTypography.body3m
fontSize: 12, .copyWith(
fontWeight: FontWeight.w600, color: UiColors.primary,
color: AppColors.krowBlue,
), ),
), ),
], ],
@@ -234,7 +218,7 @@ class _ClockInPageState extends State<ClockInPage> {
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFF1F5F9), // slate-100 color: UiColors.bgSecondary,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Column( child: Column(
@@ -242,24 +226,17 @@ class _ClockInPageState extends State<ClockInPage> {
const Icon( const Icon(
LucideIcons.clock, LucideIcons.clock,
size: 48, size: 48,
color: Color(0xFF94A3B8), // slate-400 color: UiColors.iconThird,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text( Text(
"You're early!", "You're early!",
style: TextStyle( style: UiTypography.body1m.textSecondary,
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xFF475569), // slate-600
),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
"Check-in available at ${_getCheckInAvailabilityTime(selectedShift)}", "Check-in available at ${_getCheckInAvailabilityTime(selectedShift)}",
style: const TextStyle( style: UiTypography.body2r.textSecondary,
fontSize: 14,
color: Color(0xFF64748B), // slate-500
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
@@ -304,11 +281,11 @@ class _ClockInPageState extends State<ClockInPage> {
Container( Container(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFECFDF5), // emerald-50 color: UiColors.tagSuccess,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color(0xFFA7F3D0), color: UiColors.success.withValues(alpha: 0.3),
), // emerald-200 ),
), ),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@@ -316,31 +293,24 @@ class _ClockInPageState extends State<ClockInPage> {
width: 48, width: 48,
height: 48, height: 48,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color(0xFFD1FAE5), // emerald-100 color: UiColors.tagActive,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.check, LucideIcons.check,
color: Color(0xFF059669), // emerald-600 color: UiColors.textSuccess,
size: 24, size: 24,
), ),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
const Text( Text(
"Shift Completed!", "Shift Completed!",
style: TextStyle( style: UiTypography.body1b.textSuccess,
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xFF065F46), // emerald-800
),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
const Text( Text(
"Great work today", "Great work today",
style: TextStyle( style: UiTypography.body2r.textSuccess,
fontSize: 14,
color: Color(0xFF059669), // emerald-600
),
), ),
], ],
), ),
@@ -351,27 +321,20 @@ class _ClockInPageState extends State<ClockInPage> {
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFF1F5F9), // slate-100 color: UiColors.bgSecondary,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: const Column( child: Column(
children: <Widget>[ children: <Widget>[
Text( Text(
"No confirmed shifts for today", "No confirmed shifts for today",
style: TextStyle( style: UiTypography.body1m.textSecondary,
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF475569), // slate-600
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
"Accept a shift to clock in", "Accept a shift to clock in",
style: TextStyle( style: UiTypography.body2r.textSecondary,
fontSize: 14,
color: Color(0xFF64748B), // slate-500
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
@@ -385,11 +348,11 @@ class _ClockInPageState extends State<ClockInPage> {
Container( Container(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFECFDF5), // emerald-50 color: UiColors.tagSuccess,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
border: Border.all( border: Border.all(
color: const Color(0xFFA7F3D0), color: UiColors.success.withValues(alpha: 0.3),
), // emerald-200 ),
), ),
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
@@ -399,23 +362,15 @@ class _ClockInPageState extends State<ClockInPage> {
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
const Text( Text(
"Checked in at", "Checked in at",
style: TextStyle( style: UiTypography.body3m.textSuccess,
fontSize: 12,
fontWeight: FontWeight.w500,
color: Color(0xFF059669),
),
), ),
Text( Text(
DateFormat( DateFormat(
'h:mm a', 'h:mm a',
).format(checkInTime), ).format(checkInTime),
style: const TextStyle( style: UiTypography.body1b.textSuccess,
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF065F46),
),
), ),
], ],
), ),
@@ -423,12 +378,12 @@ class _ClockInPageState extends State<ClockInPage> {
width: 40, width: 40,
height: 40, height: 40,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color(0xFFD1FAE5), color: UiColors.tagActive,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.check, LucideIcons.check,
color: Color(0xFF059669), color: UiColors.textSuccess,
), ),
), ),
], ],
@@ -466,12 +421,12 @@ class _ClockInPageState extends State<ClockInPage> {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected ? Colors.white : Colors.transparent, color: isSelected ? UiColors.white : UiColors.transparent,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
boxShadow: isSelected boxShadow: isSelected
? <BoxShadow>[ ? <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.05), color: UiColors.black.withValues(alpha: 0.05),
blurRadius: 2, blurRadius: 2,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),
@@ -484,15 +439,15 @@ class _ClockInPageState extends State<ClockInPage> {
Icon( Icon(
icon, icon,
size: 16, size: 16,
color: isSelected ? Colors.black : Colors.grey, color: isSelected ? UiColors.foreground : UiColors.iconThird,
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
Text( Text(
label, label,
style: TextStyle( style: UiTypography.body2m.copyWith(
fontSize: 14, color: isSelected
fontWeight: FontWeight.w500, ? UiColors.foreground
color: isSelected ? Colors.black : Colors.grey, : UiColors.textSecondary,
), ),
), ),
], ],
@@ -521,26 +476,19 @@ class _ClockInPageState extends State<ClockInPage> {
width: 96, width: 96,
height: 96, height: 96,
decoration: BoxDecoration( decoration: BoxDecoration(
color: scanned color: scanned ? UiColors.tagSuccess : UiColors.tagInProgress,
? Colors.green.shade50
: Colors.blue.shade50,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Icon( child: Icon(
scanned ? LucideIcons.check : LucideIcons.nfc, scanned ? LucideIcons.check : LucideIcons.nfc,
size: 48, size: 48,
color: scanned color: scanned ? UiColors.textSuccess : UiColors.primary,
? Colors.green.shade600
: Colors.blue.shade600,
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
Text( Text(
scanned ? 'Processing check-in...' : 'Ready to scan', scanned ? 'Processing check-in...' : 'Ready to scan',
style: const TextStyle( style: UiTypography.headline4m,
fontSize: 18,
fontWeight: FontWeight.w600,
),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
@@ -548,7 +496,7 @@ class _ClockInPageState extends State<ClockInPage> {
? 'Please wait...' ? 'Please wait...'
: 'Hold your phone near the NFC tag at the clock-in station', : 'Hold your phone near the NFC tag at the clock-in station',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 14, color: Colors.grey.shade600), style: UiTypography.body2r.textSecondary,
), ),
if (!scanned) ...<Widget>[ if (!scanned) ...<Widget>[
const SizedBox(height: 24), const SizedBox(height: 24),
@@ -573,16 +521,13 @@ class _ClockInPageState extends State<ClockInPage> {
// It's safer to just return a result // It's safer to just return a result
}, },
icon: const Icon(LucideIcons.nfc, size: 24), icon: const Icon(LucideIcons.nfc, size: 24),
label: const Text( label: Text(
'Tap to Scan', 'Tap to Scan',
style: TextStyle( style: UiTypography.headline4m.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0047FF), backgroundColor: UiColors.primary,
foregroundColor: Colors.white, foregroundColor: UiColors.white,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),

View File

@@ -1,13 +0,0 @@
import 'package:flutter/material.dart';
class AppColors {
static const Color krowBlue = Color(0xFF0A39DF);
static const Color krowYellow = Color(0xFFFFED4A);
static const Color krowCharcoal = Color(0xFF121826);
static const Color krowMuted = Color(0xFF6A7382);
static const Color krowBorder = Color(0xFFE3E6E9);
static const Color krowBackground = Color(0xFFFAFBFC);
static const Color white = Colors.white;
static const Color black = Colors.black;
}

View File

@@ -1,10 +1,10 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
enum AttendanceType { checkin, checkout, breaks, days } enum AttendanceType { checkin, checkout, breaks, days }
class AttendanceCard extends StatelessWidget { class AttendanceCard extends StatelessWidget {
const AttendanceCard({ const AttendanceCard({
super.key, super.key,
required this.type, required this.type,
@@ -26,12 +26,12 @@ class AttendanceCard extends StatelessWidget {
return Container( return Container(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey.shade100), border: Border.all(color: UiColors.bgSecondary),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.05), color: UiColors.black.withValues(alpha: 0.05),
blurRadius: 2, blurRadius: 2,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),
@@ -53,10 +53,7 @@ class AttendanceCard extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
title, title,
style: const TextStyle( style: UiTypography.titleUppercase4m.textSecondary,
fontSize: 11,
color: Color(0xFF64748B), // slate-500
),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -65,27 +62,20 @@ class AttendanceCard extends StatelessWidget {
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
child: Text( child: Text(
value, value,
style: const TextStyle( style: UiTypography.headline4m,
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xFF0F172A), // slate-900
),
), ),
), ),
if (scheduledTime != null) ...<Widget>[ if (scheduledTime != null) ...<Widget>[
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
"Scheduled: $scheduledTime", "Scheduled: $scheduledTime",
style: const TextStyle( style: UiTypography.footnote2r.textInactive,
fontSize: 10,
color: Color(0xFF94A3B8), // slate-400
),
), ),
], ],
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
subtitle, subtitle,
style: const TextStyle(fontSize: 12, color: Color(0xFF0032A0)), style: UiTypography.footnote1r.copyWith(color: UiColors.primary),
), ),
], ],
), ),
@@ -97,26 +87,26 @@ class AttendanceCard extends StatelessWidget {
case AttendanceType.checkin: case AttendanceType.checkin:
return _AttendanceStyle( return _AttendanceStyle(
icon: LucideIcons.logIn, icon: LucideIcons.logIn,
bgColor: const Color(0xFF0032A0).withOpacity(0.1), bgColor: UiColors.primary.withValues(alpha: 0.1),
iconColor: const Color(0xFF0032A0), iconColor: UiColors.primary,
); );
case AttendanceType.checkout: case AttendanceType.checkout:
return _AttendanceStyle( return _AttendanceStyle(
icon: LucideIcons.logOut, icon: LucideIcons.logOut,
bgColor: const Color(0xFF333F48).withOpacity(0.1), bgColor: UiColors.foreground.withValues(alpha: 0.1),
iconColor: const Color(0xFF333F48), iconColor: UiColors.foreground,
); );
case AttendanceType.breaks: case AttendanceType.breaks:
return _AttendanceStyle( return _AttendanceStyle(
icon: LucideIcons.coffee, icon: LucideIcons.coffee,
bgColor: const Color(0xFFF9E547).withOpacity(0.2), bgColor: UiColors.accent.withValues(alpha: 0.2),
iconColor: const Color(0xFF4C460D), iconColor: UiColors.accentForeground,
); );
case AttendanceType.days: case AttendanceType.days:
return _AttendanceStyle( return _AttendanceStyle(
icon: LucideIcons.calendar, icon: LucideIcons.calendar,
bgColor: Colors.green.withOpacity(0.1), bgColor: UiColors.success.withValues(alpha: 0.1),
iconColor: Colors.green, iconColor: UiColors.textSuccess,
); );
} }
} }

View File

@@ -1,7 +1,7 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../theme/app_colors.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import 'package:lucide_icons/lucide_icons.dart';
enum CommuteMode { enum CommuteMode {
lockedNoShift, lockedNoShift,
@@ -161,18 +161,18 @@ class _CommuteTrackerState extends State<CommuteTracker> {
margin: const EdgeInsets.only(bottom: 20), margin: const EdgeInsets.only(bottom: 20),
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: const LinearGradient( gradient: LinearGradient(
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,
colors: <Color>[ colors: <Color>[
Color(0xFFEFF6FF), // blue-50 UiColors.primary.withValues(alpha: 0.05),
Color(0xFFECFEFF), // cyan-50 UiColors.primary.withValues(alpha: 0.1),
], ],
), ),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.05), color: UiColors.black.withValues(alpha: 0.05),
blurRadius: 2, blurRadius: 2,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),
@@ -188,35 +188,28 @@ class _CommuteTrackerState extends State<CommuteTracker> {
width: 32, width: 32,
height: 32, height: 32,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color(0xFF2563EB), // blue-600 color: UiColors.primary,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.mapPin, LucideIcons.mapPin,
size: 16, size: 16,
color: Colors.white, color: UiColors.white,
), ),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
const Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Text(
'Enable Commute Tracking?', 'Enable Commute Tracking?',
style: TextStyle( style: UiTypography.body2m.textPrimary,
fontSize: 14,
fontWeight: FontWeight.w600,
color: Color(0xFF0F172A), // slate-900
), ),
), const SizedBox(height: 4),
SizedBox(height: 4),
Text( Text(
'Share location 1hr before shift so your manager can see you\'re on the way.', 'Share location 1hr before shift so your manager can see you\'re on the way.',
style: TextStyle( style: UiTypography.body4r.textSecondary,
fontSize: 12,
color: Color(0xFF475569), // slate-600
),
), ),
], ],
), ),
@@ -233,9 +226,9 @@ class _CommuteTrackerState extends State<CommuteTracker> {
}, },
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
side: const BorderSide(color: Color(0xFFE2E8F0)), side: const BorderSide(color: UiColors.border),
), ),
child: const Text('Not Now', style: TextStyle(fontSize: 12)), child: Text('Not Now', style: UiTypography.footnote1m),
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -245,12 +238,12 @@ class _CommuteTrackerState extends State<CommuteTracker> {
setState(() => _localHasConsent = true); setState(() => _localHasConsent = true);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2563EB), // blue-600 backgroundColor: UiColors.primary,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
), ),
child: const Text( child: Text(
'Enable', 'Enable',
style: TextStyle(fontSize: 12, color: Colors.white), style: UiTypography.footnote1m.white,
), ),
), ),
), ),
@@ -266,11 +259,11 @@ class _CommuteTrackerState extends State<CommuteTracker> {
margin: const EdgeInsets.only(bottom: 20), margin: const EdgeInsets.only(bottom: 20),
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.05), color: UiColors.black.withValues(alpha: 0.05),
blurRadius: 2, blurRadius: 2,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),
@@ -282,13 +275,13 @@ class _CommuteTrackerState extends State<CommuteTracker> {
width: 32, width: 32,
height: 32, height: 32,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color(0xFFF1F5F9), // slate-100 color: UiColors.bgSecondary,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.navigation, LucideIcons.navigation,
size: 16, size: 16,
color: Color(0xFF475569), // slate-600 color: UiColors.textSecondary,
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -298,13 +291,9 @@ class _CommuteTrackerState extends State<CommuteTracker> {
children: <Widget>[ children: <Widget>[
Row( Row(
children: <Widget>[ children: <Widget>[
const Text( Text(
'On My Way', 'On My Way',
style: TextStyle( style: UiTypography.body2m.textPrimary,
fontSize: 14,
fontWeight: FontWeight.w600,
color: Color(0xFF0F172A), // slate-900
),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Row( Row(
@@ -312,26 +301,20 @@ class _CommuteTrackerState extends State<CommuteTracker> {
const Icon( const Icon(
LucideIcons.clock, LucideIcons.clock,
size: 12, size: 12,
color: Color(0xFF64748B), // slate-500 color: UiColors.textInactive,
), ),
const SizedBox(width: 2), const SizedBox(width: 2),
Text( Text(
'Shift starts in ${_getMinutesUntilShift()} min', 'Shift starts in ${_getMinutesUntilShift()} min',
style: const TextStyle( style: UiTypography.titleUppercase4m.textSecondary,
fontSize: 11,
color: Color(0xFF64748B), // slate-500
),
), ),
], ],
), ),
], ],
), ),
const Text( Text(
'Track arrival', 'Track arrival',
style: TextStyle( style: UiTypography.titleUppercase4m.textSecondary,
fontSize: 10,
color: Color(0xFF64748B), // slate-500
),
), ),
], ],
), ),
@@ -342,7 +325,7 @@ class _CommuteTrackerState extends State<CommuteTracker> {
setState(() => _localIsCommuteOn = value); setState(() => _localIsCommuteOn = value);
widget.onCommuteToggled?.call(value); widget.onCommuteToggled?.call(value);
}, },
activeThumbColor: AppColors.krowBlue, activeThumbColor: UiColors.primary,
), ),
], ],
), ),
@@ -357,8 +340,8 @@ class _CommuteTrackerState extends State<CommuteTracker> {
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,
colors: <Color>[ colors: <Color>[
Color(0xFF2563EB), // blue-600 UiColors.primary,
Color(0xFF0891B2), // cyan-600 UiColors.iconActive,
], ],
), ),
), ),
@@ -383,13 +366,13 @@ class _CommuteTrackerState extends State<CommuteTracker> {
width: 96, width: 96,
height: 96, height: 96,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2), color: UiColors.white.withValues(alpha: 0.2),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.navigation, LucideIcons.navigation,
size: 48, size: 48,
color: Colors.white, color: UiColors.white,
), ),
), ),
); );
@@ -400,20 +383,15 @@ class _CommuteTrackerState extends State<CommuteTracker> {
}, },
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
const Text( Text(
'On My Way', 'On My Way',
style: TextStyle( style: UiTypography.displayMb.white,
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.white,
),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'Your manager can see you\'re heading to the site', 'Your manager can see you\'re heading to the site',
style: TextStyle( style: UiTypography.body2r.copyWith(
fontSize: 14, color: UiColors.primaryForeground.withValues(alpha: 0.8),
color: Colors.blue.shade100,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -424,29 +402,24 @@ class _CommuteTrackerState extends State<CommuteTracker> {
constraints: const BoxConstraints(maxWidth: 300), constraints: const BoxConstraints(maxWidth: 300),
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1), color: UiColors.white.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: Colors.white.withOpacity(0.2), color: UiColors.white.withValues(alpha: 0.2),
), ),
), ),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Text( Text(
'Distance to Site', 'Distance to Site',
style: TextStyle( style: UiTypography.body2r.copyWith(
fontSize: 14, color: UiColors.primaryForeground.withValues(alpha: 0.8),
color: Colors.blue.shade100,
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
_formatDistance(widget.distanceMeters!), _formatDistance(widget.distanceMeters!),
style: const TextStyle( style: UiTypography.displayM.white,
fontSize: 36,
fontWeight: FontWeight.bold,
color: Colors.white,
),
), ),
], ],
), ),
@@ -458,29 +431,24 @@ class _CommuteTrackerState extends State<CommuteTracker> {
constraints: const BoxConstraints(maxWidth: 300), constraints: const BoxConstraints(maxWidth: 300),
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1), color: UiColors.white.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: Colors.white.withOpacity(0.2), color: UiColors.white.withValues(alpha: 0.2),
), ),
), ),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Text( Text(
'Estimated Arrival', 'Estimated Arrival',
style: TextStyle( style: UiTypography.body2r.copyWith(
fontSize: 14, color: UiColors.primaryForeground.withValues(alpha: 0.8),
color: Colors.blue.shade100,
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'${widget.etaMinutes} min', '${widget.etaMinutes} min',
style: const TextStyle( style: UiTypography.headline1m.white,
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
), ),
], ],
), ),
@@ -490,9 +458,8 @@ class _CommuteTrackerState extends State<CommuteTracker> {
const SizedBox(height: 32), const SizedBox(height: 32),
Text( Text(
'Most app features are locked while commute mode is on. You\'ll be able to clock in once you arrive.', 'Most app features are locked while commute mode is on. You\'ll be able to clock in once you arrive.',
style: TextStyle( style: UiTypography.footnote1r.copyWith(
fontSize: 12, color: UiColors.primaryForeground.withValues(alpha: 0.8),
color: Colors.blue.shade100,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -508,12 +475,12 @@ class _CommuteTrackerState extends State<CommuteTracker> {
setState(() => _localIsCommuteOn = false); setState(() => _localIsCommuteOn = false);
}, },
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: UiColors.white,
side: BorderSide(color: Colors.white.withOpacity(0.3)), side: BorderSide(color: UiColors.white.withValues(alpha: 0.3)),
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
minimumSize: const Size(double.infinity, 48), minimumSize: const Size(double.infinity, 48),
), ),
child: const Text('Turn Off Commute Mode'), child: Text('Turn Off Commute Mode', style: UiTypography.buttonL),
), ),
), ),
], ],
@@ -527,18 +494,18 @@ class _CommuteTrackerState extends State<CommuteTracker> {
margin: const EdgeInsets.only(bottom: 20), margin: const EdgeInsets.only(bottom: 20),
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: const LinearGradient( gradient: LinearGradient(
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,
colors: <Color>[ colors: <Color>[
Color(0xFFECFDF5), // emerald-50 UiColors.tagSuccess,
Color(0xFFD1FAE5), // green-50 UiColors.tagActive,
], ],
), ),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.1), color: UiColors.black.withValues(alpha: 0.1),
blurRadius: 8, blurRadius: 8,
offset: const Offset(0, 2), offset: const Offset(0, 2),
), ),
@@ -550,31 +517,24 @@ class _CommuteTrackerState extends State<CommuteTracker> {
width: 64, width: 64,
height: 64, height: 64,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color(0xFF10B981), // emerald-500 color: UiColors.success,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.checkCircle, LucideIcons.checkCircle,
size: 32, size: 32,
color: Colors.white, color: UiColors.white,
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text( Text(
'You\'ve Arrived! 🎉', 'You\'ve Arrived! 🎉',
style: TextStyle( style: UiTypography.headline3m.textPrimary,
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xFF0F172A), // slate-900
),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
const Text( Text(
'You\'re at the shift location. Ready to clock in?', 'You\'re at the shift location. Ready to clock in?',
style: TextStyle( style: UiTypography.body2r.textSecondary,
fontSize: 14,
color: Color(0xFF475569), // slate-600
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],

View File

@@ -1,8 +1,8 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class DateSelector extends StatelessWidget { class DateSelector extends StatelessWidget {
const DateSelector({ const DateSelector({
super.key, super.key,
required this.selectedDate, required this.selectedDate,
@@ -36,12 +36,12 @@ class DateSelector extends StatelessWidget {
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected ? const Color(0xFF0032A0) : Colors.white, color: isSelected ? UiColors.primary : UiColors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
boxShadow: isSelected boxShadow: isSelected
? <BoxShadow>[ ? <BoxShadow>[
BoxShadow( BoxShadow(
color: const Color(0xFF0032A0).withOpacity(0.3), color: UiColors.primary.withValues(alpha: 0.3),
blurRadius: 10, blurRadius: 10,
offset: const Offset(0, 4), offset: const Offset(0, 4),
), ),
@@ -53,22 +53,18 @@ class DateSelector extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Text( Text(
DateFormat('d').format(date), DateFormat('d').format(date),
style: TextStyle( style: UiTypography.title1m.copyWith(
fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: isSelected color: isSelected ? UiColors.white : UiColors.foreground,
? Colors.white
: const Color(0xFF0F172A),
), ),
), ),
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
DateFormat('E').format(date), DateFormat('E').format(date),
style: TextStyle( style: UiTypography.footnote2r.copyWith(
fontSize: 12,
color: isSelected color: isSelected
? Colors.white.withOpacity(0.8) ? UiColors.white.withValues(alpha: 0.8)
: const Color(0xFF94A3B8), : UiColors.textInactive,
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
@@ -77,9 +73,7 @@ class DateSelector extends StatelessWidget {
width: 6, width: 6,
height: 6, height: 6,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: isSelected ? UiColors.white : UiColors.primary,
? Colors.white
: const Color(0xFF0032A0),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
) )
@@ -87,8 +81,8 @@ class DateSelector extends StatelessWidget {
Container( Container(
width: 6, width: 6,
height: 6, height: 6,
decoration: BoxDecoration( decoration: const BoxDecoration(
color: Colors.grey.shade300, color: UiColors.border,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
) )

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
class LocationMapPlaceholder extends StatelessWidget { class LocationMapPlaceholder extends StatelessWidget {
@@ -18,7 +18,7 @@ class LocationMapPlaceholder extends StatelessWidget {
height: 200, height: 200,
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFE2E8F0), color: UiColors.border,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
image: DecorationImage( image: DecorationImage(
image: const NetworkImage( image: const NetworkImage(
@@ -33,13 +33,14 @@ class LocationMapPlaceholder extends StatelessWidget {
child: Stack( child: Stack(
children: <Widget>[ children: <Widget>[
// Fallback UI if image fails (which it will without key) // Fallback UI if image fails (which it will without key)
const Center( Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Icon(LucideIcons.mapPin, size: 48, color: UiColors.iconSecondary), const Icon(LucideIcons.mapPin,
SizedBox(height: 8), size: 48, color: UiColors.iconSecondary),
Text('Map View (GPS)', style: TextStyle(color: UiColors.textSecondary)), const SizedBox(height: 8),
Text('Map View (GPS)', style: UiTypography.body2r.textSecondary),
], ],
), ),
), ),
@@ -52,11 +53,11 @@ class LocationMapPlaceholder extends StatelessWidget {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.1), color: UiColors.black.withValues(alpha: 0.1),
blurRadius: 8, blurRadius: 8,
offset: const Offset(0, 4), offset: const Offset(0, 4),
), ),
@@ -65,8 +66,12 @@ class LocationMapPlaceholder extends StatelessWidget {
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Icon( Icon(
isVerified ? LucideIcons.checkCircle : LucideIcons.alertCircle, isVerified
color: isVerified ? UiColors.textSuccess : UiColors.destructive, ? LucideIcons.checkCircle
: LucideIcons.alertCircle,
color: isVerified
? UiColors.textSuccess
: UiColors.destructive,
size: 20, size: 20,
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
@@ -76,12 +81,12 @@ class LocationMapPlaceholder extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Text( Text(
isVerified ? 'Location Verified' : 'Location Check', isVerified ? 'Location Verified' : 'Location Check',
style: UiTypography.body1b.copyWith(color: UiColors.textPrimary), style: UiTypography.body1b.textPrimary,
), ),
if (distance != null) if (distance != null)
Text( Text(
'${distance!.toStringAsFixed(0)}m from venue', '${distance!.toStringAsFixed(0)}m from venue',
style: UiTypography.body2r.copyWith(color: UiColors.textSecondary), style: UiTypography.body2r.textSecondary,
), ),
], ],
), ),

View File

@@ -1,8 +1,8 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
class LunchBreakDialog extends StatefulWidget { class LunchBreakDialog extends StatefulWidget {
const LunchBreakDialog({super.key, required this.onComplete}); const LunchBreakDialog({super.key, required this.onComplete});
final VoidCallback onComplete; final VoidCallback onComplete;
@@ -47,7 +47,7 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Dialog( return Dialog(
backgroundColor: Colors.white, backgroundColor: UiColors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
@@ -82,25 +82,21 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
Container( Container(
width: 80, width: 80,
height: 80, height: 80,
decoration: BoxDecoration( decoration: const BoxDecoration(
color: Colors.grey.shade100, color: UiColors.bgSecondary,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: const Icon( child: const Icon(
LucideIcons.coffee, LucideIcons.coffee,
size: 40, size: 40,
color: Color(0xFF6A7382), color: UiColors.iconSecondary,
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
const Text( Text(
"Did You Take\na Lunch?", "Did You Take\na Lunch?",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: UiTypography.headline1m.textPrimary,
fontSize: 24,
fontWeight: FontWeight.bold,
color: Color(0xFF121826),
),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
Row( Row(
@@ -116,18 +112,14 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: UiColors.border),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
color: Colors.transparent, color: UiColors.transparent,
), ),
alignment: Alignment.center, alignment: Alignment.center,
child: const Text( child: Text(
"No", "No",
style: TextStyle( style: UiTypography.body1m.textPrimary,
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xFF121826),
),
), ),
), ),
), ),
@@ -142,19 +134,15 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
}); });
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0032A0), backgroundColor: UiColors.primary,
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
), ),
child: const Text( child: Text(
"Yes", "Yes",
style: TextStyle( style: UiTypography.body1m.white,
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white,
),
), ),
), ),
), ),
@@ -172,9 +160,9 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
const Text( Text(
"When did you take lunch?", "When did you take lunch?",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: UiTypography.headline4m,
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
// Mock Inputs // Mock Inputs
@@ -183,12 +171,17 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
Expanded( Expanded(
child: DropdownButtonFormField<String>( child: DropdownButtonFormField<String>(
isExpanded: true, isExpanded: true,
initialValue: _breakStart, value: _breakStart,
items: _timeOptions.map((String t) => DropdownMenuItem(value: t, child: Text(t, style: const TextStyle(fontSize: 13)))).toList(), items: _timeOptions
.map((String t) => DropdownMenuItem(
value: t,
child: Text(t, style: UiTypography.body3r)))
.toList(),
onChanged: (String? v) => setState(() => _breakStart = v), onChanged: (String? v) => setState(() => _breakStart = v),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'Start', labelText: 'Start',
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), contentPadding:
EdgeInsets.symmetric(horizontal: 10, vertical: 8),
), ),
), ),
), ),
@@ -196,12 +189,17 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
Expanded( Expanded(
child: DropdownButtonFormField<String>( child: DropdownButtonFormField<String>(
isExpanded: true, isExpanded: true,
initialValue: _breakEnd, value: _breakEnd,
items: _timeOptions.map((String t) => DropdownMenuItem(value: t, child: Text(t, style: const TextStyle(fontSize: 13)))).toList(), items: _timeOptions
.map((String t) => DropdownMenuItem(
value: t,
child: Text(t, style: UiTypography.body3r)))
.toList(),
onChanged: (String? v) => setState(() => _breakEnd = v), onChanged: (String? v) => setState(() => _breakEnd = v),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'End', labelText: 'End',
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), contentPadding:
EdgeInsets.symmetric(horizontal: 10, vertical: 8),
), ),
), ),
), ),
@@ -214,10 +212,10 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
setState(() => _step = 3); setState(() => _step = 3);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0032A0), backgroundColor: UiColors.primary,
minimumSize: const Size(double.infinity, 48), minimumSize: const Size(double.infinity, 48),
), ),
child: const Text("Next", style: TextStyle(color: Colors.white)), child: Text("Next", style: UiTypography.body1m.white),
), ),
], ],
)); ));
@@ -231,16 +229,18 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
const Text( Text(
"Why didn't you take lunch?", "Why didn't you take lunch?",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: UiTypography.headline4m,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
..._noLunchReasons.map((String reason) => RadioListTile<String>( ..._noLunchReasons.map((String reason) => RadioListTile<String>(
title: Text(reason), title: Text(reason, style: UiTypography.body2r),
value: reason, value: reason,
groupValue: _noLunchReason, groupValue: _noLunchReason,
onChanged: (String? val) => setState(() => _noLunchReason = val), onChanged: (String? val) =>
setState(() => _noLunchReason = val),
activeColor: UiColors.primary,
)), )),
const SizedBox(height: 24), const SizedBox(height: 24),
@@ -249,10 +249,10 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
setState(() => _step = 3); setState(() => _step = 3);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0032A0), backgroundColor: UiColors.primary,
minimumSize: const Size(double.infinity, 48), minimumSize: const Size(double.infinity, 48),
), ),
child: const Text("Next", style: TextStyle(color: Colors.white)), child: Text("Next", style: UiTypography.body1m.white),
), ),
], ],
)); ));
@@ -265,13 +265,14 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
const Text( Text(
"Additional Notes", "Additional Notes",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: UiTypography.headline4m,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextField( TextField(
onChanged: (String v) => _additionalNotes = v, onChanged: (String v) => _additionalNotes = v,
style: UiTypography.body2r,
decoration: const InputDecoration( decoration: const InputDecoration(
hintText: 'Add any details...', hintText: 'Add any details...',
border: OutlineInputBorder(), border: OutlineInputBorder(),
@@ -285,10 +286,10 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
setState(() => _step = 4); setState(() => _step = 4);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0032A0), backgroundColor: UiColors.primary,
minimumSize: const Size(double.infinity, 48), minimumSize: const Size(double.infinity, 48),
), ),
child: const Text("Submit", style: TextStyle(color: Colors.white)), child: Text("Submit", style: UiTypography.body1m.white),
), ),
], ],
)); ));
@@ -301,20 +302,21 @@ class _LunchBreakDialogState extends State<LunchBreakDialog> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
const Icon(LucideIcons.checkCircle, size: 64, color: Colors.green), const Icon(LucideIcons.checkCircle,
size: 64, color: UiColors.success),
const SizedBox(height: 24), const SizedBox(height: 24),
const Text( Text(
"Break Logged!", "Break Logged!",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), style: UiTypography.headline1m,
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
ElevatedButton( ElevatedButton(
onPressed: widget.onComplete, onPressed: widget.onComplete,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0032A0), backgroundColor: UiColors.primary,
minimumSize: const Size(double.infinity, 48), minimumSize: const Size(double.infinity, 48),
), ),
child: const Text("Close", style: TextStyle(color: Colors.white)), child: Text("Close", style: UiTypography.body1m.white),
), ),
], ],
)); ));

View File

@@ -1,3 +1,4 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
@@ -72,9 +73,8 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Color baseColor = widget.isCheckedIn final Color baseColor =
? const Color(0xFF10B981) widget.isCheckedIn ? UiColors.success : UiColors.primary;
: const Color(0xFF0032A0);
if (widget.mode == 'nfc') { if (widget.mode == 'nfc') {
return GestureDetector( return GestureDetector(
@@ -96,7 +96,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: baseColor.withOpacity(0.4), color: baseColor.withValues(alpha: 0.4),
blurRadius: 25, blurRadius: 25,
offset: const Offset(0, 10), offset: const Offset(0, 10),
spreadRadius: -5, spreadRadius: -5,
@@ -106,7 +106,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
const Icon(LucideIcons.wifi, color: Colors.white), const Icon(LucideIcons.wifi, color: UiColors.white),
const SizedBox(width: 12), const SizedBox(width: 12),
Text( Text(
widget.isLoading widget.isLoading
@@ -114,11 +114,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
? "Checking out..." ? "Checking out..."
: "Checking in...") : "Checking in...")
: (widget.isCheckedIn ? "NFC Check Out" : "NFC Check In"), : (widget.isCheckedIn ? "NFC Check Out" : "NFC Check In"),
style: const TextStyle( style: UiTypography.body1b.white,
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
), ),
], ],
), ),
@@ -133,12 +129,10 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
// Calculate background color based on drag // Calculate background color based on drag
final double progress = _dragValue / maxDrag; final double progress = _dragValue / maxDrag;
final Color startColor = widget.isCheckedIn final Color startColor =
? const Color(0xFF10B981) widget.isCheckedIn ? UiColors.success : UiColors.primary;
: const Color(0xFF0032A0); final Color endColor =
final Color endColor = widget.isCheckedIn widget.isCheckedIn ? UiColors.primary : UiColors.success;
? const Color(0xFF0032A0)
: const Color(0xFF10B981);
final Color currentColor = final Color currentColor =
Color.lerp(startColor, endColor, progress) ?? startColor; Color.lerp(startColor, endColor, progress) ?? startColor;
@@ -149,7 +143,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.1), color: UiColors.black.withValues(alpha: 0.1),
blurRadius: 4, blurRadius: 4,
offset: const Offset(0, 2), offset: const Offset(0, 2),
), ),
@@ -164,11 +158,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
widget.isCheckedIn widget.isCheckedIn
? "Swipe to Check Out" ? "Swipe to Check Out"
: "Swipe to Check In", : "Swipe to Check In",
style: TextStyle( style: UiTypography.body1b,
color: Colors.white.withOpacity(0.8),
fontWeight: FontWeight.w600,
fontSize: 18,
),
), ),
), ),
), ),
@@ -176,11 +166,7 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
Center( Center(
child: Text( child: Text(
widget.isCheckedIn ? "Check Out!" : "Check In!", widget.isCheckedIn ? "Check Out!" : "Check In!",
style: const TextStyle( style: UiTypography.body1b,
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 18,
),
), ),
), ),
Positioned( Positioned(
@@ -193,11 +179,11 @@ class _SwipeToCheckInState extends State<SwipeToCheckIn>
width: _handleSize, width: _handleSize,
height: _handleSize, height: _handleSize,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.1), color: UiColors.black.withValues(alpha: 0.1),
blurRadius: 2, blurRadius: 2,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),