From 8b6061cb3086034fdebbcb839765a469659b7d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:23:15 -0500 Subject: [PATCH 1/6] correction of change view for recurring and permant - show permanet and recurring in find shift --- .../domain/lib/src/entities/shifts/shift.dart | 24 ++++ .../permanent_order/permanent_order_view.dart | 42 +++++- .../recurring_order/recurring_order_view.dart | 48 ++++++- .../shifts_repository_impl.dart | 2 + .../presentation/widgets/my_shift_card.dart | 96 ++++++++++++-- .../widgets/tabs/find_shifts_tab.dart | 124 +++++++++++++++++- 6 files changed, 323 insertions(+), 13 deletions(-) diff --git a/apps/mobile/packages/domain/lib/src/entities/shifts/shift.dart b/apps/mobile/packages/domain/lib/src/entities/shifts/shift.dart index e24d6477..f3fb278e 100644 --- a/apps/mobile/packages/domain/lib/src/entities/shifts/shift.dart +++ b/apps/mobile/packages/domain/lib/src/entities/shifts/shift.dart @@ -31,6 +31,9 @@ class Shift extends Equatable { final bool? hasApplied; final double? totalValue; final Break? breakInfo; + final String? orderId; + final String? orderType; + final List? schedules; const Shift({ required this.id, @@ -62,6 +65,9 @@ class Shift extends Equatable { this.hasApplied, this.totalValue, this.breakInfo, + this.orderId, + this.orderType, + this.schedules, }); @override @@ -95,9 +101,27 @@ class Shift extends Equatable { hasApplied, totalValue, breakInfo, + orderId, + orderType, + schedules, ]; } +class ShiftSchedule extends Equatable { + const ShiftSchedule({ + required this.date, + required this.startTime, + required this.endTime, + }); + + final String date; + final String startTime; + final String endTime; + + @override + List get props => [date, startTime, endTime]; +} + class ShiftManager extends Equatable { const ShiftManager({required this.name, required this.phone, this.avatar}); diff --git a/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/permanent_order/permanent_order_view.dart b/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/permanent_order/permanent_order_view.dart index 888bd150..c5041687 100644 --- a/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/permanent_order/permanent_order_view.dart +++ b/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/permanent_order/permanent_order_view.dart @@ -20,6 +20,42 @@ class PermanentOrderView extends StatelessWidget { /// Creates a [PermanentOrderView]. const PermanentOrderView({super.key}); + DateTime _firstPermanentShiftDate( + DateTime startDate, + List permanentDays, + ) { + final DateTime start = DateTime(startDate.year, startDate.month, startDate.day); + final DateTime end = start.add(const Duration(days: 29)); + final Set selected = permanentDays.toSet(); + for (DateTime day = start; !day.isAfter(end); day = day.add(const Duration(days: 1))) { + if (selected.contains(_weekdayLabel(day))) { + return day; + } + } + return start; + } + + String _weekdayLabel(DateTime date) { + switch (date.weekday) { + case DateTime.monday: + return 'MON'; + case DateTime.tuesday: + return 'TUE'; + case DateTime.wednesday: + return 'WED'; + case DateTime.thursday: + return 'THU'; + case DateTime.friday: + return 'FRI'; + case DateTime.saturday: + return 'SAT'; + case DateTime.sunday: + return 'SUN'; + default: + return 'SUN'; + } + } + @override Widget build(BuildContext context) { final TranslationsClientCreateOrderPermanentEn labels = @@ -42,6 +78,10 @@ class PermanentOrderView extends StatelessWidget { }, builder: (BuildContext context, PermanentOrderState state) { if (state.status == PermanentOrderStatus.success) { + final DateTime initialDate = _firstPermanentShiftDate( + state.startDate, + state.permanentDays, + ); return PermanentOrderSuccessView( title: labels.title, message: labels.subtitle, @@ -50,7 +90,7 @@ class PermanentOrderView extends StatelessWidget { ClientPaths.orders, (_) => false, arguments: { - 'initialDate': state.startDate.toIso8601String(), + 'initialDate': initialDate.toIso8601String(), }, ), ); diff --git a/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/recurring_order/recurring_order_view.dart b/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/recurring_order/recurring_order_view.dart index 89a20519..a6f173c8 100644 --- a/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/recurring_order/recurring_order_view.dart +++ b/apps/mobile/packages/features/client/create_order/lib/src/presentation/widgets/recurring_order/recurring_order_view.dart @@ -20,6 +20,43 @@ class RecurringOrderView extends StatelessWidget { /// Creates a [RecurringOrderView]. const RecurringOrderView({super.key}); + DateTime _firstRecurringShiftDate( + DateTime startDate, + DateTime endDate, + List recurringDays, + ) { + final DateTime start = DateTime(startDate.year, startDate.month, startDate.day); + final DateTime end = DateTime(endDate.year, endDate.month, endDate.day); + final Set selected = recurringDays.toSet(); + for (DateTime day = start; !day.isAfter(end); day = day.add(const Duration(days: 1))) { + if (selected.contains(_weekdayLabel(day))) { + return day; + } + } + return start; + } + + String _weekdayLabel(DateTime date) { + switch (date.weekday) { + case DateTime.monday: + return 'MON'; + case DateTime.tuesday: + return 'TUE'; + case DateTime.wednesday: + return 'WED'; + case DateTime.thursday: + return 'THU'; + case DateTime.friday: + return 'FRI'; + case DateTime.saturday: + return 'SAT'; + case DateTime.sunday: + return 'SUN'; + default: + return 'SUN'; + } + } + @override Widget build(BuildContext context) { final TranslationsClientCreateOrderRecurringEn labels = @@ -44,6 +81,15 @@ class RecurringOrderView extends StatelessWidget { }, builder: (BuildContext context, RecurringOrderState state) { if (state.status == RecurringOrderStatus.success) { + final DateTime maxEndDate = + state.startDate.add(const Duration(days: 29)); + final DateTime effectiveEndDate = + state.endDate.isAfter(maxEndDate) ? maxEndDate : state.endDate; + final DateTime initialDate = _firstRecurringShiftDate( + state.startDate, + effectiveEndDate, + state.recurringDays, + ); return RecurringOrderSuccessView( title: labels.title, message: labels.subtitle, @@ -52,7 +98,7 @@ class RecurringOrderView extends StatelessWidget { ClientPaths.orders, (_) => false, arguments: { - 'initialDate': state.startDate.toIso8601String(), + 'initialDate': initialDate.toIso8601String(), }, ), ); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart b/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart index 8be4f612..53667bde 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart @@ -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, diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart index 86352524..f34b405b 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart @@ -77,6 +77,13 @@ class _MyShiftCardState extends State { 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 { statusText = status?.toUpperCase() ?? ""; } + final schedules = widget.shift.schedules ?? []; + final hasSchedules = schedules.isNotEmpty; + final List 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 { 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 { ), 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 ...[ diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart index bb426fd7..81e6ac03 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart @@ -20,6 +20,119 @@ class _FindShiftsTabState extends State { 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 _groupMultiDayShifts(List shifts) { + final Map> grouped = >{}; + 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, () => []).add(shift); + } + + final Set addedGroups = {}; + final List result = []; + + 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 group = grouped[key] ?? []; + 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 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 { @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 { 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(); From fe28396a5854a1ffaa9ad6298c06e58e426ee406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:34:58 -0500 Subject: [PATCH 2/6] adding tag type for shifts --- .../lib/src/presentation/widgets/my_shift_card.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart index f34b405b..03f20b49 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/my_shift_card.dart @@ -216,8 +216,8 @@ class _MyShiftCardState extends State { letterSpacing: 0.5, ), ), - // Shift Type Badge - if (status == 'open' || status == 'pending') ...[ + // Shift Type Badge (Order type) + if ((widget.shift.orderType ?? '').isNotEmpty) ...[ const SizedBox(width: UiConstants.space2), Container( padding: const EdgeInsets.symmetric( @@ -225,13 +225,14 @@ class _MyShiftCardState extends State { vertical: 2, ), decoration: BoxDecoration( - color: UiColors.primary.withValues(alpha: 0.1), + color: UiColors.background, borderRadius: UiConstants.radiusSm, + border: Border.all(color: UiColors.border), ), child: Text( _getShiftType(), style: UiTypography.footnote2m.copyWith( - color: UiColors.primary, + color: UiColors.textSecondary, ), ), ), From ed854cb95893f10bf1089b0e63edaba14501f919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Thu, 19 Feb 2026 11:00:55 -0500 Subject: [PATCH 3/6] solving problem with apply button --- .../core/lib/src/routing/staff/navigator.dart | 9 ++++++- .../blocs/shifts/shifts_bloc.dart | 10 ++++++-- .../blocs/shifts/shifts_event.dart | 8 ++++++- .../pages/shift_details_page.dart | 9 +++++-- .../src/presentation/pages/shifts_page.dart | 24 +++++++++++++++++-- .../shifts/lib/src/staff_shifts_module.dart | 1 + 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart b/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart index 3ba4a8ea..0f624872 100644 --- a/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart +++ b/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart @@ -98,7 +98,11 @@ extension StaffNavigator on IModularNavigator { /// Parameters: /// * [selectedDate] - Optional date to pre-select in the shifts view /// * [initialTab] - Optional initial tab (via query parameter) - void toShifts({DateTime? selectedDate, String? initialTab}) { + void toShifts({ + DateTime? selectedDate, + String? initialTab, + bool? refreshAvailable, + }) { final Map args = {}; if (selectedDate != null) { args['selectedDate'] = selectedDate; @@ -106,6 +110,9 @@ extension StaffNavigator on IModularNavigator { if (initialTab != null) { args['initialTab'] = initialTab; } + if (refreshAvailable == true) { + args['refreshAvailable'] = true; + } navigate( StaffPaths.shifts, arguments: args.isEmpty ? null : args, diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart index 6a8c1c43..e6e0fe97 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart @@ -108,9 +108,15 @@ class ShiftsBloc extends Bloc ) async { final currentState = state; if (currentState is! ShiftsLoaded) return; - if (currentState.availableLoading || currentState.availableLoaded) return; + if (!event.force && + (currentState.availableLoading || currentState.availableLoaded)) { + return; + } - emit(currentState.copyWith(availableLoading: true)); + emit(currentState.copyWith( + availableLoading: true, + availableLoaded: false, + )); await handleError( emit: emit, action: () async { diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart index d25866e0..55ea9fd1 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart @@ -12,7 +12,13 @@ class LoadShiftsEvent extends ShiftsEvent {} class LoadHistoryShiftsEvent extends ShiftsEvent {} -class LoadAvailableShiftsEvent extends ShiftsEvent {} +class LoadAvailableShiftsEvent extends ShiftsEvent { + final bool force; + const LoadAvailableShiftsEvent({this.force = false}); + + @override + List get props => [force]; +} class LoadFindFirstEvent extends ShiftsEvent {} diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart index e4563de1..b2a17a60 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart @@ -93,7 +93,11 @@ class _ShiftDetailsPageState extends State { message: state.message, type: UiSnackbarType.success, ); - Modular.to.toShifts(selectedDate: state.shiftDate); + Modular.to.toShifts( + selectedDate: state.shiftDate, + initialTab: 'find', + refreshAvailable: true, + ); } else if (state is ShiftDetailsError) { if (_isApplying) { UiSnackbar.show( @@ -112,7 +116,8 @@ class _ShiftDetailsPageState extends State { ); } - Shift displayShift = 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); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart index 32ffc356..13776407 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart @@ -12,7 +12,13 @@ import '../widgets/tabs/history_shifts_tab.dart'; class ShiftsPage extends StatefulWidget { final String? initialTab; final DateTime? selectedDate; - const ShiftsPage({super.key, this.initialTab, this.selectedDate}); + final bool refreshAvailable; + const ShiftsPage({ + super.key, + this.initialTab, + this.selectedDate, + this.refreshAvailable = false, + }); @override State createState() => _ShiftsPageState(); @@ -22,6 +28,8 @@ class _ShiftsPageState extends State { late String _activeTab; DateTime? _selectedDate; bool _prioritizeFind = false; + bool _refreshAvailable = false; + bool _pendingAvailableRefresh = false; final ShiftsBloc _bloc = Modular.get(); @override @@ -30,6 +38,8 @@ class _ShiftsPageState extends State { _activeTab = widget.initialTab ?? 'myshifts'; _selectedDate = widget.selectedDate; _prioritizeFind = widget.initialTab == 'find'; + _refreshAvailable = widget.refreshAvailable; + _pendingAvailableRefresh = widget.refreshAvailable; if (_prioritizeFind) { _bloc.add(LoadFindFirstEvent()); } else { @@ -40,7 +50,9 @@ class _ShiftsPageState extends State { } if (_activeTab == 'find') { if (!_prioritizeFind) { - _bloc.add(LoadAvailableShiftsEvent()); + _bloc.add( + LoadAvailableShiftsEvent(force: _refreshAvailable), + ); } } } @@ -59,6 +71,10 @@ class _ShiftsPageState extends State { _selectedDate = widget.selectedDate; }); } + if (widget.refreshAvailable) { + _refreshAvailable = true; + _pendingAvailableRefresh = true; + } } @override @@ -77,6 +93,10 @@ class _ShiftsPageState extends State { } }, builder: (context, state) { + if (_pendingAvailableRefresh && state is ShiftsLoaded) { + _pendingAvailableRefresh = false; + _bloc.add(const LoadAvailableShiftsEvent(force: true)); + } final bool baseLoaded = state is ShiftsLoaded; final List myShifts = (state is ShiftsLoaded) ? state.myShifts diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart b/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart index 02bade2c..16518dcb 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart @@ -46,6 +46,7 @@ class StaffShiftsModule extends Module { return ShiftsPage( initialTab: queryParams['tab'] ?? args?['initialTab'], selectedDate: args?['selectedDate'], + refreshAvailable: args?['refreshAvailable'] == true, ); }, ); From d160610bf9f3e55f7f23b14fa2f62e949ff19ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:37:26 -0500 Subject: [PATCH 4/6] deleting few values of shift enum --- backend/dataconnect/connector/shiftRole/queries.gql | 4 ++-- backend/dataconnect/functions/seed.gql | 8 ++++---- backend/dataconnect/schema/shift.gql | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/backend/dataconnect/connector/shiftRole/queries.gql b/backend/dataconnect/connector/shiftRole/queries.gql index 07720bf0..6795e79d 100644 --- a/backend/dataconnect/connector/shiftRole/queries.gql +++ b/backend/dataconnect/connector/shiftRole/queries.gql @@ -254,7 +254,7 @@ query listShiftRolesByVendorId( shiftRoles( where: { shift: { - status: {in: [IN_PROGRESS, CONFIRMED, ASSIGNED, OPEN, PENDING]} #IN_PROGRESS? PENDING? + status: {in: [IN_PROGRESS, ASSIGNED, OPEN]} #IN_PROGRESS? order: { vendorId: { eq: $vendorId } } @@ -511,7 +511,7 @@ query getCompletedShiftsByBusinessId( shifts( where: { order: { businessId: { eq: $businessId } } - status: {in: [IN_PROGRESS, CONFIRMED, COMPLETED, OPEN]} + status: {in: [IN_PROGRESS, COMPLETED, OPEN]} date: { ge: $dateFrom, le: $dateTo } } offset: $offset diff --git a/backend/dataconnect/functions/seed.gql b/backend/dataconnect/functions/seed.gql index 8c6b69c0..1c6e0fcd 100644 --- a/backend/dataconnect/functions/seed.gql +++ b/backend/dataconnect/functions/seed.gql @@ -927,7 +927,7 @@ mutation seedAll @transaction { placeId: "Eiw0MDAwIFNhbiBKb3NlIFN0cmVldCwgR3JhbmFkYSBIaWxscywgQ0EsIFVTQSIuKiwKFAoSCYNJZBTdmsKAEddGOfBj8LvTEhQKEglnNXI0zZrCgBEjR6om62lcVw" latitude: 34.2611486 longitude: -118.5010287 - status: ASSIGNED + status: OPEN workersNeeded: 2 filled: 1 } @@ -950,7 +950,7 @@ mutation seedAll @transaction { placeId: "Eiw2ODAwIFNhbiBKb3NlIFN0cmVldCwgR3JhbmFkYSBIaWxscywgQ0EsIFVTQSIuKiwKFAoSCYNJZBTdmsKAEddGOfBj8LvTEhQKEglnNXI0zZrCgBEjR6om62lcVw" latitude: 34.2611486 longitude: -118.5010287 - status: ASSIGNED + status: OPEN workersNeeded: 2 filled: 1 } @@ -996,7 +996,7 @@ mutation seedAll @transaction { placeId: "Eiw0MDAwIFNhbiBKb3NlIFN0cmVldCwgR3JhbmFkYSBIaWxscywgQ0EsIFVTQSIuKiwKFAoSCYNJZBTdmsKAEddGOfBj8LvTEhQKEglnNXI0zZrCgBEjR6om62lcVw" latitude: 34.2611486 longitude: -118.5010287 - status: ASSIGNED + status: OPEN workersNeeded: 2 filled: 1 } @@ -1042,7 +1042,7 @@ mutation seedAll @transaction { placeId: "Eiw1MDAwIFNhbiBKb3NlIFN0cmVldCwgR3JhbmFkYSBIaWxscywgQ0EsIFVTQSIuKiwKFAoSCYNJZBTdmsKAEddGOfBj8LvTEhQKEglnNXI0zZrCgBEjR6om62lcVw" latitude: 34.2611486 longitude: -118.5010287 - status: ASSIGNED + status: OPEN workersNeeded: 2 filled: 1 } diff --git a/backend/dataconnect/schema/shift.gql b/backend/dataconnect/schema/shift.gql index 3e5f7c67..f03e54a7 100644 --- a/backend/dataconnect/schema/shift.gql +++ b/backend/dataconnect/schema/shift.gql @@ -1,9 +1,7 @@ enum ShiftStatus { DRAFT FILLED - PENDING ASSIGNED - CONFIRMED OPEN IN_PROGRESS COMPLETED From e6b3eca16d0ac5d3c18d0edf496e3c7a805e38fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:40:34 -0500 Subject: [PATCH 5/6] new query for my shifts --- .../client_create_order_repository_impl.dart | 6 +- .../widgets/shift_order_form_sheet.dart | 2 +- .../shifts_repository_impl.dart | 5 +- .../connector/application/queries.gql | 89 +++++++++++++++++++ 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart b/apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart index 757aff1f..d808ff3d 100644 --- a/apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart +++ b/apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart @@ -105,7 +105,7 @@ class ClientCreateOrderRepositoryImpl implements ClientCreateOrderRepositoryInte .state(hub.state) .street(hub.street) .country(hub.country) - .status(dc.ShiftStatus.CONFIRMED) + .status(dc.ShiftStatus.OPEN) .workersNeeded(workersNeeded) .filled(0) .durationDays(1) @@ -224,7 +224,7 @@ class ClientCreateOrderRepositoryImpl implements ClientCreateOrderRepositoryInte .state(hub.state) .street(hub.street) .country(hub.country) - .status(dc.ShiftStatus.CONFIRMED) + .status(dc.ShiftStatus.OPEN) .workersNeeded(workersNeeded) .filled(0) .durationDays(1) @@ -342,7 +342,7 @@ class ClientCreateOrderRepositoryImpl implements ClientCreateOrderRepositoryInte .state(hub.state) .street(hub.street) .country(hub.country) - .status(dc.ShiftStatus.CONFIRMED) + .status(dc.ShiftStatus.OPEN) .workersNeeded(workersNeeded) .filled(0) .durationDays(1) diff --git a/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart b/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart index 15bdac09..593a267a 100644 --- a/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart +++ b/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart @@ -265,7 +265,7 @@ class _ShiftOrderFormSheetState extends State { .state(selectedHub.state) .street(selectedHub.street) .country(selectedHub.country) - .status(dc.ShiftStatus.PENDING) + .status(dc.ShiftStatus.OPEN) .workersNeeded(workersNeeded) .filled(0) .durationDays(1) diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart b/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart index b1ada599..7d39b3c2 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart @@ -95,11 +95,12 @@ class ShiftsRepositoryImpl DateTime? end, }) async { final staffId = await _service.getStaffId(); - var query = _service.connector.getApplicationsByStaffId(staffId: staffId); + var query = _service.connector.getMyApplicationsByStaffId(staffId: staffId); if (start != null && end != null) { query = query.dayStart(_service.toTimestamp(start)).dayEnd(_service.toTimestamp(end)); } - final fdc.QueryResult response = await _service.executeProtected(() => query.execute()); + final fdc.QueryResult response = + await _service.executeProtected(() => query.execute()); final apps = response.data.applications; final List shifts = []; diff --git a/backend/dataconnect/connector/application/queries.gql b/backend/dataconnect/connector/application/queries.gql index 4a6d6396..e08aca4c 100644 --- a/backend/dataconnect/connector/application/queries.gql +++ b/backend/dataconnect/connector/application/queries.gql @@ -356,6 +356,95 @@ query getApplicationsByStaffId( } } +query getMyApplicationsByStaffId( + $staffId: UUID! + $offset: Int + $limit: Int + $dayStart: Timestamp + $dayEnd: Timestamp +) @auth(level: USER) { + applications( + where: { + staffId: { eq: $staffId } + status: { in: [ CONFIRMED, CHECKED_IN, CHECKED_OUT, LATE, PENDING] } + shift: { + date: { ge: $dayStart, le: $dayEnd } + } + + } + offset: $offset + limit: $limit + ) { + id + shiftId + staffId + status + appliedAt + checkInTime + checkOutTime + origin + createdAt + + shift { + id + title + date + startTime + endTime + location + status + durationDays + description + latitude + longitude + + order { + id + eventName + #location + + teamHub { + address + placeId + hubName + } + + business { + id + businessName + email + contactName + companyLogoUrl + } + vendor { + id + companyName + } + } + + } + + shiftRole { + id + roleId + count + assigned + startTime + endTime + hours + breakType + isBreakPaid + totalValue + role { + id + name + costPerHour + } + } + + } +} + query vaidateDayStaffApplication( $staffId: UUID! $offset: Int From d7bd1174c912548e75fded59a24c276a400aab6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:46:32 -0500 Subject: [PATCH 6/6] new query for history --- backend/dataconnect/connector/application/queries.gql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/dataconnect/connector/application/queries.gql b/backend/dataconnect/connector/application/queries.gql index e08aca4c..d2a8a205 100644 --- a/backend/dataconnect/connector/application/queries.gql +++ b/backend/dataconnect/connector/application/queries.gql @@ -784,10 +784,14 @@ query listCompletedApplicationsByStaffId( durationDays latitude longitude + orderId order { id eventName + orderType + startDate + endDate teamHub { address