feat: Adds product image field to data models
Includes an `image` field in the `ProductStruct` and `ProductEntity` data models. Updates the ObjectBox schema and regenerates the necessary code to persist the new field. Refactors the `ProductScannedComponent` to accept a `ProductStruct` object, simplifying parameter passing. Updates the `ScannerPage` to build and pass the `ProductStruct` to the component, enabling the display of the product image and using the structured data for other details like quantity. The 'Marque' display is replaced with 'Quantité' in the component.
This commit is contained in:
parent
8eddb5d4b7
commit
44289e29dc
@ -12,6 +12,7 @@ class ProductEntity {
|
||||
String? description;
|
||||
String? price;
|
||||
String? quantity;
|
||||
String? image;
|
||||
|
||||
ProductEntity({
|
||||
this.id = 0,
|
||||
@ -20,6 +21,7 @@ class ProductEntity {
|
||||
this.description,
|
||||
this.price,
|
||||
this.quantity,
|
||||
this.image,
|
||||
});
|
||||
|
||||
/// Convertir vers ProductStruct
|
||||
@ -31,6 +33,7 @@ class ProductEntity {
|
||||
description: description,
|
||||
price: price,
|
||||
quantity: quantity,
|
||||
image: image,
|
||||
);
|
||||
}
|
||||
|
||||
@ -43,6 +46,7 @@ class ProductEntity {
|
||||
description: struct.description,
|
||||
price: struct.price,
|
||||
quantity: struct.quantity,
|
||||
image: struct.image,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
"entities": [
|
||||
{
|
||||
"id": "1:6757833172062715556",
|
||||
"lastPropertyId": "6:7033704955625644592",
|
||||
"lastPropertyId": "7:1825580906382154543",
|
||||
"name": "ProductEntity",
|
||||
"properties": [
|
||||
{
|
||||
@ -38,6 +38,11 @@
|
||||
"id": "6:7033704955625644592",
|
||||
"name": "quantity",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "7:1825580906382154543",
|
||||
"name": "image",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
|
@ -22,7 +22,7 @@ final _entities = <obx_int.ModelEntity>[
|
||||
obx_int.ModelEntity(
|
||||
id: const obx_int.IdUid(1, 6757833172062715556),
|
||||
name: 'ProductEntity',
|
||||
lastPropertyId: const obx_int.IdUid(6, 7033704955625644592),
|
||||
lastPropertyId: const obx_int.IdUid(7, 1825580906382154543),
|
||||
flags: 0,
|
||||
properties: <obx_int.ModelProperty>[
|
||||
obx_int.ModelProperty(
|
||||
@ -61,6 +61,12 @@ final _entities = <obx_int.ModelEntity>[
|
||||
type: 9,
|
||||
flags: 0,
|
||||
),
|
||||
obx_int.ModelProperty(
|
||||
id: const obx_int.IdUid(7, 1825580906382154543),
|
||||
name: 'image',
|
||||
type: 9,
|
||||
flags: 0,
|
||||
),
|
||||
],
|
||||
relations: <obx_int.ModelRelation>[],
|
||||
backlinks: <obx_int.ModelBacklink>[],
|
||||
@ -143,13 +149,17 @@ obx_int.ModelDefinition getObjectBoxModel() {
|
||||
final quantityOffset = object.quantity == null
|
||||
? null
|
||||
: fbb.writeString(object.quantity!);
|
||||
fbb.startTable(7);
|
||||
final imageOffset = object.image == null
|
||||
? null
|
||||
: fbb.writeString(object.image!);
|
||||
fbb.startTable(8);
|
||||
fbb.addInt64(0, object.id);
|
||||
fbb.addOffset(1, codeOffset);
|
||||
fbb.addOffset(2, nameOffset);
|
||||
fbb.addOffset(3, descriptionOffset);
|
||||
fbb.addOffset(4, priceOffset);
|
||||
fbb.addOffset(5, quantityOffset);
|
||||
fbb.addOffset(6, imageOffset);
|
||||
fbb.finish(fbb.endTable());
|
||||
return object.id;
|
||||
},
|
||||
@ -177,6 +187,9 @@ obx_int.ModelDefinition getObjectBoxModel() {
|
||||
final quantityParam = const fb.StringReader(
|
||||
asciiOptimization: true,
|
||||
).vTableGetNullable(buffer, rootOffset, 14);
|
||||
final imageParam = const fb.StringReader(
|
||||
asciiOptimization: true,
|
||||
).vTableGetNullable(buffer, rootOffset, 16);
|
||||
final object = ProductEntity(
|
||||
id: idParam,
|
||||
code: codeParam,
|
||||
@ -184,6 +197,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
|
||||
description: descriptionParam,
|
||||
price: priceParam,
|
||||
quantity: quantityParam,
|
||||
image: imageParam,
|
||||
);
|
||||
|
||||
return object;
|
||||
@ -225,4 +239,9 @@ class ProductEntity_ {
|
||||
static final quantity = obx.QueryStringProperty<ProductEntity>(
|
||||
_entities[0].properties[5],
|
||||
);
|
||||
|
||||
/// See [ProductEntity.image].
|
||||
static final image = obx.QueryStringProperty<ProductEntity>(
|
||||
_entities[0].properties[6],
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ abstract class ProductStruct with _$ProductStruct {
|
||||
String? description,
|
||||
String? price,
|
||||
String? quantity,
|
||||
String? image,
|
||||
}) = _ProductStruct;
|
||||
|
||||
factory ProductStruct.fromJson(Map<String, dynamic> json) =>
|
||||
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ProductStruct {
|
||||
|
||||
int get id; String? get code; String? get name; String? get description; String? get price; String? get quantity;
|
||||
int get id; String? get code; String? get name; String? get description; String? get price; String? get quantity; String? get image;
|
||||
/// Create a copy of ProductStruct
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -29,16 +29,16 @@ $ProductStructCopyWith<ProductStruct> get copyWith => _$ProductStructCopyWithImp
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProductStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.code, code) || other.code == code)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.price, price) || other.price == price)&&(identical(other.quantity, quantity) || other.quantity == quantity));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProductStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.code, code) || other.code == code)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.price, price) || other.price == price)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.image, image) || other.image == image));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity);
|
||||
int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity,image);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity)';
|
||||
return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity, image: $image)';
|
||||
}
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ abstract mixin class $ProductStructCopyWith<$Res> {
|
||||
factory $ProductStructCopyWith(ProductStruct value, $Res Function(ProductStruct) _then) = _$ProductStructCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int id, String? code, String? name, String? description, String? price, String? quantity
|
||||
int id, String? code, String? name, String? description, String? price, String? quantity, String? image
|
||||
});
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ class _$ProductStructCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of ProductStruct
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,Object? image = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as int,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable
|
||||
@ -74,6 +74,7 @@ as String?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to
|
||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,price: freezed == price ? _self.price : price // ignore: cast_nullable_to_non_nullable
|
||||
as String?,quantity: freezed == quantity ? _self.quantity : quantity // ignore: cast_nullable_to_non_nullable
|
||||
as String?,image: freezed == image ? _self.image : image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
@ -85,7 +86,7 @@ as String?,
|
||||
@JsonSerializable()
|
||||
|
||||
class _ProductStruct implements ProductStruct {
|
||||
_ProductStruct({this.id = 0, this.code, this.name, this.description, this.price, this.quantity});
|
||||
_ProductStruct({this.id = 0, this.code, this.name, this.description, this.price, this.quantity, this.image});
|
||||
factory _ProductStruct.fromJson(Map<String, dynamic> json) => _$ProductStructFromJson(json);
|
||||
|
||||
@override@JsonKey() final int id;
|
||||
@ -94,6 +95,7 @@ class _ProductStruct implements ProductStruct {
|
||||
@override final String? description;
|
||||
@override final String? price;
|
||||
@override final String? quantity;
|
||||
@override final String? image;
|
||||
|
||||
/// Create a copy of ProductStruct
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@ -108,16 +110,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProductStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.code, code) || other.code == code)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.price, price) || other.price == price)&&(identical(other.quantity, quantity) || other.quantity == quantity));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProductStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.code, code) || other.code == code)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.price, price) || other.price == price)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.image, image) || other.image == image));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity);
|
||||
int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity,image);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity)';
|
||||
return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity, image: $image)';
|
||||
}
|
||||
|
||||
|
||||
@ -128,7 +130,7 @@ abstract mixin class _$ProductStructCopyWith<$Res> implements $ProductStructCopy
|
||||
factory _$ProductStructCopyWith(_ProductStruct value, $Res Function(_ProductStruct) _then) = __$ProductStructCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int id, String? code, String? name, String? description, String? price, String? quantity
|
||||
int id, String? code, String? name, String? description, String? price, String? quantity, String? image
|
||||
});
|
||||
|
||||
|
||||
@ -145,7 +147,7 @@ class __$ProductStructCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of ProductStruct
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,Object? image = freezed,}) {
|
||||
return _then(_ProductStruct(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as int,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable
|
||||
@ -153,6 +155,7 @@ as String?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to
|
||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,price: freezed == price ? _self.price : price // ignore: cast_nullable_to_non_nullable
|
||||
as String?,quantity: freezed == quantity ? _self.quantity : quantity // ignore: cast_nullable_to_non_nullable
|
||||
as String?,image: freezed == image ? _self.image : image // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ _ProductStruct _$ProductStructFromJson(Map<String, dynamic> json) =>
|
||||
description: json['description'] as String?,
|
||||
price: json['price'] as String?,
|
||||
quantity: json['quantity'] as String?,
|
||||
image: json['image'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ProductStructToJson(_ProductStruct instance) =>
|
||||
@ -24,4 +25,5 @@ Map<String, dynamic> _$ProductStructToJson(_ProductStruct instance) =>
|
||||
'description': instance.description,
|
||||
'price': instance.price,
|
||||
'quantity': instance.quantity,
|
||||
'image': instance.image,
|
||||
};
|
||||
|
@ -1,20 +1,16 @@
|
||||
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.codeScanned,
|
||||
required this.productName,
|
||||
required this.brands,
|
||||
required this.img,
|
||||
required this.productStruct,
|
||||
this.onRescan,
|
||||
this.onDetails,
|
||||
});
|
||||
final String codeScanned;
|
||||
final String productName;
|
||||
final String brands;
|
||||
final String img;
|
||||
final ProductStruct productStruct;
|
||||
|
||||
final Future Function()? onRescan;
|
||||
final Function()? onDetails;
|
||||
|
||||
@ -76,7 +72,7 @@ class _ProductScannedComponentState extends State<ProductScannedComponent> {
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Image.network(
|
||||
widget.img,
|
||||
widget.productStruct.image ?? '',
|
||||
height: MediaQuery.sizeOf(context).height * .2,
|
||||
),
|
||||
),
|
||||
@ -91,7 +87,7 @@ class _ProductScannedComponentState extends State<ProductScannedComponent> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Code scanné:'),
|
||||
Text(widget.codeScanned),
|
||||
Text(widget.productStruct.id.toString()),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
@ -106,7 +102,7 @@ class _ProductScannedComponentState extends State<ProductScannedComponent> {
|
||||
Text('Produit: '),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.productName,
|
||||
widget.productStruct.name ?? '',
|
||||
textAlign: TextAlign.end,
|
||||
),
|
||||
),
|
||||
@ -120,7 +116,10 @@ class _ProductScannedComponentState extends State<ProductScannedComponent> {
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [Text('Marque:'), Text(widget.brands)],
|
||||
children: [
|
||||
Text('Quantité:'),
|
||||
Text(widget.productStruct.quantity ?? ''),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
height: 1.0,
|
||||
|
@ -95,7 +95,7 @@ class LoginPageModel extends StateNotifier<LoginPageState> {
|
||||
user.setToLocalStorage(),
|
||||
]);
|
||||
state = state.copyWith(loading: false, status: LoginPageStateStatus.logged);
|
||||
debugPrint("$token");
|
||||
debugPrint(token);
|
||||
}
|
||||
|
||||
Future<void> logOut() async {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:barcode_scanner/backend/api/api_calls.dart';
|
||||
import 'package:barcode_scanner/backend/schema/product/product_struct.dart';
|
||||
import 'package:barcode_scanner/components/product_scanned_component.dart';
|
||||
import 'package:barcode_scanner/router/go_secure_router_builder.dart';
|
||||
import 'package:barcode_scanner/themes/app_theme.dart';
|
||||
@ -104,6 +105,13 @@ class _ScannerPageState extends ConsumerState<ScannerPage>
|
||||
debugPrint('Nom du produit : ${product["product_name"]}');
|
||||
debugPrint('Marque : ${product["brands"]}');
|
||||
debugPrint('Image : ${product["image_url"]}');
|
||||
final productStruct = ProductStruct(
|
||||
id: int.parse(product["id"]),
|
||||
name: product["product_name"],
|
||||
image: product["image_thumb_url"],
|
||||
description: product["categories"],
|
||||
quantity: product["quantity"],
|
||||
);
|
||||
//show dialog
|
||||
await showDialog(
|
||||
barrierDismissible: false,
|
||||
@ -125,10 +133,7 @@ class _ScannerPageState extends ConsumerState<ScannerPage>
|
||||
child: SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width * 0.9,
|
||||
child: ProductScannedComponent(
|
||||
img: product["image_url"],
|
||||
productName: product["product_name"],
|
||||
brands: product["brands"],
|
||||
codeScanned: qrcodeValue,
|
||||
productStruct: productStruct,
|
||||
onRescan: () async {
|
||||
Navigator.of(context).pop();
|
||||
qrcodeFound = false;
|
||||
@ -171,6 +176,13 @@ class _ScannerPageState extends ConsumerState<ScannerPage>
|
||||
debugPrint('Nom du produit : ${product["product_name"]}');
|
||||
debugPrint('Marque : ${product["brands"]}');
|
||||
debugPrint('Image : ${product["image_url"]}');
|
||||
final productStruct = ProductStruct(
|
||||
id: int.parse(product["id"]),
|
||||
image: product["image_thumb_url"],
|
||||
name: product["product_name"],
|
||||
description: product["categories"],
|
||||
quantity: product["quantity"],
|
||||
);
|
||||
//show dialog
|
||||
await showDialog(
|
||||
barrierDismissible: false,
|
||||
@ -192,10 +204,7 @@ class _ScannerPageState extends ConsumerState<ScannerPage>
|
||||
child: SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width * 0.9,
|
||||
child: ProductScannedComponent(
|
||||
img: product["image_url"],
|
||||
productName: product["product_name"],
|
||||
brands: product["brands"],
|
||||
codeScanned: qrcodeValue,
|
||||
productStruct: productStruct,
|
||||
onRescan: () async {
|
||||
Navigator.of(context).pop();
|
||||
qrcodeFound = false;
|
||||
@ -245,7 +254,7 @@ class _ScannerPageState extends ConsumerState<ScannerPage>
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.help_outline, color: Colors.white, size: 24.0),
|
||||
onPressed: () {
|
||||
print('IconButton pressed ...');
|
||||
debugPrint('IconButton pressed ...');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user