correction of change view for recurring and permant - show permanet and recurring in find shift
This commit is contained in:
@@ -227,6 +227,8 @@ class ShiftsRepositoryImpl
|
||||
filledSlots: sr.assigned ?? 0,
|
||||
latitude: sr.shift.latitude,
|
||||
longitude: sr.shift.longitude,
|
||||
orderId: sr.shift.order.id,
|
||||
orderType: sr.shift.order.orderType?.stringValue,
|
||||
breakInfo: BreakAdapter.fromData(
|
||||
isPaid: sr.isBreakPaid ?? false,
|
||||
breakTime: sr.breakType?.stringValue,
|
||||
|
||||
@@ -77,6 +77,13 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
||||
String _getShiftType() {
|
||||
// Handling potential localization key availability
|
||||
try {
|
||||
final String orderType = (widget.shift.orderType ?? '').toUpperCase();
|
||||
if (orderType == 'PERMANENT') {
|
||||
return t.staff_shifts.filter.long_term;
|
||||
}
|
||||
if (orderType == 'RECURRING') {
|
||||
return t.staff_shifts.filter.multi_day;
|
||||
}
|
||||
if (widget.shift.durationDays != null && widget.shift.durationDays! > 30) {
|
||||
return t.staff_shifts.filter.long_term;
|
||||
}
|
||||
@@ -133,6 +140,24 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
||||
statusText = status?.toUpperCase() ?? "";
|
||||
}
|
||||
|
||||
final schedules = widget.shift.schedules ?? <ShiftSchedule>[];
|
||||
final hasSchedules = schedules.isNotEmpty;
|
||||
final List<ShiftSchedule> visibleSchedules = schedules.length <= 5
|
||||
? schedules
|
||||
: schedules.take(3).toList();
|
||||
final int remainingSchedules =
|
||||
schedules.length <= 5 ? 0 : schedules.length - 3;
|
||||
final String scheduleRange = hasSchedules
|
||||
? () {
|
||||
final first = schedules.first.date;
|
||||
final last = schedules.last.date;
|
||||
if (first == last) {
|
||||
return _formatDate(first);
|
||||
}
|
||||
return '${_formatDate(first)} – ${_formatDate(last)}';
|
||||
}()
|
||||
: '';
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Modular.to.pushNamed(
|
||||
@@ -299,7 +324,55 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
|
||||
// Date & Time
|
||||
if (widget.shift.durationDays != null &&
|
||||
if (hasSchedules) ...[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
UiIcons.clock,
|
||||
size: UiConstants.iconXs,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
const SizedBox(width: UiConstants.space1),
|
||||
Text(
|
||||
'${schedules.length} schedules',
|
||||
style: UiTypography.footnote2m.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: UiConstants.space1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Text(
|
||||
scheduleRange,
|
||||
style: UiTypography.footnote2r.copyWith(color: UiColors.primary),
|
||||
),
|
||||
),
|
||||
...visibleSchedules.map(
|
||||
(schedule) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Text(
|
||||
'${_formatDate(schedule.date)}, ${_formatTime(schedule.startTime)} – ${_formatTime(schedule.endTime)}',
|
||||
style: UiTypography.footnote2r.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (remainingSchedules > 0)
|
||||
Text(
|
||||
'+$remainingSchedules more schedules',
|
||||
style: UiTypography.footnote2r.copyWith(
|
||||
color: UiColors.primary.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
] else if (widget.shift.durationDays != null &&
|
||||
widget.shift.durationDays! > 1) ...[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -324,17 +397,22 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Text(
|
||||
'${_formatDate(widget.shift.date)}, ${_formatTime(widget.shift.startTime)} – ${_formatTime(widget.shift.endTime)}',
|
||||
style: UiTypography.footnote2r.copyWith(color: UiColors.primary),
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Text(
|
||||
'${_formatDate(widget.shift.date)}, ${_formatTime(widget.shift.startTime)} – ${_formatTime(widget.shift.endTime)}',
|
||||
style: UiTypography.footnote2r.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.shift.durationDays! > 1)
|
||||
Text(
|
||||
'... +${widget.shift.durationDays! - 1} more days',
|
||||
style: UiTypography.footnote2r.copyWith(color: UiColors.primary.withOpacity(0.7)),
|
||||
)
|
||||
Text(
|
||||
'... +${widget.shift.durationDays! - 1} more days',
|
||||
style: UiTypography.footnote2r.copyWith(
|
||||
color:
|
||||
UiColors.primary.withOpacity(0.7),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
] else ...[
|
||||
|
||||
@@ -20,6 +20,119 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
|
||||
String _searchQuery = '';
|
||||
String _jobType = 'all';
|
||||
|
||||
bool _isRecurring(Shift shift) =>
|
||||
(shift.orderType ?? '').toUpperCase() == 'RECURRING';
|
||||
|
||||
bool _isPermanent(Shift shift) =>
|
||||
(shift.orderType ?? '').toUpperCase() == 'PERMANENT';
|
||||
|
||||
DateTime? _parseShiftDate(String date) {
|
||||
if (date.isEmpty) return null;
|
||||
try {
|
||||
return DateTime.parse(date);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<Shift> _groupMultiDayShifts(List<Shift> shifts) {
|
||||
final Map<String, List<Shift>> grouped = <String, List<Shift>>{};
|
||||
for (final shift in shifts) {
|
||||
if (!_isRecurring(shift) && !_isPermanent(shift)) {
|
||||
continue;
|
||||
}
|
||||
final orderId = shift.orderId;
|
||||
final roleId = shift.roleId;
|
||||
if (orderId == null || roleId == null) {
|
||||
continue;
|
||||
}
|
||||
final key = '$orderId::$roleId';
|
||||
grouped.putIfAbsent(key, () => <Shift>[]).add(shift);
|
||||
}
|
||||
|
||||
final Set<String> addedGroups = <String>{};
|
||||
final List<Shift> result = <Shift>[];
|
||||
|
||||
for (final shift in shifts) {
|
||||
if (!_isRecurring(shift) && !_isPermanent(shift)) {
|
||||
result.add(shift);
|
||||
continue;
|
||||
}
|
||||
final orderId = shift.orderId;
|
||||
final roleId = shift.roleId;
|
||||
if (orderId == null || roleId == null) {
|
||||
result.add(shift);
|
||||
continue;
|
||||
}
|
||||
final key = '$orderId::$roleId';
|
||||
if (addedGroups.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
addedGroups.add(key);
|
||||
final List<Shift> group = grouped[key] ?? <Shift>[];
|
||||
if (group.isEmpty) {
|
||||
result.add(shift);
|
||||
continue;
|
||||
}
|
||||
group.sort((a, b) {
|
||||
final ad = _parseShiftDate(a.date);
|
||||
final bd = _parseShiftDate(b.date);
|
||||
if (ad == null && bd == null) return 0;
|
||||
if (ad == null) return 1;
|
||||
if (bd == null) return -1;
|
||||
return ad.compareTo(bd);
|
||||
});
|
||||
|
||||
final Shift first = group.first;
|
||||
final List<ShiftSchedule> schedules = group
|
||||
.map((s) => ShiftSchedule(
|
||||
date: s.date,
|
||||
startTime: s.startTime,
|
||||
endTime: s.endTime,
|
||||
))
|
||||
.toList();
|
||||
|
||||
result.add(
|
||||
Shift(
|
||||
id: first.id,
|
||||
roleId: first.roleId,
|
||||
title: first.title,
|
||||
clientName: first.clientName,
|
||||
logoUrl: first.logoUrl,
|
||||
hourlyRate: first.hourlyRate,
|
||||
location: first.location,
|
||||
locationAddress: first.locationAddress,
|
||||
date: first.date,
|
||||
startTime: first.startTime,
|
||||
endTime: first.endTime,
|
||||
createdDate: first.createdDate,
|
||||
tipsAvailable: first.tipsAvailable,
|
||||
travelTime: first.travelTime,
|
||||
mealProvided: first.mealProvided,
|
||||
parkingAvailable: first.parkingAvailable,
|
||||
gasCompensation: first.gasCompensation,
|
||||
description: first.description,
|
||||
instructions: first.instructions,
|
||||
managers: first.managers,
|
||||
latitude: first.latitude,
|
||||
longitude: first.longitude,
|
||||
status: first.status,
|
||||
durationDays: schedules.length,
|
||||
requiredSlots: first.requiredSlots,
|
||||
filledSlots: first.filledSlots,
|
||||
hasApplied: first.hasApplied,
|
||||
totalValue: first.totalValue,
|
||||
breakInfo: first.breakInfo,
|
||||
orderId: first.orderId,
|
||||
orderType: first.orderType,
|
||||
schedules: schedules,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Widget _buildFilterTab(String id, String label) {
|
||||
final isSelected = _jobType == id;
|
||||
return GestureDetector(
|
||||
@@ -49,8 +162,10 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final groupedJobs = _groupMultiDayShifts(widget.availableJobs);
|
||||
|
||||
// Filter logic
|
||||
final filteredJobs = widget.availableJobs.where((s) {
|
||||
final filteredJobs = groupedJobs.where((s) {
|
||||
final matchesSearch =
|
||||
s.title.toLowerCase().contains(_searchQuery.toLowerCase()) ||
|
||||
s.location.toLowerCase().contains(_searchQuery.toLowerCase()) ||
|
||||
@@ -60,10 +175,15 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
|
||||
|
||||
if (_jobType == 'all') return true;
|
||||
if (_jobType == 'one-day') {
|
||||
if (_isRecurring(s) || _isPermanent(s)) return false;
|
||||
return s.durationDays == null || s.durationDays! <= 1;
|
||||
}
|
||||
if (_jobType == 'multi-day') {
|
||||
return s.durationDays != null && s.durationDays! > 1;
|
||||
return _isRecurring(s) ||
|
||||
(s.durationDays != null && s.durationDays! > 1);
|
||||
}
|
||||
if (_jobType == 'long-term') {
|
||||
return _isPermanent(s);
|
||||
}
|
||||
return true;
|
||||
}).toList();
|
||||
|
||||
Reference in New Issue
Block a user