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:
@@ -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),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -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),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user