feat: implement navigation to order details with specific date for one-time and recurring orders

This commit is contained in:
Achintha Isuru
2026-02-21 20:03:49 -05:00
parent b2cfd93b8f
commit 71b5f743de
4 changed files with 160 additions and 84 deletions

View File

@@ -168,4 +168,16 @@ extension ClientNavigator on IModularNavigator {
void toCreateOrderPermanent() { void toCreateOrderPermanent() {
pushNamed(ClientPaths.createOrderPermanent); pushNamed(ClientPaths.createOrderPermanent);
} }
// ==========================================================================
// VIEW ORDER
// ==========================================================================
/// Navigates to the order details page to a specific date.
void toOrdersSpecificDate(DateTime date) {
navigate(
ClientPaths.orders,
arguments: <String, DateTime>{'initialDate': date},
);
}
} }

View File

@@ -24,7 +24,9 @@ class OneTimeOrderPage extends StatelessWidget {
create: (BuildContext context) => Modular.get<OneTimeOrderBloc>(), create: (BuildContext context) => Modular.get<OneTimeOrderBloc>(),
child: BlocBuilder<OneTimeOrderBloc, OneTimeOrderState>( child: BlocBuilder<OneTimeOrderBloc, OneTimeOrderState>(
builder: (BuildContext context, OneTimeOrderState state) { builder: (BuildContext context, OneTimeOrderState state) {
final OneTimeOrderBloc bloc = BlocProvider.of<OneTimeOrderBloc>(context); final OneTimeOrderBloc bloc = BlocProvider.of<OneTimeOrderBloc>(
context,
);
return OneTimeOrderView( return OneTimeOrderView(
status: _mapStatus(state.status), status: _mapStatus(state.status),
@@ -33,16 +35,23 @@ class OneTimeOrderPage extends StatelessWidget {
selectedVendor: state.selectedVendor, selectedVendor: state.selectedVendor,
vendors: state.vendors, vendors: state.vendors,
date: state.date, date: state.date,
selectedHub: state.selectedHub != null ? _mapHub(state.selectedHub!) : null, selectedHub: state.selectedHub != null
? _mapHub(state.selectedHub!)
: null,
hubs: state.hubs.map(_mapHub).toList(), hubs: state.hubs.map(_mapHub).toList(),
positions: state.positions.map(_mapPosition).toList(), positions: state.positions.map(_mapPosition).toList(),
roles: state.roles.map(_mapRole).toList(), roles: state.roles.map(_mapRole).toList(),
isValid: state.isValid, isValid: state.isValid,
onEventNameChanged: (String val) => bloc.add(OneTimeOrderEventNameChanged(val)), onEventNameChanged: (String val) =>
onVendorChanged: (Vendor val) => bloc.add(OneTimeOrderVendorChanged(val)), bloc.add(OneTimeOrderEventNameChanged(val)),
onDateChanged: (DateTime val) => bloc.add(OneTimeOrderDateChanged(val)), onVendorChanged: (Vendor val) =>
bloc.add(OneTimeOrderVendorChanged(val)),
onDateChanged: (DateTime val) =>
bloc.add(OneTimeOrderDateChanged(val)),
onHubChanged: (OrderHubUiModel val) { onHubChanged: (OrderHubUiModel val) {
final OneTimeOrderHubOption originalHub = state.hubs.firstWhere((OneTimeOrderHubOption h) => h.id == val.id); final OneTimeOrderHubOption originalHub = state.hubs.firstWhere(
(OneTimeOrderHubOption h) => h.id == val.id,
);
bloc.add(OneTimeOrderHubChanged(originalHub)); bloc.add(OneTimeOrderHubChanged(originalHub));
}, },
onPositionAdded: () => bloc.add(const OneTimeOrderPositionAdded()), onPositionAdded: () => bloc.add(const OneTimeOrderPositionAdded()),
@@ -57,16 +66,11 @@ class OneTimeOrderPage extends StatelessWidget {
); );
bloc.add(OneTimeOrderPositionUpdated(index, updated)); bloc.add(OneTimeOrderPositionUpdated(index, updated));
}, },
onPositionRemoved: (int index) => bloc.add(OneTimeOrderPositionRemoved(index)), onPositionRemoved: (int index) =>
bloc.add(OneTimeOrderPositionRemoved(index)),
onSubmit: () => bloc.add(const OneTimeOrderSubmitted()), onSubmit: () => bloc.add(const OneTimeOrderSubmitted()),
onDone: () => Modular.to.pushNamedAndRemoveUntil( onDone: () => Modular.to.toOrdersSpecificDate(state.date),
ClientPaths.orders, onBack: () => Modular.to.toCreateOrder(),
(_) => false,
arguments: <String, dynamic>{
'initialDate': state.date.toIso8601String(),
},
),
onBack: () => Modular.to.navigate(ClientPaths.createOrder),
); );
}, },
), ),

