refactor: Update AvailabilityPage and ClockInPage to enhance UI consistency and remove unused code
This commit is contained in:
@@ -4,11 +4,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_modular/flutter_modular.dart'
|
import 'package:flutter_modular/flutter_modular.dart'
|
||||||
hide ModularWatchExtension;
|
hide ModularWatchExtension;
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
|
||||||
import '../blocs/availability_bloc.dart';
|
import '../blocs/availability_bloc.dart';
|
||||||
import '../blocs/availability_event.dart';
|
import '../blocs/availability_event.dart';
|
||||||
import '../blocs/availability_state.dart';
|
import '../blocs/availability_state.dart';
|
||||||
import 'package:krow_domain/krow_domain.dart';
|
|
||||||
|
|
||||||
class AvailabilityPage extends StatefulWidget {
|
class AvailabilityPage extends StatefulWidget {
|
||||||
const AvailabilityPage({super.key});
|
const AvailabilityPage({super.key});
|
||||||
@@ -102,7 +102,12 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else if (state is AvailabilityError) {
|
} else if (state is AvailabilityError) {
|
||||||
return Center(child: Text('Error: ${state.message}'));
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
'Error: ${state.message}',
|
||||||
|
style: UiTypography.body2r.textError,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
},
|
},
|
||||||
@@ -124,7 +129,7 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Quick Set Availability',
|
'Quick Set Availability',
|
||||||
style: UiTypography.body4r.copyWith(color: UiColors.textFilter),
|
style: UiTypography.body2b,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Row(
|
Row(
|
||||||
@@ -172,11 +177,13 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
? UiColors.destructive.withValues(alpha: 0.2)
|
? UiColors.destructive.withValues(alpha: 0.2)
|
||||||
: UiColors.primary.withValues(alpha: 0.2),
|
: UiColors.primary.withValues(alpha: 0.2),
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: UiColors.transparent,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
foregroundColor: isDestructive ? UiColors.destructive : UiColors.primary,
|
foregroundColor: isDestructive
|
||||||
|
? UiColors.destructive
|
||||||
|
: UiColors.primary,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
label,
|
label,
|
||||||
@@ -196,16 +203,9 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: UiColors.cardViewBackground,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: Colors.grey.shade100),
|
border: Border.all(color: UiColors.border),
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: UiColors.black.withValues(alpha: 0.05),
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: const Offset(0, 1),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -223,11 +223,7 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
monthYear,
|
monthYear,
|
||||||
style: const TextStyle(
|
style: UiTypography.title2b,
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
_buildNavButton(
|
_buildNavButton(
|
||||||
UiIcons.chevronRight,
|
UiIcons.chevronRight,
|
||||||
@@ -257,10 +253,10 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Color(0xFFF1F5F9), // slate-100
|
color: UiColors.separatorSecondary,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: Icon(icon, size: 20, color: UiColors.mutedForeground),
|
child: Icon(icon, size: 20, color: UiColors.iconSecondary),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -283,26 +279,15 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? UiColors.primary
|
? UiColors.primary
|
||||||
: (isAvailable
|
: (isAvailable ? UiColors.tagSuccess : UiColors.bgSecondary),
|
||||||
? const Color(0xFFECFDF5)
|
|
||||||
: const Color(0xFFF8FAFC)), // emerald-50 or slate-50
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? UiColors.primary
|
? UiColors.primary
|
||||||
: (isAvailable
|
: (isAvailable
|
||||||
? const Color(0xFFA7F3D0)
|
? UiColors.success.withValues(alpha: 0.3)
|
||||||
: Colors.transparent), // emerald-200
|
: UiColors.transparent),
|
||||||
),
|
),
|
||||||
boxShadow: isSelected
|
|
||||||
? [
|
|
||||||
BoxShadow(
|
|
||||||
color: UiColors.primary.withValues(alpha: 0.3),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: const Offset(0, 4),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
@@ -312,26 +297,24 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
day.date.day.toString().padLeft(2, '0'),
|
day.date.day.toString().padLeft(2, '0'),
|
||||||
style: TextStyle(
|
style: UiTypography.title1m.copyWith(
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? UiColors.white
|
? UiColors.white
|
||||||
: (isAvailable
|
: (isAvailable
|
||||||
? const Color(0xFF047857)
|
? UiColors.textSuccess
|
||||||
: UiColors.mutedForeground), // emerald-700
|
: UiColors.textSecondary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
DateFormat('EEE').format(day.date),
|
DateFormat('EEE').format(day.date),
|
||||||
style: TextStyle(
|
style: UiTypography.footnote2r.copyWith(
|
||||||
fontSize: 10,
|
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? UiColors.white.withValues(alpha: 0.8)
|
? UiColors.white.withValues(alpha: 0.8)
|
||||||
: (isAvailable
|
: (isAvailable
|
||||||
? const Color(0xFF047857)
|
? UiColors.textSuccess
|
||||||
: UiColors.mutedForeground),
|
: UiColors.textSecondary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -365,16 +348,9 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: UiColors.cardViewBackground,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: Colors.grey.shade100),
|
border: Border.all(color: UiColors.border),
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: UiColors.black.withValues(alpha: 0.05),
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: const Offset(0, 1),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -387,18 +363,11 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
dateStr,
|
dateStr,
|
||||||
style: const TextStyle(
|
style: UiTypography.title2b,
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
isAvailable ? 'You are available' : 'Not available',
|
isAvailable ? 'You are available' : 'Not available',
|
||||||
style: const TextStyle(
|
style: UiTypography.body2r.textSecondary,
|
||||||
fontSize: 14,
|
|
||||||
color: UiColors.mutedForeground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -430,26 +399,26 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
case 'morning':
|
case 'morning':
|
||||||
return {
|
return {
|
||||||
'icon': UiIcons.sunrise,
|
'icon': UiIcons.sunrise,
|
||||||
'bg': const Color(0xFFE6EBF9), // bg-[#0032A0]/10
|
'bg': UiColors.primary.withValues(alpha: 0.1),
|
||||||
'iconColor': const Color(0xFF0032A0),
|
'iconColor': UiColors.primary,
|
||||||
};
|
};
|
||||||
case 'afternoon':
|
case 'afternoon':
|
||||||
return {
|
return {
|
||||||
'icon': UiIcons.sun,
|
'icon': UiIcons.sun,
|
||||||
'bg': const Color(0xFFCCD6EC), // bg-[#0032A0]/20
|
'bg': UiColors.primary.withValues(alpha: 0.2),
|
||||||
'iconColor': const Color(0xFF0032A0),
|
'iconColor': UiColors.primary,
|
||||||
};
|
};
|
||||||
case 'evening':
|
case 'evening':
|
||||||
return {
|
return {
|
||||||
'icon': UiIcons.moon,
|
'icon': UiIcons.moon,
|
||||||
'bg': const Color(0xFFEBEDEE), // bg-[#333F48]/10
|
'bg': UiColors.bgSecondary,
|
||||||
'iconColor': const Color(0xFF333F48),
|
'iconColor': UiColors.foreground,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
'icon': UiIcons.clock,
|
'icon': UiIcons.clock,
|
||||||
'bg': Colors.grey.shade100,
|
'bg': UiColors.bgSecondary,
|
||||||
'iconColor': Colors.grey,
|
'iconColor': UiColors.iconSecondary,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,14 +438,14 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
Color borderColor;
|
Color borderColor;
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
bgColor = const Color(0xFFF8FAFC); // slate-50
|
bgColor = UiColors.bgSecondary;
|
||||||
borderColor = const Color(0xFFF1F5F9); // slate-100
|
borderColor = UiColors.borderInactive;
|
||||||
} else if (isActive) {
|
} else if (isActive) {
|
||||||
bgColor = UiColors.primary.withValues(alpha: 0.05);
|
bgColor = UiColors.primary.withValues(alpha: 0.05);
|
||||||
borderColor = UiColors.primary.withValues(alpha: 0.2);
|
borderColor = UiColors.primary.withValues(alpha: 0.2);
|
||||||
} else {
|
} else {
|
||||||
bgColor = const Color(0xFFF8FAFC); // slate-50
|
bgColor = UiColors.bgSecondary;
|
||||||
borderColor = const Color(0xFFE2E8F0); // slate-200
|
borderColor = UiColors.borderPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
@@ -485,13 +454,13 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
: UiColors.mutedForeground;
|
: UiColors.mutedForeground;
|
||||||
final subtitleColor = (isEnabled && isActive)
|
final subtitleColor = (isEnabled && isActive)
|
||||||
? UiColors.mutedForeground
|
? UiColors.mutedForeground
|
||||||
: Colors.grey.shade400;
|
: UiColors.textInactive;
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: isEnabled
|
onTap: isEnabled
|
||||||
? () => context.read<AvailabilityBloc>().add(
|
? () => context.read<AvailabilityBloc>().add(
|
||||||
ToggleSlotStatus(day, slot.id),
|
ToggleSlotStatus(day, slot.id),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
@@ -526,15 +495,11 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
slot.label,
|
slot.label,
|
||||||
style: TextStyle(
|
style: UiTypography.body2m.copyWith(color: titleColor),
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: titleColor,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
slot.timeRange,
|
slot.timeRange,
|
||||||
style: TextStyle(fontSize: 12, color: subtitleColor),
|
style: UiTypography.body3r.copyWith(color: subtitleColor),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -548,7 +513,11 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
color: UiColors.primary,
|
color: UiColors.primary,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: const Icon(UiIcons.check, size: 16, color: UiColors.white),
|
child: const Icon(
|
||||||
|
UiIcons.check,
|
||||||
|
size: 16,
|
||||||
|
color: UiColors.white,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
else if (isEnabled && !isActive)
|
else if (isEnabled && !isActive)
|
||||||
Container(
|
Container(
|
||||||
@@ -557,9 +526,9 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: const Color(0xFFCBD5E1),
|
color: UiColors.borderStill,
|
||||||
width: 2,
|
width: 2,
|
||||||
), // slate-300
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -575,27 +544,23 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
color: UiColors.primary.withValues(alpha: 0.05),
|
color: UiColors.primary.withValues(alpha: 0.05),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: const Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 12,
|
||||||
children: [
|
children: [
|
||||||
Icon(UiIcons.clock, size: 20, color: UiColors.primary),
|
const Icon(UiIcons.clock, size: 20, color: UiColors.primary),
|
||||||
SizedBox(width: 12),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Auto-Match uses your availability',
|
'Auto-Match uses your availability',
|
||||||
style: TextStyle(
|
style: UiTypography.body2m,
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 2),
|
|
||||||
Text(
|
Text(
|
||||||
"When enabled, you'll only be matched with shifts during your available times.",
|
"When enabled, you'll only be matched with shifts during your available times.",
|
||||||
style: TextStyle(fontSize: 12, color: UiColors.mutedForeground),
|
style: UiTypography.body3r.textSecondary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -605,4 +570,3 @@ class _AvailabilityPageState extends State<AvailabilityPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,14 +64,6 @@ class _ClockInPageState extends State<ClockInPage> {
|
|||||||
final bool isCheckedIn =
|
final bool isCheckedIn =
|
||||||
state.attendance.isCheckedIn && isActiveSelected;
|
state.attendance.isCheckedIn && isActiveSelected;
|
||||||
|
|
||||||
// Format times for display
|
|
||||||
final String checkInStr = checkInTime != null
|
|
||||||
? DateFormat('h:mm a').format(checkInTime)
|
|
||||||
: '--:-- --';
|
|
||||||
final String checkOutStr = checkOutTime != null
|
|
||||||
? DateFormat('h:mm a').format(checkOutTime)
|
|
||||||
: '--:-- --';
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: UiAppBar(
|
appBar: UiAppBar(
|
||||||
titleWidget: Text(
|
titleWidget: Text(
|
||||||
@@ -117,7 +109,6 @@ class _ClockInPageState extends State<ClockInPage> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
|
|
||||||
// Your Activity Header
|
// Your Activity Header
|
||||||
const Text(
|
const Text(
|
||||||
"Your Activity",
|
"Your Activity",
|
||||||
|
|||||||
Reference in New Issue
Block a user