From 9d25fd44ccd49e0307ec0f2ca0d05c0a68487856 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Fri, 27 Feb 2026 13:16:11 -0500 Subject: [PATCH] Add rapid order parsing & audio recording Add support for transcribing and parsing rapid (urgent) orders into one-time order drafts. Introduces ParseRapidOrderTextToOrderUseCase and wiring for TranscribeRapidOrderUseCase, implements parseRapidOrder and transcribeRapidOrder in the client repository, and injects these into the RapidOrderBloc and module. Adds the record package dependency and registers the record plugin for iOS/macOS targets. Updates OneTimeOrder state, bloc and views to handle rapid-order drafts and navigate to the one-time order flow after parsing. Also includes small formatting and navigator changes. --- .../ios/Runner/GeneratedPluginRegistrant.m | 7 ++ .../Flutter/GeneratedPluginRegistrant.swift | 2 + .../ios/Runner/GeneratedPluginRegistrant.m | 7 ++ .../Flutter/GeneratedPluginRegistrant.swift | 2 + .../core/lib/src/routing/staff/navigator.dart | 4 +- apps/mobile/packages/core/pubspec.yaml | 1 + .../lib/src/create_order_module.dart | 12 +++- .../client_create_order_repository_impl.dart | 45 +++++++++++++ ...ent_create_order_repository_interface.dart | 10 +++ .../usecases/parse_rapid_order_usecase.dart | 15 +++++ .../one_time_order/one_time_order_bloc.dart | 50 +++++++++++++-- .../one_time_order/one_time_order_state.dart | 11 ++-- .../blocs/rapid_order/rapid_order_bloc.dart | 22 ++++--- .../blocs/rapid_order/rapid_order_state.dart | 9 +++ .../pages/one_time_order_page.dart | 1 + .../widgets/rapid_order/rapid_order_view.dart | 7 ++ .../one_time_order/one_time_order_view.dart | 17 ++--- .../Flutter/GeneratedPluginRegistrant.swift | 2 + apps/mobile/pubspec.lock | 64 +++++++++++++++++++ 19 files changed, 256 insertions(+), 32 deletions(-) create mode 100644 apps/mobile/packages/features/client/orders/create_order/lib/src/domain/usecases/parse_rapid_order_usecase.dart diff --git a/apps/mobile/apps/client/ios/Runner/GeneratedPluginRegistrant.m b/apps/mobile/apps/client/ios/Runner/GeneratedPluginRegistrant.m index 8b0a7da5..241fcf3b 100644 --- a/apps/mobile/apps/client/ios/Runner/GeneratedPluginRegistrant.m +++ b/apps/mobile/apps/client/ios/Runner/GeneratedPluginRegistrant.m @@ -36,6 +36,12 @@ @import image_picker_ios; #endif +#if __has_include() +#import +#else +@import record_ios; +#endif + #if __has_include() #import #else @@ -56,6 +62,7 @@ [FLTFirebaseAuthPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAuthPlugin"]]; [FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]]; [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; + [RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]]; [SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]]; [URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]]; } diff --git a/apps/mobile/apps/client/macos/Flutter/GeneratedPluginRegistrant.swift b/apps/mobile/apps/client/macos/Flutter/GeneratedPluginRegistrant.swift index 30780dc6..1dea22d7 100644 --- a/apps/mobile/apps/client/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/apps/mobile/apps/client/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import file_selector_macos import firebase_app_check import firebase_auth import firebase_core +import record_macos import shared_preferences_foundation import url_launcher_macos @@ -19,6 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m b/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m index e8a688bb..72d03754 100644 --- a/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m +++ b/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m @@ -54,6 +54,12 @@ @import permission_handler_apple; #endif +#if __has_include() +#import +#else +@import record_ios; +#endif + #if __has_include() #import #else @@ -77,6 +83,7 @@ [FLTGoogleMapsPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTGoogleMapsPlugin"]]; [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; [PermissionHandlerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PermissionHandlerPlugin"]]; + [RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]]; [SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]]; [URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]]; } diff --git a/apps/mobile/apps/staff/macos/Flutter/GeneratedPluginRegistrant.swift b/apps/mobile/apps/staff/macos/Flutter/GeneratedPluginRegistrant.swift index 56b4b1e5..e919f640 100644 --- a/apps/mobile/apps/staff/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/apps/mobile/apps/staff/macos/Flutter/GeneratedPluginRegistrant.swift @@ -11,6 +11,7 @@ import firebase_app_check import firebase_auth import firebase_core import geolocator_apple +import record_macos import shared_preferences_foundation import url_launcher_macos @@ -21,6 +22,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } 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 5456d1e6..21d5c9ca 100644 --- a/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart +++ b/apps/mobile/packages/core/lib/src/routing/staff/navigator.dart @@ -139,7 +139,7 @@ extension StaffNavigator on IModularNavigator { /// /// Manage personal information, documents, and preferences. void toProfile() { - pushNamedAndRemoveUntil(StaffPaths.profile, (_) => false); + navigate(StaffPaths.profile); } // ========================================================================== @@ -189,7 +189,7 @@ extension StaffNavigator on IModularNavigator { /// /// Record previous work experience and qualifications. void toExperience() { - pushNamed(StaffPaths.experience); + navigate(StaffPaths.experience); } /// Pushes the attire preferences page. diff --git a/apps/mobile/packages/core/pubspec.yaml b/apps/mobile/packages/core/pubspec.yaml index 08ec902f..15f91f58 100644 --- a/apps/mobile/packages/core/pubspec.yaml +++ b/apps/mobile/packages/core/pubspec.yaml @@ -25,4 +25,5 @@ dependencies: image_picker: ^1.1.2 path_provider: ^2.1.3 file_picker: ^8.1.7 + record: ^6.2.0 firebase_auth: ^6.1.4 diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/create_order_module.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/create_order_module.dart index e459dd35..d5a51815 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/create_order_module.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/create_order_module.dart @@ -9,6 +9,8 @@ import 'domain/usecases/create_permanent_order_usecase.dart'; import 'domain/usecases/create_recurring_order_usecase.dart'; import 'domain/usecases/create_rapid_order_usecase.dart'; import 'domain/usecases/get_order_details_for_reorder_usecase.dart'; +import 'domain/usecases/parse_rapid_order_usecase.dart'; +import 'domain/usecases/transcribe_rapid_order_usecase.dart'; import 'presentation/blocs/index.dart'; import 'presentation/pages/create_order_page.dart'; import 'presentation/pages/one_time_order_page.dart'; @@ -37,10 +39,18 @@ class ClientCreateOrderModule extends Module { i.addLazySingleton(CreatePermanentOrderUseCase.new); i.addLazySingleton(CreateRecurringOrderUseCase.new); i.addLazySingleton(CreateRapidOrderUseCase.new); + i.addLazySingleton(TranscribeRapidOrderUseCase.new); + i.addLazySingleton(ParseRapidOrderTextToOrderUseCase.new); i.addLazySingleton(GetOrderDetailsForReorderUseCase.new); // BLoCs - i.add(RapidOrderBloc.new); + i.add( + (Injector i) => RapidOrderBloc( + i.get(), + i.get(), + i.get(), + ), + ); i.add(OneTimeOrderBloc.new); i.add(PermanentOrderBloc.new); i.add(RecurringOrderBloc.new); diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart index aea8a443..645ce1df 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart @@ -367,6 +367,51 @@ class ClientCreateOrderRepositoryImpl throw UnimplementedError('Rapid order IA is not connected yet.'); } + @override + Future parseRapidOrder(String text) async { + final RapidOrderParseResponse response = await _rapidOrderService.parseText( + text: text, + ); + final RapidOrderParsedData data = response.parsed; + + final DateTime startAt = + DateTime.tryParse(data.startAt ?? '') ?? DateTime.now(); + final DateTime endAt = + DateTime.tryParse(data.endAt ?? '') ?? + startAt.add(const Duration(hours: 8)); + + final String startTimeStr = DateFormat('hh:mm a').format(startAt); + final String endTimeStr = DateFormat('hh:mm a').format(endAt); + + return domain.OneTimeOrder( + date: startAt, + location: data.locationHint ?? '', + eventName: data.notes ?? '', + hub: data.locationHint != null + ? domain.OneTimeOrderHubDetails( + id: '', + name: data.locationHint!, + address: '', + ) + : null, + positions: data.positions.map((RapidOrderPosition p) { + return domain.OneTimeOrderPosition( + role: p.role, + count: p.count, + startTime: startTimeStr, + endTime: endTimeStr, + ); + }).toList(), + ); + } + + @override + Future transcribeRapidOrder(String audioPath) async { + final RapidOrderTranscriptionResponse response = await _rapidOrderService + .transcribeAudio(audioFileUri: audioPath); + return response.transcript; + } + @override Future reorder(String previousOrderId, DateTime newDate) async { // TODO: Implement reorder functionality to fetch the previous order and create a new one with the updated date. diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/repositories/client_create_order_repository_interface.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/repositories/client_create_order_repository_interface.dart index a2c80cd5..84124804 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/repositories/client_create_order_repository_interface.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/repositories/client_create_order_repository_interface.dart @@ -24,6 +24,16 @@ abstract interface class ClientCreateOrderRepositoryInterface { /// [description] is the text message (or transcribed voice) describing the need. Future createRapidOrder(String description); + /// Transcribes the audio file for a rapid order. + /// + /// [audioPath] is the local path to the recorded audio file. + Future transcribeRapidOrder(String audioPath); + + /// Parses the text description for a rapid order into a structured draft. + /// + /// [text] is the text message describing the need. + Future parseRapidOrder(String text); + /// Reorders an existing staffing order with a new date. /// /// [previousOrderId] is the ID of the order to reorder. diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/usecases/parse_rapid_order_usecase.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/usecases/parse_rapid_order_usecase.dart new file mode 100644 index 00000000..17113b2a --- /dev/null +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/domain/usecases/parse_rapid_order_usecase.dart @@ -0,0 +1,15 @@ +import 'package:krow_domain/krow_domain.dart'; +import '../repositories/client_create_order_repository_interface.dart'; + +/// Use case for parsing rapid order text into a structured OneTimeOrder. +class ParseRapidOrderTextToOrderUseCase { + ParseRapidOrderTextToOrderUseCase({ + required ClientCreateOrderRepositoryInterface repository, + }) : _repository = repository; + + final ClientCreateOrderRepositoryInterface _repository; + + Future call(String text) async { + return _repository.parseRapidOrder(text); + } +} diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_bloc.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_bloc.dart index a255fe7d..7c3a4435 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_bloc.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_bloc.dart @@ -136,9 +136,7 @@ class OneTimeOrderBloc extends Bloc } } - Future _loadManagersForHub( - String hubId, - ) async { + Future _loadManagersForHub(String hubId) async { final List? managers = await handleErrorWithResult( action: () async { @@ -163,7 +161,9 @@ class OneTimeOrderBloc extends Bloc .toList(); }, onError: (_) { - add(const OneTimeOrderManagersLoaded([])); + add( + const OneTimeOrderManagersLoaded([]), + ); }, ); @@ -172,7 +172,6 @@ class OneTimeOrderBloc extends Bloc } } - Future _onVendorsLoaded( OneTimeOrderVendorsLoaded event, Emitter emit, @@ -216,7 +215,6 @@ class OneTimeOrderBloc extends Bloc } } - void _onHubChanged( OneTimeOrderHubChanged event, Emitter emit, @@ -239,7 +237,6 @@ class OneTimeOrderBloc extends Bloc emit(state.copyWith(managers: event.managers)); } - void _onEventNameChanged( OneTimeOrderEventNameChanged event, Emitter emit, @@ -349,6 +346,45 @@ class OneTimeOrderBloc extends Bloc final DateTime? startDate = data['startDate'] as DateTime?; final String? orderId = data['orderId']?.toString(); + // Handle Rapid Order Draft + if (data['isRapidDraft'] == true) { + final OneTimeOrder? order = data['order'] as OneTimeOrder?; + if (order != null) { + emit( + state.copyWith( + eventName: order.eventName ?? '', + date: order.date, + positions: order.positions, + location: order.location, + isRapidDraft: true, + ), + ); + + // Try to match vendor if available + if (order.vendorId != null) { + final Vendor? vendor = state.vendors + .where((Vendor v) => v.id == order.vendorId) + .firstOrNull; + if (vendor != null) { + emit(state.copyWith(selectedVendor: vendor)); + await _loadRolesForVendor(vendor.id, emit); + } + } + + // Try to match hub if available + if (order.hub != null) { + final OneTimeOrderHubOption? hub = state.hubs + .where((OneTimeOrderHubOption h) => h.id == order.hub?.id) + .firstOrNull; + if (hub != null) { + emit(state.copyWith(selectedHub: hub)); + await _loadManagersForHub(hub.id); + } + } + return; + } + } + emit(state.copyWith(eventName: title, date: startDate ?? DateTime.now())); if (orderId == null || orderId.isEmpty) return; diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_state.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_state.dart index b48b9134..c2964f35 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_state.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/one_time_order/one_time_order_state.dart @@ -18,6 +18,7 @@ class OneTimeOrderState extends Equatable { this.roles = const [], this.managers = const [], this.selectedManager, + this.isRapidDraft = false, }); factory OneTimeOrderState.initial() { @@ -47,6 +48,7 @@ class OneTimeOrderState extends Equatable { final List roles; final List managers; final OneTimeOrderManagerOption? selectedManager; + final bool isRapidDraft; OneTimeOrderState copyWith({ DateTime? date, @@ -62,6 +64,7 @@ class OneTimeOrderState extends Equatable { List? roles, List? managers, OneTimeOrderManagerOption? selectedManager, + bool? isRapidDraft, }) { return OneTimeOrderState( date: date ?? this.date, @@ -77,6 +80,7 @@ class OneTimeOrderState extends Equatable { roles: roles ?? this.roles, managers: managers ?? this.managers, selectedManager: selectedManager ?? this.selectedManager, + isRapidDraft: isRapidDraft ?? this.isRapidDraft, ); } @@ -109,6 +113,7 @@ class OneTimeOrderState extends Equatable { roles, managers, selectedManager, + isRapidDraft, ]; } @@ -171,10 +176,7 @@ class OneTimeOrderRoleOption extends Equatable { } class OneTimeOrderManagerOption extends Equatable { - const OneTimeOrderManagerOption({ - required this.id, - required this.name, - }); + const OneTimeOrderManagerOption({required this.id, required this.name}); final String id; final String name; @@ -182,4 +184,3 @@ class OneTimeOrderManagerOption extends Equatable { @override List get props => [id, name]; } - diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_bloc.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_bloc.dart index b9fdedf5..3b957100 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_bloc.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_bloc.dart @@ -1,7 +1,8 @@ -import 'package:client_create_order/src/domain/arguments/rapid_order_arguments.dart'; -import 'package:client_create_order/src/domain/usecases/create_rapid_order_usecase.dart'; +import 'package:client_create_order/src/domain/usecases/parse_rapid_order_usecase.dart'; +import 'package:client_create_order/src/domain/usecases/transcribe_rapid_order_usecase.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:krow_core/core.dart'; +import 'package:krow_domain/krow_domain.dart'; import 'rapid_order_event.dart'; import 'rapid_order_state.dart'; @@ -9,8 +10,11 @@ import 'rapid_order_state.dart'; /// BLoC for managing the rapid (urgent) order creation flow. class RapidOrderBloc extends Bloc with BlocErrorHandler { - RapidOrderBloc(this._createRapidOrderUseCase) - : super( + RapidOrderBloc( + this._transcribeRapidOrderUseCase, + this._parseRapidOrderUseCase, + this._audioRecorderService, + ) : super( const RapidOrderInitial( examples: [ '"We had a call out. Need 2 cooks ASAP"', @@ -24,7 +28,9 @@ class RapidOrderBloc extends Bloc on(_onSubmitted); on(_onExampleSelected); } - final CreateRapidOrderUseCase _createRapidOrderUseCase; + final TranscribeRapidOrderUseCase _transcribeRapidOrderUseCase; + final ParseRapidOrderTextToOrderUseCase _parseRapidOrderUseCase; + final AudioRecorderService _audioRecorderService; void _onMessageChanged( RapidOrderMessageChanged event, @@ -72,10 +78,8 @@ class RapidOrderBloc extends Bloc await handleError( emit: emit.call, action: () async { - await _createRapidOrderUseCase( - RapidOrderArguments(description: message), - ); - emit(const RapidOrderSuccess()); + final OneTimeOrder order = await _parseRapidOrderUseCase(message); + emit(RapidOrderParsed(order)); }, onError: (String errorKey) => RapidOrderFailure(errorKey), ); diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_state.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_state.dart index 6c752b92..88396c09 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_state.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/blocs/rapid_order/rapid_order_state.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:krow_domain/krow_domain.dart'; abstract class RapidOrderState extends Equatable { const RapidOrderState(); @@ -48,3 +49,11 @@ class RapidOrderFailure extends RapidOrderState { @override List get props => [error]; } + +class RapidOrderParsed extends RapidOrderState { + const RapidOrderParsed(this.order); + final OneTimeOrder order; + + @override + List get props => [order]; +} diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/pages/one_time_order_page.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/pages/one_time_order_page.dart index 3c611062..11d8e1d7 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/pages/one_time_order_page.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/pages/one_time_order_page.dart @@ -53,6 +53,7 @@ class OneTimeOrderPage extends StatelessWidget { : null, hubManagers: state.managers.map(_mapManager).toList(), isValid: state.isValid, + title: state.isRapidDraft ? 'Rapid Order : Verify the order' : null, onEventNameChanged: (String val) => bloc.add(OneTimeOrderEventNameChanged(val)), onVendorChanged: (Vendor val) => diff --git a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/widgets/rapid_order/rapid_order_view.dart b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/widgets/rapid_order/rapid_order_view.dart index 08837105..f15757c2 100644 --- a/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/widgets/rapid_order/rapid_order_view.dart +++ b/apps/mobile/packages/features/client/orders/create_order/lib/src/presentation/widgets/rapid_order/rapid_order_view.dart @@ -72,6 +72,13 @@ class _RapidOrderFormState extends State<_RapidOrderForm> { TextPosition(offset: _messageController.text.length), ); } + } else if (state is RapidOrderParsed) { + Modular.to.toCreateOrderOneTime( + arguments: { + 'order': state.order, + 'isRapidDraft': true, + }, + ); } else if (state is RapidOrderFailure) { UiSnackbar.show( context, diff --git a/apps/mobile/packages/features/client/orders/orders_common/lib/src/presentation/widgets/one_time_order/one_time_order_view.dart b/apps/mobile/packages/features/client/orders/orders_common/lib/src/presentation/widgets/one_time_order/one_time_order_view.dart index 4abe0eae..bb80fcc4 100644 --- a/apps/mobile/packages/features/client/orders/orders_common/lib/src/presentation/widgets/one_time_order/one_time_order_view.dart +++ b/apps/mobile/packages/features/client/orders/orders_common/lib/src/presentation/widgets/one_time_order/one_time_order_view.dart @@ -38,6 +38,7 @@ class OneTimeOrderView extends StatelessWidget { required this.onSubmit, required this.onDone, required this.onBack, + this.title, super.key, }); @@ -54,6 +55,7 @@ class OneTimeOrderView extends StatelessWidget { final List hubManagers; final OrderManagerUiModel? selectedHubManager; final bool isValid; + final String? title; final ValueChanged onEventNameChanged; final ValueChanged onVendorChanged; @@ -61,7 +63,8 @@ class OneTimeOrderView extends StatelessWidget { final ValueChanged onHubChanged; final ValueChanged onHubManagerChanged; final VoidCallback onPositionAdded; - final void Function(int index, OrderPositionUiModel position) onPositionUpdated; + final void Function(int index, OrderPositionUiModel position) + onPositionUpdated; final void Function(int index) onPositionRemoved; final VoidCallback onSubmit; final VoidCallback onDone; @@ -98,7 +101,7 @@ class OneTimeOrderView extends StatelessWidget { body: Column( children: [ OneTimeOrderHeader( - title: labels.title, + title: title ?? labels.title, subtitle: labels.subtitle, onBack: onBack, ), @@ -136,7 +139,7 @@ class OneTimeOrderView extends StatelessWidget { body: Column( children: [ OneTimeOrderHeader( - title: labels.title, + title: title ?? labels.title, subtitle: labels.subtitle, onBack: onBack, ), @@ -220,7 +223,8 @@ class _OneTimeOrderForm extends StatelessWidget { final ValueChanged onHubChanged; final ValueChanged onHubManagerChanged; final VoidCallback onPositionAdded; - final void Function(int index, OrderPositionUiModel position) onPositionUpdated; + final void Function(int index, OrderPositionUiModel position) + onPositionUpdated; final void Function(int index) onPositionRemoved; @override @@ -317,10 +321,7 @@ class _OneTimeOrderForm extends StatelessWidget { items: hubs.map((OrderHubUiModel hub) { return DropdownMenuItem( value: hub, - child: Text( - hub.name, - style: UiTypography.body2m.textPrimary, - ), + child: Text(hub.name, style: UiTypography.body2m.textPrimary), ); }).toList(), ), diff --git a/apps/mobile/packages/features/client/orders/orders_common/macos/Flutter/GeneratedPluginRegistrant.swift b/apps/mobile/packages/features/client/orders/orders_common/macos/Flutter/GeneratedPluginRegistrant.swift index 8a0af98d..3eb92bc4 100644 --- a/apps/mobile/packages/features/client/orders/orders_common/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/apps/mobile/packages/features/client/orders/orders_common/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import file_selector_macos import firebase_app_check import firebase_auth import firebase_core +import record_macos import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { @@ -18,5 +19,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/apps/mobile/pubspec.lock b/apps/mobile/pubspec.lock index 07839283..7fd533da 100644 --- a/apps/mobile/pubspec.lock +++ b/apps/mobile/pubspec.lock @@ -1221,6 +1221,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + record: + dependency: transitive + description: + name: record + sha256: d5b6b334f3ab02460db6544e08583c942dbf23e3504bf1e14fd4cbe3d9409277 + url: "https://pub.dev" + source: hosted + version: "6.2.0" + record_android: + dependency: transitive + description: + name: record_android + sha256: "94783f08403aed33ffb68797bf0715b0812eb852f3c7985644c945faea462ba1" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + record_ios: + dependency: transitive + description: + name: record_ios + sha256: "8df7c136131bd05efc19256af29b2ba6ccc000ccc2c80d4b6b6d7a8d21a3b5a9" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + record_linux: + dependency: transitive + description: + name: record_linux + sha256: c31a35cc158cd666fc6395f7f56fc054f31685571684be6b97670a27649ce5c7 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + record_macos: + dependency: transitive + description: + name: record_macos + sha256: "084902e63fc9c0c224c29203d6c75f0bdf9b6a40536c9d916393c8f4c4256488" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + record_platform_interface: + dependency: transitive + description: + name: record_platform_interface + sha256: "8a81dbc4e14e1272a285bbfef6c9136d070a47d9b0d1f40aa6193516253ee2f6" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + record_web: + dependency: transitive + description: + name: record_web + sha256: "7e9846981c1f2d111d86f0ae3309071f5bba8b624d1c977316706f08fc31d16d" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + record_windows: + dependency: transitive + description: + name: record_windows + sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78" + url: "https://pub.dev" + source: hosted + version: "1.0.7" rename: dependency: transitive description: