feat: Implement review order functionality with localization support for titles, subtitles, and labels across multiple components

This commit is contained in:
Achintha Isuru
2026-03-10 10:12:38 -04:00
parent d6c9ed2cf3
commit c5d6bcbe04
13 changed files with 97 additions and 65 deletions

View File

@@ -1,12 +1,12 @@
---
name: mobile-feature-builder
name: mobile-builder
description: "Use this agent when implementing new mobile features or modifying existing features in the KROW Workforce staff or client mobile apps. This includes creating new feature modules, adding screens, implementing BLoCs, writing use cases, building repository implementations, integrating Firebase Data Connect, and writing tests for mobile features. Examples:\\n\\n- User: \"Add a shift swap feature to the staff app\"\\n Assistant: \"I'll use the mobile-feature-builder agent to implement the shift swap feature following Clean Architecture principles.\"\\n <commentary>Since the user is requesting a new mobile feature, use the Agent tool to launch the mobile-feature-builder agent to plan and implement the feature with proper domain/data/presentation layers.</commentary>\\n\\n- User: \"Create a new notifications screen in the client app with real-time updates\"\\n Assistant: \"Let me launch the mobile-feature-builder agent to implement the notifications feature with proper BLoC state management and Firebase integration.\"\\n <commentary>Since the user wants a new mobile screen with state management, use the Agent tool to launch the mobile-feature-builder agent to build it with correct architecture.</commentary>\\n\\n- User: \"The timesheet feature needs a new use case for calculating overtime\"\\n Assistant: \"I'll use the mobile-feature-builder agent to add the overtime calculation use case to the timesheet feature's domain layer.\"\\n <commentary>Since the user is requesting business logic additions to a mobile feature, use the Agent tool to launch the mobile-feature-builder agent to implement it in the correct layer.</commentary>\\n\\n- User: \"Write tests for the job listing BLoC in the staff app\"\\n Assistant: \"Let me use the mobile-feature-builder agent to write comprehensive BLoC tests using bloc_test and mocktail.\"\\n <commentary>Since the user wants mobile feature tests written, use the Agent tool to launch the mobile-feature-builder agent which knows the testing patterns and conventions.</commentary>"
model: opus
color: blue
memory: project
---
You are the **Mobile Feature Agent**, an elite Flutter/Dart engineer specializing in Clean Architecture mobile development for the KROW Workforce platform. You have deep expertise in BLoC state management, feature-first packaging, and design system compliance. You enforce **zero tolerance for architectural violations**.
You are the **Mobile Development Agent**, an elite Flutter/Dart engineer specializing in Clean Architecture mobile development for the KROW Workforce platform. You have deep expertise in BLoC state management, feature-first packaging, and design system compliance. You enforce **zero tolerance for architectural violations**.
## Initial Setup

View File

