feat: Refactor ClockInPage for improved readability and consistency in code formatting
This commit is contained in:
@@ -33,7 +33,9 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(context).staff.clock_in;
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(
|
||||
context,
|
||||
).staff.clock_in;
|
||||
return BlocProvider<ClockInBloc>.value(
|
||||
value: _bloc,
|
||||
child: BlocConsumer<ClockInBloc, ClockInState>(
|
||||
@@ -60,22 +62,17 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
final String? activeShiftId = state.attendance.activeShiftId;
|
||||
final bool isActiveSelected =
|
||||
selectedShift != null && selectedShift.id == activeShiftId;
|
||||
final DateTime? checkInTime =
|
||||
isActiveSelected ? state.attendance.checkInTime : null;
|
||||
final DateTime? checkOutTime =
|
||||
isActiveSelected ? state.attendance.checkOutTime : null;
|
||||
final DateTime? checkInTime = isActiveSelected
|
||||
? state.attendance.checkInTime
|
||||
: null;
|
||||
final DateTime? checkOutTime = isActiveSelected
|
||||
? state.attendance.checkOutTime
|
||||
: null;
|
||||
final bool isCheckedIn =
|
||||
state.attendance.isCheckedIn && isActiveSelected;
|
||||
|
||||
return Scaffold(
|
||||
appBar: UiAppBar(
|
||||
titleWidget: Text(
|
||||
i18n.title,
|
||||
style: UiTypography.title1m.textPrimary,
|
||||
),
|
||||
showBackButton: false,
|
||||
centerTitle: false,
|
||||
),
|
||||
appBar: UiAppBar(title: i18n.title, showBackButton: false),
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(
|
||||
@@ -141,17 +138,14 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.white,
|
||||
borderRadius:
|
||||
UiConstants.radiusLg,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
border: Border.all(
|
||||
color: shift.id ==
|
||||
selectedShift?.id
|
||||
color: shift.id == selectedShift?.id
|
||||
? UiColors.primary
|
||||
: UiColors.border,
|
||||
width:
|
||||
shift.id == selectedShift?.id
|
||||
? 2
|
||||
: 1,
|
||||
width: shift.id == selectedShift?.id
|
||||
? 2
|
||||
: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -163,23 +157,23 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
shift.id ==
|
||||
selectedShift?.id
|
||||
? i18n
|
||||
.selected_shift_badge
|
||||
: i18n
|
||||
.today_shift_badge,
|
||||
style: UiTypography
|
||||
.titleUppercase4b
|
||||
.copyWith(
|
||||
color: shift.id ==
|
||||
selectedShift?.id
|
||||
? UiColors.primary
|
||||
: UiColors
|
||||
.textSecondary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
shift.id ==
|
||||
selectedShift?.id
|
||||
? i18n.selected_shift_badge
|
||||
: i18n.today_shift_badge,
|
||||
style: UiTypography
|
||||
.titleUppercase4b
|
||||
.copyWith(
|
||||
color:
|
||||
shift.id ==
|
||||
selectedShift
|
||||
?.id
|
||||
? UiColors.primary
|
||||
: UiColors
|
||||
.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
shift.title,
|
||||
@@ -187,7 +181,8 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
),
|
||||
Text(
|
||||
"${shift.clientName} • ${shift.location}",
|
||||
style: UiTypography.body3r
|
||||
style: UiTypography
|
||||
.body3r
|
||||
.textSecondary,
|
||||
),
|
||||
],
|
||||
@@ -199,15 +194,16 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"${_formatTime(shift.startTime)} - ${_formatTime(shift.endTime)}",
|
||||
style: UiTypography.body3m
|
||||
style: UiTypography
|
||||
.body3m
|
||||
.textSecondary,
|
||||
),
|
||||
Text(
|
||||
"\$${shift.hourlyRate}/hr",
|
||||
style: UiTypography.body3m
|
||||
.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -226,8 +222,9 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
!_isCheckInAllowed(selectedShift))
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding:
|
||||
const EdgeInsets.all(UiConstants.space6),
|
||||
padding: const EdgeInsets.all(
|
||||
UiConstants.space6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.bgSecondary,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
@@ -261,8 +258,12 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
// Attire Photo Section
|
||||
if (!isCheckedIn) ...<Widget>[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(UiConstants.space4),
|
||||
margin: const EdgeInsets.only(bottom: UiConstants.space4),
|
||||
padding: const EdgeInsets.all(
|
||||
UiConstants.space4,
|
||||
),
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: UiConstants.space4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.white,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
@@ -277,15 +278,27 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
color: UiColors.bgSecondary,
|
||||
borderRadius: UiConstants.radiusMd,
|
||||
),
|
||||
child: const Icon(UiIcons.camera, color: UiColors.primary),
|
||||
child: const Icon(
|
||||
UiIcons.camera,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(i18n.attire_photo_label, style: UiTypography.body2b),
|
||||
Text(i18n.attire_photo_desc, style: UiTypography.body3r.textSecondary),
|
||||
Text(
|
||||
i18n.attire_photo_label,
|
||||
style: UiTypography.body2b,
|
||||
),
|
||||
Text(
|
||||
i18n.attire_photo_desc,
|
||||
style: UiTypography
|
||||
.body3r
|
||||
.textSecondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -303,25 +316,38 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
if (!isCheckedIn && (!state.isLocationVerified || state.currentLocation == null)) ...<Widget>[
|
||||
|
||||
if (!isCheckedIn &&
|
||||
(!state.isLocationVerified ||
|
||||
state.currentLocation ==
|
||||
null)) ...<Widget>[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(UiConstants.space4),
|
||||
margin: const EdgeInsets.only(bottom: UiConstants.space4),
|
||||
padding: const EdgeInsets.all(
|
||||
UiConstants.space4,
|
||||
),
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: UiConstants.space4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.tagError,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(UiIcons.error, color: UiColors.textError, size: 20),
|
||||
const Icon(
|
||||
UiIcons.error,
|
||||
color: UiColors.textError,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
Expanded(
|
||||
child: Text(
|
||||
state.currentLocation == null
|
||||
? i18n.location_verifying
|
||||
: i18n.not_in_range(distance: '500'),
|
||||
state.currentLocation == null
|
||||
? i18n.location_verifying
|
||||
: i18n.not_in_range(
|
||||
distance: '500',
|
||||
),
|
||||
style: UiTypography.body3m.textError,
|
||||
),
|
||||
),
|
||||
@@ -333,7 +359,8 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
SwipeToCheckIn(
|
||||
isCheckedIn: isCheckedIn,
|
||||
mode: state.checkInMode,
|
||||
isDisabled: !isCheckedIn && !state.isLocationVerified,
|
||||
isDisabled:
|
||||
!isCheckedIn && !state.isLocationVerified,
|
||||
isLoading:
|
||||
state.status ==
|
||||
ClockInStatus.actionInProgress,
|
||||
@@ -554,7 +581,9 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
}
|
||||
|
||||
Future<void> _showNFCDialog(BuildContext context) async {
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(context).staff.clock_in;
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(
|
||||
context,
|
||||
).staff.clock_in;
|
||||
bool scanned = false;
|
||||
|
||||
// Using a local navigator context since we are in a dialog
|
||||
@@ -668,8 +697,14 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
try {
|
||||
final List<String> parts = timeStr.split(':');
|
||||
if (parts.length >= 2) {
|
||||
final DateTime dt = DateTime(2022, 1, 1, int.parse(parts[0]), int.parse(parts[1]));
|
||||
return DateFormat('h:mm a').format(dt);
|
||||
final DateTime dt = DateTime(
|
||||
2022,
|
||||
1,
|
||||
1,
|
||||
int.parse(parts[0]),
|
||||
int.parse(parts[1]),
|
||||
);
|
||||
return DateFormat('h:mm a').format(dt);
|
||||
}
|
||||
return timeStr;
|
||||
} catch (e) {
|
||||
@@ -683,7 +718,9 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
// Parse shift date (e.g. 2024-01-31T09:00:00)
|
||||
// The Shift entity has 'date' which is the start DateTime string
|
||||
final DateTime shiftStart = DateTime.parse(shift.startTime);
|
||||
final DateTime windowStart = shiftStart.subtract(const Duration(minutes: 15));
|
||||
final DateTime windowStart = shiftStart.subtract(
|
||||
const Duration(minutes: 15),
|
||||
);
|
||||
return DateTime.now().isAfter(windowStart);
|
||||
} catch (e) {
|
||||
// Fallback: If parsing fails, allow check in to avoid blocking.
|
||||
@@ -692,15 +729,17 @@ class _ClockInPageState extends State<ClockInPage> {
|
||||
}
|
||||
|
||||
String _getCheckInAvailabilityTime(Shift shift) {
|
||||
try {
|
||||
final DateTime shiftStart = DateTime.parse(shift.startTime.trim());
|
||||
final DateTime windowStart = shiftStart.subtract(const Duration(minutes: 15));
|
||||
return DateFormat('h:mm a').format(windowStart);
|
||||
} catch (e) {
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(context).staff.clock_in;
|
||||
return i18n.soon;
|
||||
}
|
||||
try {
|
||||
final DateTime shiftStart = DateTime.parse(shift.startTime.trim());
|
||||
final DateTime windowStart = shiftStart.subtract(
|
||||
const Duration(minutes: 15),
|
||||
);
|
||||
return DateFormat('h:mm a').format(windowStart);
|
||||
} catch (e) {
|
||||
final TranslationsStaffClockInEn i18n = Translations.of(
|
||||
context,
|
||||
).staff.clock_in;
|
||||
return i18n.soon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user