mandreshope 8252cf0b22 feat: Adds stock picking detail view and API call
Implements a dedicated page for viewing detailed stock picking information.

- Introduces `getStockPikingById` API call to fetch a single stock picking record by ID.
- Enhances `MainAppbarComponent` to support customizable leading widgets, enabling a back button on detail pages.
- Improves `QuickActionComponent` by allowing optional `onTap` callbacks for actions, making buttons conditionally visible and reusable across different contexts.
- Adds `margin` property to `StockPickingCard` for flexible layout adjustments.
- Refactors `ReceptionDetailsPage` to utilize the new API call and display a single stock picking's details, adapting its app bar and quick actions accordingly.
2025-07-29 14:43:43 +03:00

121 lines
4.9 KiB
Dart

import 'package:barcode_scanner/backend/schema/stock_picking/stock_picking_model.dart';
import 'package:barcode_scanner/components/components.dart';
import 'package:barcode_scanner/pages/operation/reception/reception_page_model.dart';
import 'package:barcode_scanner/router/go_secure_router_builder.dart';
import 'package:barcode_scanner/themes/app_theme.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
class ReceptionPage extends ConsumerStatefulWidget {
const ReceptionPage({super.key});
@override
ConsumerState<ReceptionPage> createState() => _ReceptionPageState();
}
class _ReceptionPageState extends ConsumerState<ReceptionPage> {
final globalKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
ref.read(receptionPageModelProvider.notifier).getUserConnected();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.of(context).primaryBackground,
key: globalKey,
drawer: DrawerComponent(isOperationExpanded: true),
appBar: MainAppbarComponent(
scaffoledKey: globalKey,
title: "Réceptions",
subTitle: "Opérations d'Entrepôt",
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ListView(
children: [
const SizedBox(height: 16),
QuickActionComponent(
onTapAdd: () {},
onTapScan: () {},
onTapSearch: () {},
),
const SizedBox(height: 16),
Consumer(
builder: (_, WidgetRef ref, _) {
final state = ref.watch(receptionPageModelProvider);
if (state.loadingReceptions) {
return Center(child: LoadingProgressComponent());
}
return Card(
color: AppTheme.of(context).secondaryBackground,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: BorderSide(color: AppTheme.of(context).alternate),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
spacing: 10,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Réceptions',
style: AppTheme.of(
context,
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
),
state.receptions?.result?.records?.isEmpty == true
? Text('No data')
: ListView.builder(
physics: NeverScrollableScrollPhysics(),
primary: true,
shrinkWrap: true,
itemCount:
(state.receptions?.result?.records ??
<StockPickingRecordModel>[])
.length,
itemBuilder: (context, index) {
final reception =
state.receptions?.result?.records![index];
return GestureDetector(
onTap: () {
final id = reception?.id;
if (id == null) return;
ReceptionDetailsRoute(
receptionId: id,
).push(context);
},
child: StockPickingCard(
reference: reception?.name ?? '',
from: reception?.locationId?.completeName,
to: reception
?.locationDestId
?.completeName,
contact:
reception?.partnerId?.displayName,
origin: reception?.origin,
status: reception?.state,
),
);
},
),
],
),
),
);
},
),
],
),
),
);
}
}