mandreshope 41a660db9a feat: Displays recent stock receptions
Fetches and displays a list of recent stock reception operations on the reception page.

Introduces a new `StockPickingCard` component to present each reception record clearly and consistently. The `ReceptionPageModel` now automatically fetches reception data upon initialization. Provides visual feedback for loading states and when no reception data is available, enhancing the user's overview of recent activities.
2025-07-29 12:07:29 +03:00

161 lines
5.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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/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) {
final state = ref.watch(receptionPageModelProvider);
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(),
const SizedBox(height: 16),
Card(
color: AppTheme.of(context).primaryBackground,
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 récentes',
style: AppTheme.of(
context,
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
),
state.receptions?.result?.records?.isEmpty == true
? Text('No data')
: ListView.builder(
primary: true,
shrinkWrap: true,
itemCount:
(state.receptions?.result?.records ??
<StockPickingRecordModel>[])
.length,
itemBuilder: (context, index) {
final record =
state.receptions?.result?.records![index];
return StockPickingCard(
reference: record?.name ?? '',
from: record?.locationId?.completeName,
to: record?.locationDestId?.completeName,
contact: record?.partnerId?.displayName,
origin: record?.origin,
status: record?.state,
);
},
),
],
),
),
),
],
),
),
);
}
}
class StockPickingCard extends StatelessWidget {
const StockPickingCard({
super.key,
required this.reference,
required this.from,
required this.to,
required this.contact,
required this.origin,
required this.status,
});
final String? reference;
final String? from;
final String? to;
final String? contact;
final String? origin;
final String? status;
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
reference ?? 'Référence inconnue',
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
_infoRow("De", from),
_infoRow("Vers", to),
_infoRow("Contact", contact),
_infoRow("Document dorigine", origin),
_infoRow("Statut", status),
],
),
),
);
}
Widget _infoRow(String label, String? value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: Row(
children: [
Text(
"$label : ",
style: const TextStyle(fontWeight: FontWeight.w600),
),
Expanded(
child: Text(
value ?? "-",
style: const TextStyle(color: Colors.black87),
),
),
],
),
);
}
}