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

@@ -87,6 +87,27 @@ class ShiftsConnectorRepositoryImpl implements ShiftsConnectorRepository {
final String orderTypeStr = sr.shift.order.orderType.stringValue
.toUpperCase();
final Map<String, dynamic> orderJson = sr.shift.order.toJson();
final DateTime? startDate = _service.toDateTime(orderJson['startDate']);
final DateTime? endDate = _service.toDateTime(orderJson['endDate']);
final String startTime = startDt != null
? DateFormat('HH:mm').format(startDt)
: '';
final String endTime = endDt != null
? DateFormat('HH:mm').format(endDt)
: '';
final List<ShiftSchedule>? schedules = _generateSchedules(
orderType: orderTypeStr,
startDate: startDate,
endDate: endDate,
recurringDays: sr.shift.order.recurringDays,
permanentDays: sr.shift.order.permanentDays,
startTime: startTime,
endTime: endTime,
);
mappedShifts.add(
Shift(
id: sr.shiftId,
@@ -98,14 +119,12 @@ class ShiftsConnectorRepositoryImpl implements ShiftsConnectorRepository {
location: sr.shift.location ?? '',
locationAddress: sr.shift.locationAddress ?? '',
date: shiftDate?.toIso8601String() ?? '',
startTime: startDt != null
? DateFormat('HH:mm').format(startDt)
: '',
endTime: endDt != null ? DateFormat('HH:mm').format(endDt) : '',
startTime: startTime,
endTime: endTime,
createdDate: createdDt?.toIso8601String() ?? '',
status: sr.shift.status?.stringValue.toLowerCase() ?? 'open',
description: sr.shift.description,
durationDays: sr.shift.durationDays,
durationDays: sr.shift.durationDays ?? schedules?.length,
requiredSlots: sr.count,
filledSlots: sr.assigned ?? 0,
latitude: sr.shift.latitude,
@@ -114,6 +133,11 @@ class ShiftsConnectorRepositoryImpl implements ShiftsConnectorRepository {
// FindShiftsTab._groupMultiDayShifts and MyShiftCard._getShiftType.
orderId: sr.shift.orderId,
orderType: orderTypeStr,
startDate: startDate?.toIso8601String(),
endDate: endDate?.toIso8601String(),
recurringDays: sr.shift.order.recurringDays,
permanentDays: sr.shift.order.permanentDays,
schedules: schedules,
breakInfo: BreakAdapter.fromData(
isPaid: sr.isBreakPaid ?? false,
breakTime: sr.breakType?.stringValue,
@@ -611,4 +635,72 @@ class ShiftsConnectorRepositoryImpl implements ShiftsConnectorRepository {
}
});
}
/// Generates a list of [ShiftSchedule] for RECURRING or PERMANENT orders.
List<ShiftSchedule>? _generateSchedules({
required String orderType,
required DateTime? startDate,
required DateTime? endDate,
required List<String>? recurringDays,
required List<String>? permanentDays,
required String startTime,
required String endTime,
}) {
if (orderType != 'RECURRING' && orderType != 'PERMANENT') return null;
if (startDate == null || endDate == null) return null;
final List<String>? daysToInclude = orderType == 'RECURRING'
? recurringDays
: permanentDays;
if (daysToInclude == null || daysToInclude.isEmpty) return null;
final List<ShiftSchedule> schedules = <ShiftSchedule>[];
final Set<int> targetWeekdayIndex = daysToInclude
.map((String day) {
switch (day.toUpperCase()) {
case 'MONDAY':
return DateTime.monday;
case 'TUESDAY':
return DateTime.tuesday;
case 'WEDNESDAY':
return DateTime.wednesday;
case 'THURSDAY':
return DateTime.thursday;
case 'FRIDAY':
return DateTime.friday;
case 'SATURDAY':
return DateTime.saturday;
case 'SUNDAY':
return DateTime.sunday;
default:
return -1;
}
})
.where((int idx) => idx != -1)
.toSet();
DateTime current = startDate;
while (current.isBefore(endDate) ||
current.isAtSameMomentAs(endDate) ||
// Handle cases where the time component might differ slightly by checking date equality
(current.year == endDate.year &&
current.month == endDate.month &&
current.day == endDate.day)) {
if (targetWeekdayIndex.contains(current.weekday)) {
schedules.add(
ShiftSchedule(
date: current.toIso8601String(),
startTime: startTime,
endTime: endTime,
),
);
}
current = current.add(const Duration(days: 1));
// Safety break to prevent infinite loops if dates are messed up
if (schedules.length > 365) break;
}
return schedules;
}
}