
Configures the ObjectBox ProductEntity to allow assigning IDs. Adds a helper to convert ProductStruct to ProductEntity for easier storage. Saves scanned products directly to the local ObjectBox store. Updates the ProductListPage to fetch and display locally stored products from ObjectBox upon initialization. Includes minor UI adjustments in the scanned product component and scanner page, and fixes loading state handling in HomePageModel.
184 lines
7.1 KiB
Dart
184 lines
7.1 KiB
Dart
import 'package:barcode_scanner/backend/schema/product/product_struct.dart';
|
|
import 'package:barcode_scanner/themes/app_theme.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
class ProductScannedComponent extends StatefulWidget {
|
|
const ProductScannedComponent({
|
|
super.key,
|
|
required this.productStruct,
|
|
this.onRescan,
|
|
this.onDetails,
|
|
});
|
|
final ProductStruct productStruct;
|
|
|
|
final Future Function()? onRescan;
|
|
final Function()? onDetails;
|
|
|
|
@override
|
|
State<ProductScannedComponent> createState() =>
|
|
_ProductScannedComponentState();
|
|
}
|
|
|
|
class _ProductScannedComponentState extends State<ProductScannedComponent> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.all(24.0),
|
|
child: Container(
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
color: AppTheme.of(context).secondaryBackground,
|
|
borderRadius: BorderRadius.circular(16.0),
|
|
),
|
|
child: Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
spacing: 16,
|
|
children: [
|
|
Container(
|
|
width: 80.0,
|
|
height: 80.0,
|
|
decoration: BoxDecoration(
|
|
color: Colors.green,
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: Align(
|
|
alignment: AlignmentDirectional(0.0, 0.0),
|
|
child: Icon(
|
|
Icons.check_rounded,
|
|
color: Colors.white,
|
|
size: 40.0,
|
|
),
|
|
),
|
|
),
|
|
Text('Scan terminé!', textAlign: TextAlign.center),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 16.0),
|
|
child: SizedBox(
|
|
width: double.infinity,
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 16.0),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
spacing: 8,
|
|
children: [
|
|
Align(
|
|
alignment: Alignment.topCenter,
|
|
child: Image.network(
|
|
widget.productStruct.image ?? '',
|
|
height: MediaQuery.sizeOf(context).height * .12,
|
|
),
|
|
),
|
|
SizedBox(height: 15),
|
|
Divider(
|
|
height: 1.0,
|
|
thickness: 1.0,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('Code scanné:'),
|
|
Text(widget.productStruct.id.toString()),
|
|
],
|
|
),
|
|
Divider(
|
|
height: 1.0,
|
|
thickness: 1.0,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Produit: '),
|
|
Expanded(
|
|
child: Text(
|
|
widget.productStruct.name ?? '',
|
|
textAlign: TextAlign.end,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Divider(
|
|
height: 1.0,
|
|
thickness: 1.0,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('Quantité:'),
|
|
Text(widget.productStruct.quantity ?? ''),
|
|
],
|
|
),
|
|
Divider(
|
|
height: 1.0,
|
|
thickness: 1.0,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
// Row(
|
|
// mainAxisSize: MainAxisSize.max,
|
|
// mainAxisAlignment:
|
|
// MainAxisAlignment.spaceBetween,
|
|
// children: [Text('Prix:'), Text('4,99 €')],
|
|
// ),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
spacing: 12,
|
|
children: [
|
|
Expanded(
|
|
child: FilledButton.tonal(
|
|
onPressed: () async {
|
|
await widget.onRescan?.call();
|
|
},
|
|
child: Text(
|
|
'Nouveau scan',
|
|
style: AppTheme.of(context).bodyMedium,
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: FilledButton(
|
|
style: ButtonStyle(
|
|
backgroundColor: WidgetStatePropertyAll(
|
|
AppTheme.of(context).primary,
|
|
),
|
|
),
|
|
onPressed: () {
|
|
widget.onDetails?.call();
|
|
},
|
|
child: Text(
|
|
'Voir détails',
|
|
style: AppTheme.of(context).bodyMedium.override(
|
|
color: AppTheme.of(context).white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|