feat: Implements reception search page
Introduces a dedicated search page for reception operations. Enables navigation to this new page from the 'Reception' quick action component, providing a dedicated interface for searching reception records. Registers the `ReceptionSearchRoute` to integrate it into the application's secure routing system. Also updates the empty state message on the reception list for improved localization and user experience.
This commit is contained in:
parent
d131928235
commit
0b4e5042cc
@ -3,3 +3,4 @@ export 'delivery/delivery_page.dart';
|
|||||||
export 'inventory/inventory_page.dart';
|
export 'inventory/inventory_page.dart';
|
||||||
export 'reception/reception_details_page.dart';
|
export 'reception/reception_details_page.dart';
|
||||||
export 'reception/reception_scan_page.dart';
|
export 'reception/reception_scan_page.dart';
|
||||||
|
export 'reception/reception_search_page.dart';
|
||||||
|
@ -48,7 +48,11 @@ class _ReceptionPageState extends ConsumerState<ReceptionPage> {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
QuickActionComponent(onTapSearch: () {}),
|
QuickActionComponent(
|
||||||
|
onTapSearch: () {
|
||||||
|
ReceptionSearchRoute().push(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Consumer(
|
Consumer(
|
||||||
builder: (_, WidgetRef ref, _) {
|
builder: (_, WidgetRef ref, _) {
|
||||||
@ -67,7 +71,7 @@ class _ReceptionPageState extends ConsumerState<ReceptionPage> {
|
|||||||
// ).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
// ).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
||||||
// ),
|
// ),
|
||||||
state.receptions.isEmpty == true
|
state.receptions.isEmpty == true
|
||||||
? Text('No data')
|
? Center(child: Text('Aucune donnée trouvée'))
|
||||||
: ListView.builder(
|
: ListView.builder(
|
||||||
physics: NeverScrollableScrollPhysics(),
|
physics: NeverScrollableScrollPhysics(),
|
||||||
primary: true,
|
primary: true,
|
||||||
|
71
lib/pages/operation/reception/reception_search_page.dart
Normal file
71
lib/pages/operation/reception/reception_search_page.dart
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import 'package:e_scan/backend/objectbox/entities/stock_picking/stock_picking_record_entity.dart';
|
||||||
|
import 'package:e_scan/components/components.dart';
|
||||||
|
import 'package:e_scan/pages/operation/reception/reception_search_page_model.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:e_scan/components/main_appbar_component.dart';
|
||||||
|
import 'package:e_scan/themes/app_theme.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ReceptionSearchPage extends ConsumerStatefulWidget {
|
||||||
|
const ReceptionSearchPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<ReceptionSearchPage> createState() =>
|
||||||
|
_ReceptionSearchPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReceptionSearchPageState extends ConsumerState<ReceptionSearchPage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final state = ref.watch(receptionSearchPageModelProvider);
|
||||||
|
final receptions = state.valueOrNull ?? <StockPickingRecordEntity>[];
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppTheme.of(context).primaryBackground,
|
||||||
|
appBar: MainAppbarComponent(
|
||||||
|
leading: BackButton(color: AppTheme.of(context).white),
|
||||||
|
title: "Rechercher une réception",
|
||||||
|
subTitle: "Opérations d'Entrepôt",
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: TextFormField(
|
||||||
|
autofocus: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Nom de la réception",
|
||||||
|
filled: true,
|
||||||
|
fillColor: AppTheme.of(context).secondaryBackground,
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
ref
|
||||||
|
.read(receptionSearchPageModelProvider.notifier)
|
||||||
|
.allByName(name: value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: state.isLoading
|
||||||
|
? Center(child: LoadingProgressComponent())
|
||||||
|
: receptions.isEmpty
|
||||||
|
? Center(child: Text('Aucun résultat trouvé'))
|
||||||
|
: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: receptions
|
||||||
|
.map(
|
||||||
|
(reception) =>
|
||||||
|
ListTile(title: Text(reception.name ?? '')),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:e_scan/backend/api/api_calls.dart';
|
||||||
|
import 'package:e_scan/backend/objectbox/entities/stock_picking/stock_picking_record_entity.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
final receptionSearchPageModelProvider =
|
||||||
|
StateNotifierProvider.autoDispose<
|
||||||
|
ReceptionSearchPageModel,
|
||||||
|
AsyncValue<List<StockPickingRecordEntity>>
|
||||||
|
>((ref) {
|
||||||
|
return ReceptionSearchPageModel();
|
||||||
|
});
|
||||||
|
|
||||||
|
class ReceptionSearchPageModel
|
||||||
|
extends StateNotifier<AsyncValue<List<StockPickingRecordEntity>>> {
|
||||||
|
/// Constructor initializes the TaskRepository using the provider reference.
|
||||||
|
ReceptionSearchPageModel() : super(const AsyncValue.loading());
|
||||||
|
|
||||||
|
Future<void> allByName({required String name}) async {
|
||||||
|
try {
|
||||||
|
state = AsyncValue.loading();
|
||||||
|
final res = await ApiCalls.getAllStockPiking();
|
||||||
|
res.when(
|
||||||
|
(data) async {
|
||||||
|
final founds = data
|
||||||
|
.where((e) => e.name?.contains(name) == true)
|
||||||
|
.toList();
|
||||||
|
state = AsyncValue.data(founds);
|
||||||
|
},
|
||||||
|
(error) {
|
||||||
|
state = AsyncValue.error(error, StackTrace.current);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
state = AsyncValue.error(e, StackTrace.current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ final appSecureRoutes = $appRoutes;
|
|||||||
TypedGoRoute<InventoryRoute>(path: 'InventoryPage'),
|
TypedGoRoute<InventoryRoute>(path: 'InventoryPage'),
|
||||||
TypedGoRoute<ReceptionDetailsRoute>(path: 'ReceptionDetailsPage'),
|
TypedGoRoute<ReceptionDetailsRoute>(path: 'ReceptionDetailsPage'),
|
||||||
TypedGoRoute<ReceptionScanRoute>(path: 'ReceptionScanPage'),
|
TypedGoRoute<ReceptionScanRoute>(path: 'ReceptionScanPage'),
|
||||||
|
TypedGoRoute<ReceptionSearchRoute>(path: 'ReceptionSearchPage'),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
class SecureRoute extends GoRouteData with _$SecureRoute {
|
class SecureRoute extends GoRouteData with _$SecureRoute {
|
||||||
@ -122,3 +123,17 @@ class ReceptionScanRoute extends GoRouteData with _$ReceptionScanRoute {
|
|||||||
Widget build(BuildContext context, GoRouterState state) =>
|
Widget build(BuildContext context, GoRouterState state) =>
|
||||||
ReceptionScanPage(receptionId: receptionId);
|
ReceptionScanPage(receptionId: receptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReceptionSearchRoute extends GoRouteData with _$ReceptionSearchRoute {
|
||||||
|
const ReceptionSearchRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
CustomTransitionPage<void> buildPage(
|
||||||
|
BuildContext context,
|
||||||
|
GoRouterState state,
|
||||||
|
) => buildPageWithDefaultTransition(
|
||||||
|
context: context,
|
||||||
|
state: state,
|
||||||
|
child: ReceptionSearchPage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -49,6 +49,11 @@ RouteBase get $secureRoute => GoRouteData.$route(
|
|||||||
|
|
||||||
factory: _$ReceptionScanRoute._fromState,
|
factory: _$ReceptionScanRoute._fromState,
|
||||||
),
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'ReceptionSearchPage',
|
||||||
|
|
||||||
|
factory: _$ReceptionSearchRoute._fromState,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -256,3 +261,25 @@ mixin _$ReceptionScanRoute on GoRouteData {
|
|||||||
@override
|
@override
|
||||||
void replace(BuildContext context) => context.replace(location);
|
void replace(BuildContext context) => context.replace(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixin _$ReceptionSearchRoute on GoRouteData {
|
||||||
|
static ReceptionSearchRoute _fromState(GoRouterState state) =>
|
||||||
|
const ReceptionSearchRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get location =>
|
||||||
|
GoRouteData.$location('/SecurePage/ReceptionSearchPage');
|
||||||
|
|
||||||
|
@override
|
||||||
|
void go(BuildContext context) => context.go(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void pushReplacement(BuildContext context) =>
|
||||||
|
context.pushReplacement(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(BuildContext context) => context.replace(location);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user