feat: Add support for displaying recurring shift details including start/end dates and recurring days.

This commit is contained in:
Achintha Isuru
2026-02-22 15:15:41 -05:00
parent 415475acb6
commit 6e81d403c3
6 changed files with 172 additions and 45 deletions

View File

@@ -116,8 +116,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
);
}
final Shift displayShift =
state is ShiftDetailsLoaded ? state.shift : widget.shift;
final Shift displayShift = state is ShiftDetailsLoaded
? state.shift
: widget.shift;
final i18n = Translations.of(context).staff_shifts.shift_details;
final duration = _calculateDuration(displayShift);
@@ -154,6 +155,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
shiftDateLabel: i18n.shift_date,
clockInLabel: i18n.start_time,
clockOutLabel: i18n.end_time,
startDate: displayShift.startDate,
endDate: displayShift.endDate,
recurringDays: displayShift.recurringDays,
permanentDays: displayShift.permanentDays,
),
const Divider(height: 1, thickness: 0.5),
if (displayShift.breakInfo != null &&

View File

@@ -342,31 +342,31 @@ class _MyShiftCardState extends State<MyShiftCard> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
UiIcons.clock,
size: UiConstants.iconXs,
color: UiColors.primary,
color: UiColors.iconSecondary,
),
const SizedBox(width: UiConstants.space1),
Text(
'${schedules.length} schedules',
style: UiTypography.footnote2m.copyWith(
color: UiColors.primary,
),
scheduleRange,
style:
UiTypography.footnote2r.textSecondary,
),
],
),
const SizedBox(height: UiConstants.space1),
Padding(
padding: const EdgeInsets.only(bottom: 2),
child: Text(
scheduleRange,
style: UiTypography.footnote2r.copyWith(
color: UiColors.primary,
),
const SizedBox(height: UiConstants.space2),
Text(
'${schedules.length} schedules',
style: UiTypography.footnote2m.copyWith(
color: UiColors.primary,
),
),
const SizedBox(height: UiConstants.space1),
...visibleSchedules.map(
(schedule) => Padding(
padding: const EdgeInsets.only(bottom: 2),

View File

@@ -6,19 +6,19 @@ import 'package:intl/intl.dart';
class ShiftDateTimeSection extends StatelessWidget {
/// The ISO string of the date.
final String date;
/// The start time string (HH:mm).
final String startTime;
/// The end time string (HH:mm).
final String endTime;
/// Localization string for shift date.
final String shiftDateLabel;
/// Localization string for clock in time.
final String clockInLabel;
/// Localization string for clock out time.
final String clockOutLabel;
@@ -31,8 +31,17 @@ class ShiftDateTimeSection extends StatelessWidget {
required this.shiftDateLabel,
required this.clockInLabel,
required this.clockOutLabel,
this.startDate,
this.endDate,
this.recurringDays,
this.permanentDays,
});
final String? startDate;
final String? endDate;
final List<String>? recurringDays;
final List<String>? permanentDays;
String _formatTime(String time) {
if (time.isEmpty) return '';
try {
@@ -70,34 +79,41 @@ class ShiftDateTimeSection extends StatelessWidget {
const SizedBox(height: UiConstants.space2),
Row(
children: [
const Icon(
UiIcons.calendar,
size: 20,
color: UiColors.primary,
),
const Icon(UiIcons.calendar, size: 20, color: UiColors.primary),
const SizedBox(width: UiConstants.space2),
Text(
_formatDate(date),
style: UiTypography.headline5m.textPrimary,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
startDate != null && endDate != null
? '${DateFormat('MMM d, y').format(DateTime.parse(startDate!))} ${DateFormat('MMM d, y').format(DateTime.parse(endDate!))}'
: _formatDate(date),
style: UiTypography.headline5m.textPrimary,
),
if (recurringDays != null || permanentDays != null) ...[
const SizedBox(height: 4),
Text(
(recurringDays ?? permanentDays ?? [])
.map(
(d) =>
'${d[0].toUpperCase()}${d.substring(1, 3).toLowerCase()}',
)
.join(', '),
style: UiTypography.footnote2r.textSecondary,
),
],
],
),
),
],
),
const SizedBox(height: UiConstants.space4),
Row(
children: [
Expanded(
child: _buildTimeBox(
clockInLabel,
startTime,
),
),
Expanded(child: _buildTimeBox(clockInLabel, startTime)),
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildTimeBox(
clockOutLabel,
endTime,
),
),
Expanded(child: _buildTimeBox(clockOutLabel, endTime)),
],
),
],