@@ -399,7 +399,29 @@
"placeholder": "Permanent Order Flow (Work in Progress)"
},
"review": {
"invalid_arguments": "Unable to load order review. Please go back and try again."
"invalid_arguments": "Unable to load order review. Please go back and try again.",
"title": "Review & Submit",
"subtitle": "Confirm details before posting",
"edit": "Edit",
"basics": "Basics",
"order_name": "Order Name",
"hub": "Hub",
"shift_contact": "Shift Contact",
"schedule": "Schedule",
"date": "Date",
"time": "Time",
"duration": "Duration",
"start_date": "Start Date",
"end_date": "End Date",
"repeat": "Repeat",
"positions": "POSITIONS",
"total": "Total",
"estimated_total": "Estimated Total",
"post_order": "Post Order"
},
"rapid_draft": {
"title": "Rapid Order",
"subtitle": "Verify the order details"
}
},
"client_main": {

View File

@@ -399,7 +399,29 @@
"placeholder": "Flujo de Orden Permanente (Trabajo en Progreso)"
},
"review": {
"invalid_arguments": "No se pudo cargar la revisi\u00f3n de la orden. Por favor, regresa e intenta de nuevo."
"invalid_arguments": "No se pudo cargar la revisi\u00f3n de la orden. Por favor, regresa e intenta de nuevo.",
"title": "Revisar y Enviar",
"subtitle": "Confirma los detalles antes de publicar",
"edit": "Editar",
"basics": "Datos B\u00e1sicos",
"order_name": "Nombre de la Orden",
"hub": "Hub",
"shift_contact": "Contacto del Turno",
"schedule": "Horario",
"date": "Fecha",
"time": "Hora",
"duration": "Duraci\u00f3n",
"start_date": "Fecha de Inicio",
"end_date": "Fecha de Fin",
"repeat": "Repetir",
"positions": "POSICIONES",
"total": "Total",
"estimated_total": "Total Estimado",
"post_order": "Publicar Orden"
},
"rapid_draft": {
"title": "Orden R\u00e1pida",
"subtitle": "Verifica los detalles de la orden"
}
},
"client_main": {

View File

@@ -1,7 +1,8 @@
import 'package:client_orders_common/client_orders_common.dart';
import 'package:core_localization/core_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:client_orders_common/client_orders_common.dart';
import 'package:intl/intl.dart';
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
@@ -59,8 +60,8 @@ class OneTimeOrderPage extends StatelessWidget {
: null,
hubManagers: state.managers.map(_mapManager).toList(),
isValid: state.isValid,
title: state.isRapidDraft ? 'Rapid Order' : null,
subtitle: state.isRapidDraft ? 'Verify the order details' : null,
title: state.isRapidDraft ? t.client_create_order.rapid_draft.title : null,
subtitle: state.isRapidDraft ? t.client_create_order.rapid_draft.subtitle : null,
onEventNameChanged: (String val) =>
bloc.add(OneTimeOrderEventNameChanged(val)),
onVendorChanged: (Vendor val) =>

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:flutter/material.dart';
import 'review_order_info_row.dart';
import 'review_order_section_card.dart';
@@ -20,11 +21,11 @@ class OneTimeScheduleSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ReviewOrderSectionCard(
title: 'Schedule',
title: t.client_create_order.review.schedule,
children: <Widget>[
ReviewOrderInfoRow(label: 'Date', value: date),
ReviewOrderInfoRow(label: 'Time', value: time),
ReviewOrderInfoRow(label: 'Duration', value: duration),
ReviewOrderInfoRow(label: t.client_create_order.review.date, value: date),
ReviewOrderInfoRow(label: t.client_create_order.review.time, value: time),
ReviewOrderInfoRow(label: t.client_create_order.review.duration, value: duration),
],
);
}

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:flutter/material.dart';
import 'review_order_info_row.dart';
import 'review_order_section_card.dart';
@@ -20,11 +21,11 @@ class PermanentScheduleSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ReviewOrderSectionCard(
title: 'Schedule',
title: t.client_create_order.review.schedule,
onEdit: onEdit,
children: <Widget>[
ReviewOrderInfoRow(label: 'Start Date', value: startDate),
ReviewOrderInfoRow(label: 'Repeat', value: repeatDays),
ReviewOrderInfoRow(label: t.client_create_order.review.start_date, value: startDate),
ReviewOrderInfoRow(label: t.client_create_order.review.repeat, value: repeatDays),
],
);
}

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:flutter/material.dart';
import 'review_order_info_row.dart';
import 'review_order_section_card.dart';
@@ -22,12 +23,12 @@ class RecurringScheduleSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ReviewOrderSectionCard(
title: 'Schedule',
title: t.client_create_order.review.schedule,
onEdit: onEdit,
children: <Widget>[
ReviewOrderInfoRow(label: 'Start Date', value: startDate),
ReviewOrderInfoRow(label: 'End Date', value: endDate),
ReviewOrderInfoRow(label: 'Repeat', value: repeatDays),
ReviewOrderInfoRow(label: t.client_create_order.review.start_date, value: startDate),
ReviewOrderInfoRow(label: t.client_create_order.review.end_date, value: endDate),
ReviewOrderInfoRow(label: t.client_create_order.review.repeat, value: repeatDays),
],
);
}

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
@@ -9,14 +10,14 @@ class ReviewOrderActionBar extends StatelessWidget {
const ReviewOrderActionBar({
required this.onBack,
required this.onSubmit,
this.submitLabel = 'Post Order',
this.submitLabel,
this.isLoading = false,
super.key,
});
final VoidCallback onBack;
final VoidCallback? onSubmit;
final String submitLabel;
final String? submitLabel;
final bool isLoading;
@override
@@ -32,39 +33,17 @@ class ReviewOrderActionBar extends StatelessWidget {
),
child: Row(
children: <Widget>[
SizedBox(
width: 80,
height: 52,
child: OutlinedButton(
onPressed: onBack,
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: UiConstants.radiusXl,
),
side: const BorderSide(
color: UiColors.border,
width: 1.5,
),
),
child: const Icon(
UiIcons.chevronLeft,
size: UiConstants.iconMd,
color: UiColors.iconPrimary,
),
),
UiButton.secondary(
leadingIcon: UiIcons.chevronLeft,
onPressed: onBack,
size: UiButtonSize.large,
),
const SizedBox(width: UiConstants.space3),
Expanded(
child: SizedBox(
height: 52,
child: UiButton.primary(
text: submitLabel,
onPressed: onSubmit,
isLoading: isLoading,
size: UiButtonSize.large,
fullWidth: true,
),
),
UiButton.primary(
text: submitLabel ?? t.client_create_order.review.post_order,
onPressed: onSubmit,
isLoading: isLoading,
size: UiButtonSize.large,
),
],
),

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:flutter/material.dart';
import 'review_order_info_row.dart';
import 'review_order_section_card.dart';
@@ -21,12 +22,12 @@ class ReviewOrderBasicsCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ReviewOrderSectionCard(
title: 'Basics',
title: t.client_create_order.review.basics,
onEdit: onEdit,
children: <Widget>[
ReviewOrderInfoRow(label: 'Order Name', value: orderName),
ReviewOrderInfoRow(label: 'Hub', value: hubName),
ReviewOrderInfoRow(label: 'Shift Contact', value: shiftContactName),
ReviewOrderInfoRow(label: t.client_create_order.review.order_name, value: orderName),
ReviewOrderInfoRow(label: t.client_create_order.review.hub, value: hubName),
ReviewOrderInfoRow(label: t.client_create_order.review.shift_contact, value: shiftContactName),
],
);
}

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'review_order_info_row.dart';
@@ -36,14 +37,14 @@ class ReviewOrderPositionsCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'POSITIONS',
t.client_create_order.review.positions,
style: UiTypography.titleUppercase4b.textSecondary,
),
if (onEdit != null)
GestureDetector(
onTap: onEdit,
child: Text(
'Edit',
t.client_create_order.review.edit,
style: UiTypography.body3m.primary,
),
),
@@ -72,7 +73,7 @@ class ReviewOrderPositionsCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Total',
t.client_create_order.review.total,
style: UiTypography.body3m,
),
Text(

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
@@ -39,7 +40,7 @@ class ReviewOrderSectionCard extends StatelessWidget {
if (onEdit != null)
GestureDetector(
onTap: onEdit,
child: Text('Edit', style: UiTypography.body3m.primary),
child: Text(t.client_create_order.review.edit, style: UiTypography.body3m.primary),
),
],
),

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
@@ -27,7 +28,7 @@ class ReviewOrderTotalBanner extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Estimated Total',
t.client_create_order.review.estimated_total,
style: UiTypography.body2m,
),
Text(

View File

@@ -1,3 +1,4 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'review_order_action_bar.dart';
@@ -30,7 +31,7 @@ class ReviewOrderView extends StatelessWidget {
this.onEditBasics,
this.onEditSchedule,
this.onEditPositions,
this.submitLabel = 'Post Order',
this.submitLabel,
this.isLoading = false,
super.key,
});
@@ -49,7 +50,7 @@ class ReviewOrderView extends StatelessWidget {
final VoidCallback? onEditBasics;
final VoidCallback? onEditSchedule;
final VoidCallback? onEditPositions;
final String submitLabel;
final String? submitLabel;
final bool isLoading;
@override
@@ -58,8 +59,8 @@ class ReviewOrderView extends StatelessWidget {
appBar: UiAppBar(
showBackButton: true,
onLeadingPressed: onBack,
title: 'Review & Submit',
subtitle: 'Confirm details before posting',
title: t.client_create_order.review.title,
subtitle: t.client_create_order.review.subtitle,
),
body: Column(
children: <Widget>[
@@ -103,7 +104,7 @@ class ReviewOrderView extends StatelessWidget {
ReviewOrderActionBar(
onBack: onBack,
onSubmit: onSubmit,
submitLabel: submitLabel,
submitLabel: submitLabel ?? t.client_create_order.review.post_order,
isLoading: isLoading,
),
],