feat: localization, file restriction banners, test credentials, edit icon fix
- #553: Audit and verify localizations (en/es), replace hardcoded strings - #549: Incomplete profile banner in Find Shifts (staff app) - #550: File restriction banner on document upload page - #551: File restriction banner on certificate upload page - #552: File restriction banner on attire upload page - #492: Hide edit icon for past/completed orders (client app) - #524: Display worker benefits in staff app - Add test credentials to seed: testclient@gmail.com, staff +1-555-555-1234 - Fix document upload validation (context arg in _validatePdfFile on submit) - Add PR_LOCALIZATION.md Made-with: Cursor
This commit is contained in:
@@ -73,11 +73,15 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
|
||||
final String eventName =
|
||||
shiftRole.shift.order.eventName ?? shiftRole.shift.title;
|
||||
|
||||
final order = shiftRole.shift.order;
|
||||
final String? hubManagerId = order.hubManagerId;
|
||||
final String? hubManagerName = order.hubManager?.user?.fullName;
|
||||
|
||||
return domain.OrderItem(
|
||||
id: _shiftRoleKey(shiftRole.shiftId, shiftRole.roleId),
|
||||
orderId: shiftRole.shift.order.id,
|
||||
orderId: order.id,
|
||||
orderType: domain.OrderType.fromString(
|
||||
shiftRole.shift.order.orderType.stringValue,
|
||||
order.orderType.stringValue,
|
||||
),
|
||||
title: shiftRole.role.name,
|
||||
eventName: eventName,
|
||||
@@ -94,6 +98,8 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
|
||||
hours: hours,
|
||||
totalValue: totalValue,
|
||||
confirmedApps: const <Map<String, dynamic>>[],
|
||||
hubManagerId: hubManagerId,
|
||||
hubManagerName: hubManagerName,
|
||||
);
|
||||
}).toList();
|
||||
});
|
||||
|
||||
@@ -193,6 +193,8 @@ class ViewOrdersCubit extends Cubit<ViewOrdersState>
|
||||
hours: order.hours,
|
||||
totalValue: order.totalValue,
|
||||
confirmedApps: confirmed,
|
||||
hubManagerId: order.hubManagerId,
|
||||
hubManagerName: order.hubManagerName,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
_buildSectionHeader('VENDOR'),
|
||||
_buildSectionHeader(t.client_orders_common.select_vendor),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space3,
|
||||
@@ -742,7 +742,7 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
_buildSectionHeader('ORDER NAME'),
|
||||
_buildSectionHeader(t.client_orders_common.order_name),
|
||||
UiTextField(
|
||||
controller: _orderNameController,
|
||||
hintText: t.client_view_orders.order_edit_sheet.order_name_hint,
|
||||
@@ -750,7 +750,7 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
_buildSectionHeader('HUB'),
|
||||
_buildSectionHeader(t.client_orders_common.hub),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space3,
|
||||
|
||||
@@ -108,6 +108,43 @@ class _ViewOrderCardState extends State<ViewOrderCard> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the edit icon should be shown.
|
||||
/// Hidden for completed orders and for past orders (shift has ended).
|
||||
bool _canEditOrder(OrderItem order) {
|
||||
if (order.status == 'COMPLETED') return false;
|
||||
if (order.date.isEmpty) return true;
|
||||
try {
|
||||
final DateTime orderDate = DateTime.parse(order.date);
|
||||
final String endTime = order.endTime.trim();
|
||||
final DateTime endDateTime;
|
||||
if (endTime.isEmpty) {
|
||||
// No end time: use end of day so orders today remain editable
|
||||
endDateTime = DateTime(
|
||||
orderDate.year,
|
||||
orderDate.month,
|
||||
orderDate.day,
|
||||
23,
|
||||
59,
|
||||
59,
|
||||
);
|
||||
} else {
|
||||
final List<String> endParts = endTime.split(':');
|
||||
final int hour = endParts.isNotEmpty ? int.parse(endParts[0]) : 0;
|
||||
final int minute = endParts.length > 1 ? int.parse(endParts[1]) : 0;
|
||||
endDateTime = DateTime(
|
||||
orderDate.year,
|
||||
orderDate.month,
|
||||
orderDate.day,
|
||||
hour,
|
||||
minute,
|
||||
);
|
||||
}
|
||||
return endDateTime.isAfter(DateTime.now());
|
||||
} catch (_) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final OrderItem order = widget.order;
|
||||
@@ -291,13 +328,14 @@ class _ViewOrderCardState extends State<ViewOrderCard> {
|
||||
// Actions
|
||||
Row(
|
||||
children: <Widget>[
|
||||
_buildHeaderIconButton(
|
||||
icon: UiIcons.edit,
|
||||
color: UiColors.primary,
|
||||
bgColor: UiColors.primary.withValues(alpha: 0.08),
|
||||
onTap: () => _openEditSheet(order: order),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space2),
|
||||
if (_canEditOrder(order))
|
||||
_buildHeaderIconButton(
|
||||
icon: UiIcons.edit,
|
||||
color: UiColors.primary,
|
||||
bgColor: UiColors.primary.withValues(alpha: 0.08),
|
||||
onTap: () => _openEditSheet(order: order),
|
||||
),
|
||||
if (_canEditOrder(order)) const SizedBox(width: UiConstants.space2),
|
||||
if (order.confirmedApps.isNotEmpty)
|
||||
_buildHeaderIconButton(
|
||||
icon: _expanded
|
||||
|
||||
Reference in New Issue
Block a user