View File

@@ -19,7 +19,9 @@ class PermanentOrderPage extends StatelessWidget {
create: (BuildContext context) => Modular.get<PermanentOrderBloc>(), create: (BuildContext context) => Modular.get<PermanentOrderBloc>(),
child: BlocBuilder<PermanentOrderBloc, PermanentOrderState>( child: BlocBuilder<PermanentOrderBloc, PermanentOrderState>(
builder: (BuildContext context, PermanentOrderState state) { builder: (BuildContext context, PermanentOrderState state) {
final PermanentOrderBloc bloc = BlocProvider.of<PermanentOrderBloc>(context); final PermanentOrderBloc bloc = BlocProvider.of<PermanentOrderBloc>(
context,
);
return PermanentOrderView( return PermanentOrderView(
status: _mapStatus(state.status), status: _mapStatus(state.status),
@@ -29,20 +31,29 @@ class PermanentOrderPage extends StatelessWidget {
vendors: state.vendors, vendors: state.vendors,
startDate: state.startDate, startDate: state.startDate,
permanentDays: state.permanentDays, permanentDays: state.permanentDays,
selectedHub: state.selectedHub != null ? _mapHub(state.selectedHub!) : null, selectedHub: state.selectedHub != null
? _mapHub(state.selectedHub!)
: null,
hubs: state.hubs.map(_mapHub).toList(), hubs: state.hubs.map(_mapHub).toList(),
positions: state.positions.map(_mapPosition).toList(), positions: state.positions.map(_mapPosition).toList(),
roles: state.roles.map(_mapRole).toList(), roles: state.roles.map(_mapRole).toList(),
isValid: state.isValid, isValid: state.isValid,
onEventNameChanged: (String val) => bloc.add(PermanentOrderEventNameChanged(val)), onEventNameChanged: (String val) =>
onVendorChanged: (Vendor val) => bloc.add(PermanentOrderVendorChanged(val)), bloc.add(PermanentOrderEventNameChanged(val)),
onStartDateChanged: (DateTime val) => bloc.add(PermanentOrderStartDateChanged(val)), onVendorChanged: (Vendor val) =>
onDayToggled: (int index) => bloc.add(PermanentOrderDayToggled(index)), bloc.add(PermanentOrderVendorChanged(val)),
onStartDateChanged: (DateTime val) =>
bloc.add(PermanentOrderStartDateChanged(val)),
onDayToggled: (int index) =>
bloc.add(PermanentOrderDayToggled(index)),
onHubChanged: (OrderHubUiModel val) { onHubChanged: (OrderHubUiModel val) {
final PermanentOrderHubOption originalHub = state.hubs.firstWhere((PermanentOrderHubOption h) => h.id == val.id); final PermanentOrderHubOption originalHub = state.hubs.firstWhere(
(PermanentOrderHubOption h) => h.id == val.id,
);
bloc.add(PermanentOrderHubChanged(originalHub)); bloc.add(PermanentOrderHubChanged(originalHub));
}, },
onPositionAdded: () => bloc.add(const PermanentOrderPositionAdded()), onPositionAdded: () =>
bloc.add(const PermanentOrderPositionAdded()),
onPositionUpdated: (int index, OrderPositionUiModel val) { onPositionUpdated: (int index, OrderPositionUiModel val) {
final PermanentOrderPosition original = state.positions[index]; final PermanentOrderPosition original = state.positions[index];
final PermanentOrderPosition updated = original.copyWith( final PermanentOrderPosition updated = original.copyWith(
@@ -54,22 +65,19 @@ class PermanentOrderPage extends StatelessWidget {
); );
bloc.add(PermanentOrderPositionUpdated(index, updated)); bloc.add(PermanentOrderPositionUpdated(index, updated));
}, },
onPositionRemoved: (int index) => bloc.add(PermanentOrderPositionRemoved(index)), onPositionRemoved: (int index) =>
bloc.add(PermanentOrderPositionRemoved(index)),
onSubmit: () => bloc.add(const PermanentOrderSubmitted()), onSubmit: () => bloc.add(const PermanentOrderSubmitted()),
onDone: () { onDone: () {
final DateTime initialDate = _firstPermanentShiftDate( final DateTime initialDate = _firstPermanentShiftDate(
state.startDate, state.startDate,
state.permanentDays, state.permanentDays,
); );
Modular.to.pushNamedAndRemoveUntil(
ClientPaths.orders, // Navigate to orders page with the initial date set to the first recurring shift date
(_) => false, Modular.to.toOrdersSpecificDate(initialDate);
arguments: <String, dynamic>{
'initialDate': initialDate.toIso8601String(),
}, },
); onBack: () => Modular.to.toCreateOrder(),
},
onBack: () => Modular.to.navigate(ClientPaths.createOrder),
); );
}, },
), ),
@@ -80,10 +88,18 @@ class PermanentOrderPage extends StatelessWidget {
DateTime startDate, DateTime startDate,
List<String> permanentDays, List<String> permanentDays,
) { ) {
final DateTime start = DateTime(startDate.year, startDate.month, startDate.day); final DateTime start = DateTime(
startDate.year,
startDate.month,
startDate.day,
);
final DateTime end = start.add(const Duration(days: 29)); final DateTime end = start.add(const Duration(days: 29));
final Set<String> selected = permanentDays.toSet(); final Set<String> selected = permanentDays.toSet();
for (DateTime day = start; !day.isAfter(end); day = day.add(const Duration(days: 1))) { for (
DateTime day = start;
!day.isAfter(end);
day = day.add(const Duration(days: 1))
) {
if (selected.contains(_weekdayLabel(day))) { if (selected.contains(_weekdayLabel(day))) {
return day; return day;
} }
@@ -93,23 +109,35 @@ class PermanentOrderPage extends StatelessWidget {
String _weekdayLabel(DateTime date) { String _weekdayLabel(DateTime date) {
switch (date.weekday) { switch (date.weekday) {
case DateTime.monday: return 'MON'; case DateTime.monday:
case DateTime.tuesday: return 'TUE'; return 'MON';
case DateTime.wednesday: return 'WED'; case DateTime.tuesday:
case DateTime.thursday: return 'THU'; return 'TUE';
case DateTime.friday: return 'FRI'; case DateTime.wednesday:
case DateTime.saturday: return 'SAT'; return 'WED';
case DateTime.sunday: return 'SUN'; case DateTime.thursday:
default: return 'SUN'; return 'THU';
case DateTime.friday:
return 'FRI';
case DateTime.saturday:
return 'SAT';
case DateTime.sunday:
return 'SUN';
default:
return 'SUN';
} }
} }
OrderFormStatus _mapStatus(PermanentOrderStatus status) { OrderFormStatus _mapStatus(PermanentOrderStatus status) {
switch (status) { switch (status) {
case PermanentOrderStatus.initial: return OrderFormStatus.initial; case PermanentOrderStatus.initial:
case PermanentOrderStatus.loading: return OrderFormStatus.loading; return OrderFormStatus.initial;
case PermanentOrderStatus.success: return OrderFormStatus.success; case PermanentOrderStatus.loading:
case PermanentOrderStatus.failure: return OrderFormStatus.failure; return OrderFormStatus.loading;
case PermanentOrderStatus.success:
return OrderFormStatus.success;
case PermanentOrderStatus.failure:
return OrderFormStatus.failure;
} }
} }

View File

@@ -19,7 +19,9 @@ class RecurringOrderPage extends StatelessWidget {
create: (BuildContext context) => Modular.get<RecurringOrderBloc>(), create: (BuildContext context) => Modular.get<RecurringOrderBloc>(),
child: BlocBuilder<RecurringOrderBloc, RecurringOrderState>( child: BlocBuilder<RecurringOrderBloc, RecurringOrderState>(
builder: (BuildContext context, RecurringOrderState state) { builder: (BuildContext context, RecurringOrderState state) {
final RecurringOrderBloc bloc = BlocProvider.of<RecurringOrderBloc>(context); final RecurringOrderBloc bloc = BlocProvider.of<RecurringOrderBloc>(
context,
);
return RecurringOrderView( return RecurringOrderView(
status: _mapStatus(state.status), status: _mapStatus(state.status),
@@ -30,21 +32,31 @@ class RecurringOrderPage extends StatelessWidget {
startDate: state.startDate, startDate: state.startDate,
endDate: state.endDate, endDate: state.endDate,
recurringDays: state.recurringDays, recurringDays: state.recurringDays,
selectedHub: state.selectedHub != null ? _mapHub(state.selectedHub!) : null, selectedHub: state.selectedHub != null
? _mapHub(state.selectedHub!)
: null,
hubs: state.hubs.map(_mapHub).toList(), hubs: state.hubs.map(_mapHub).toList(),
positions: state.positions.map(_mapPosition).toList(), positions: state.positions.map(_mapPosition).toList(),
roles: state.roles.map(_mapRole).toList(), roles: state.roles.map(_mapRole).toList(),
isValid: state.isValid, isValid: state.isValid,
onEventNameChanged: (String val) => bloc.add(RecurringOrderEventNameChanged(val)), onEventNameChanged: (String val) =>
onVendorChanged: (Vendor val) => bloc.add(RecurringOrderVendorChanged(val)), bloc.add(RecurringOrderEventNameChanged(val)),
onStartDateChanged: (DateTime val) => bloc.add(RecurringOrderStartDateChanged(val)), onVendorChanged: (Vendor val) =>
onEndDateChanged: (DateTime val) => bloc.add(RecurringOrderEndDateChanged(val)), bloc.add(RecurringOrderVendorChanged(val)),
onDayToggled: (int index) => bloc.add(RecurringOrderDayToggled(index)), onStartDateChanged: (DateTime val) =>
bloc.add(RecurringOrderStartDateChanged(val)),
onEndDateChanged: (DateTime val) =>
bloc.add(RecurringOrderEndDateChanged(val)),
onDayToggled: (int index) =>
bloc.add(RecurringOrderDayToggled(index)),
onHubChanged: (OrderHubUiModel val) { onHubChanged: (OrderHubUiModel val) {
final RecurringOrderHubOption originalHub = state.hubs.firstWhere((RecurringOrderHubOption h) => h.id == val.id); final RecurringOrderHubOption originalHub = state.hubs.firstWhere(
(RecurringOrderHubOption h) => h.id == val.id,
);
bloc.add(RecurringOrderHubChanged(originalHub)); bloc.add(RecurringOrderHubChanged(originalHub));
}, },
onPositionAdded: () => bloc.add(const RecurringOrderPositionAdded()), onPositionAdded: () =>
bloc.add(const RecurringOrderPositionAdded()),
onPositionUpdated: (int index, OrderPositionUiModel val) { onPositionUpdated: (int index, OrderPositionUiModel val) {
final RecurringOrderPosition original = state.positions[index]; final RecurringOrderPosition original = state.positions[index];
final RecurringOrderPosition updated = original.copyWith( final RecurringOrderPosition updated = original.copyWith(
@@ -56,27 +68,27 @@ class RecurringOrderPage extends StatelessWidget {
); );
bloc.add(RecurringOrderPositionUpdated(index, updated)); bloc.add(RecurringOrderPositionUpdated(index, updated));
}, },
onPositionRemoved: (int index) => bloc.add(RecurringOrderPositionRemoved(index)), onPositionRemoved: (int index) =>
bloc.add(RecurringOrderPositionRemoved(index)),
onSubmit: () => bloc.add(const RecurringOrderSubmitted()), onSubmit: () => bloc.add(const RecurringOrderSubmitted()),
onDone: () { onDone: () {
final DateTime maxEndDate = state.startDate.add(const Duration(days: 29)); final DateTime maxEndDate = state.startDate.add(
const Duration(days: 29),
);
final DateTime effectiveEndDate = final DateTime effectiveEndDate =
state.endDate.isAfter(maxEndDate) ? maxEndDate : state.endDate; state.endDate.isAfter(maxEndDate)
? maxEndDate
: state.endDate;
final DateTime initialDate = _firstRecurringShiftDate( final DateTime initialDate = _firstRecurringShiftDate(
state.startDate, state.startDate,
effectiveEndDate, effectiveEndDate,
state.recurringDays, state.recurringDays,
); );
Modular.to.pushNamedAndRemoveUntil( // Navigate to orders page with the initial date set to the first recurring shift date
ClientPaths.orders, Modular.to.toOrdersSpecificDate(initialDate);
(_) => false,
arguments: <String, dynamic>{
'initialDate': initialDate.toIso8601String(),
}, },
); onBack: () => Modular.to.toCreateOrder(),
},
onBack: () => Modular.to.navigate(ClientPaths.createOrder),
); );
}, },
), ),
@@ -88,10 +100,18 @@ class RecurringOrderPage extends StatelessWidget {
DateTime endDate, DateTime endDate,
List<String> recurringDays, List<String> recurringDays,
) { ) {
final DateTime start = DateTime(startDate.year, startDate.month, startDate.day); final DateTime start = DateTime(
startDate.year,
startDate.month,
startDate.day,
);
final DateTime end = DateTime(endDate.year, endDate.month, endDate.day); final DateTime end = DateTime(endDate.year, endDate.month, endDate.day);
final Set<String> selected = recurringDays.toSet(); final Set<String> selected = recurringDays.toSet();
for (DateTime day = start; !day.isAfter(end); day = day.add(const Duration(days: 1))) { for (
DateTime day = start;
!day.isAfter(end);
day = day.add(const Duration(days: 1))
) {
if (selected.contains(_weekdayLabel(day))) { if (selected.contains(_weekdayLabel(day))) {
return day; return day;
} }
@@ -101,23 +121,35 @@ class RecurringOrderPage extends StatelessWidget {
String _weekdayLabel(DateTime date) { String _weekdayLabel(DateTime date) {
switch (date.weekday) { switch (date.weekday) {
case DateTime.monday: return 'MON'; case DateTime.monday:
case DateTime.tuesday: return 'TUE'; return 'MON';
case DateTime.wednesday: return 'WED'; case DateTime.tuesday:
case DateTime.thursday: return 'THU'; return 'TUE';
case DateTime.friday: return 'FRI'; case DateTime.wednesday:
case DateTime.saturday: return 'SAT'; return 'WED';
case DateTime.sunday: return 'SUN'; case DateTime.thursday:
default: return 'SUN'; return 'THU';
case DateTime.friday:
return 'FRI';
case DateTime.saturday:
return 'SAT';
case DateTime.sunday:
return 'SUN';
default:
return 'SUN';
} }
} }
OrderFormStatus _mapStatus(RecurringOrderStatus status) { OrderFormStatus _mapStatus(RecurringOrderStatus status) {
switch (status) { switch (status) {
case RecurringOrderStatus.initial: return OrderFormStatus.initial; case RecurringOrderStatus.initial:
case RecurringOrderStatus.loading: return OrderFormStatus.loading; return OrderFormStatus.initial;
case RecurringOrderStatus.success: return OrderFormStatus.success; case RecurringOrderStatus.loading:
case RecurringOrderStatus.failure: return OrderFormStatus.failure; return OrderFormStatus.loading;
case RecurringOrderStatus.success:
return OrderFormStatus.success;
case RecurringOrderStatus.failure:
return OrderFormStatus.failure;
} }
} }