diff --git a/lib/backend/schema/auth/auth_struct.dart b/lib/backend/schema/auth/auth_struct.dart new file mode 100644 index 0000000..d3edd2b --- /dev/null +++ b/lib/backend/schema/auth/auth_struct.dart @@ -0,0 +1,17 @@ +import 'package:barcode_scanner/backend/schema/user/user_struct.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'auth_struct.freezed.dart'; +part 'auth_struct.g.dart'; + +@Freezed(toJson: false) +abstract class AuthStruct with _$AuthStruct { + factory AuthStruct({ + String? accessToken, + String? refreshToken, + UserStruct? user, + }) = _AuthStruct; + + factory AuthStruct.fromJson(Map json) => + _$AuthStructFromJson(json); +} diff --git a/lib/backend/schema/auth/auth_struct.freezed.dart b/lib/backend/schema/auth/auth_struct.freezed.dart new file mode 100644 index 0000000..86c1f5b --- /dev/null +++ b/lib/backend/schema/auth/auth_struct.freezed.dart @@ -0,0 +1,173 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'auth_struct.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$AuthStruct { + + String? get accessToken; String? get refreshToken; UserStruct? get user; +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$AuthStructCopyWith get copyWith => _$AuthStructCopyWithImpl(this as AuthStruct, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is AuthStruct&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)&&(identical(other.user, user) || other.user == user)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,accessToken,refreshToken,user); + +@override +String toString() { + return 'AuthStruct(accessToken: $accessToken, refreshToken: $refreshToken, user: $user)'; +} + + +} + +/// @nodoc +abstract mixin class $AuthStructCopyWith<$Res> { + factory $AuthStructCopyWith(AuthStruct value, $Res Function(AuthStruct) _then) = _$AuthStructCopyWithImpl; +@useResult +$Res call({ + String? accessToken, String? refreshToken, UserStruct? user +}); + + +$UserStructCopyWith<$Res>? get user; + +} +/// @nodoc +class _$AuthStructCopyWithImpl<$Res> + implements $AuthStructCopyWith<$Res> { + _$AuthStructCopyWithImpl(this._self, this._then); + + final AuthStruct _self; + final $Res Function(AuthStruct) _then; + +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? accessToken = freezed,Object? refreshToken = freezed,Object? user = freezed,}) { + return _then(_self.copyWith( +accessToken: freezed == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable +as String?,refreshToken: freezed == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +as String?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserStruct?, + )); +} +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserStructCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserStructCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + + +/// @nodoc +@JsonSerializable(createToJson: false) + +class _AuthStruct implements AuthStruct { + _AuthStruct({this.accessToken, this.refreshToken, this.user}); + factory _AuthStruct.fromJson(Map json) => _$AuthStructFromJson(json); + +@override final String? accessToken; +@override final String? refreshToken; +@override final UserStruct? user; + +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$AuthStructCopyWith<_AuthStruct> get copyWith => __$AuthStructCopyWithImpl<_AuthStruct>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _AuthStruct&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)&&(identical(other.user, user) || other.user == user)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,accessToken,refreshToken,user); + +@override +String toString() { + return 'AuthStruct(accessToken: $accessToken, refreshToken: $refreshToken, user: $user)'; +} + + +} + +/// @nodoc +abstract mixin class _$AuthStructCopyWith<$Res> implements $AuthStructCopyWith<$Res> { + factory _$AuthStructCopyWith(_AuthStruct value, $Res Function(_AuthStruct) _then) = __$AuthStructCopyWithImpl; +@override @useResult +$Res call({ + String? accessToken, String? refreshToken, UserStruct? user +}); + + +@override $UserStructCopyWith<$Res>? get user; + +} +/// @nodoc +class __$AuthStructCopyWithImpl<$Res> + implements _$AuthStructCopyWith<$Res> { + __$AuthStructCopyWithImpl(this._self, this._then); + + final _AuthStruct _self; + final $Res Function(_AuthStruct) _then; + +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? accessToken = freezed,Object? refreshToken = freezed,Object? user = freezed,}) { + return _then(_AuthStruct( +accessToken: freezed == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable +as String?,refreshToken: freezed == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +as String?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserStruct?, + )); +} + +/// Create a copy of AuthStruct +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserStructCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserStructCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + +// dart format on diff --git a/lib/backend/schema/auth/auth_struct.g.dart b/lib/backend/schema/auth/auth_struct.g.dart new file mode 100644 index 0000000..dd22839 --- /dev/null +++ b/lib/backend/schema/auth/auth_struct.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'auth_struct.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_AuthStruct _$AuthStructFromJson(Map json) => _AuthStruct( + accessToken: json['accessToken'] as String?, + refreshToken: json['refreshToken'] as String?, + user: json['user'] == null + ? null + : UserStruct.fromJson(json['user'] as Map), +); diff --git a/lib/backend/schema/product/product_struct.dart b/lib/backend/schema/product/product_struct.dart new file mode 100644 index 0000000..0bb386d --- /dev/null +++ b/lib/backend/schema/product/product_struct.dart @@ -0,0 +1,19 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'product_struct.freezed.dart'; +part 'product_struct.g.dart'; + +@Freezed(toJson: true) +abstract class ProductStruct with _$ProductStruct { + factory ProductStruct({ + String? id, + String? code, + String? name, + String? description, + String? price, + String? quantity, + }) = _ProductStruct; + + factory ProductStruct.fromJson(Map json) => + _$ProductStructFromJson(json); +} diff --git a/lib/backend/schema/product/product_struct.freezed.dart b/lib/backend/schema/product/product_struct.freezed.dart new file mode 100644 index 0000000..a49f41e --- /dev/null +++ b/lib/backend/schema/product/product_struct.freezed.dart @@ -0,0 +1,163 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'product_struct.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$ProductStruct { + + String? get id; String? get code; String? get name; String? get description; String? get price; String? get quantity; +/// Create a copy of ProductStruct +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ProductStructCopyWith get copyWith => _$ProductStructCopyWithImpl(this as ProductStruct, _$identity); + + /// Serializes this ProductStruct to a JSON map. + Map 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)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity); + +@override +String toString() { + return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity)'; +} + + +} + +/// @nodoc +abstract mixin class $ProductStructCopyWith<$Res> { + factory $ProductStructCopyWith(ProductStruct value, $Res Function(ProductStruct) _then) = _$ProductStructCopyWithImpl; +@useResult +$Res call({ + String? id, String? code, String? name, String? description, String? price, String? quantity +}); + + + + +} +/// @nodoc +class _$ProductStructCopyWithImpl<$Res> + implements $ProductStructCopyWith<$Res> { + _$ProductStructCopyWithImpl(this._self, this._then); + + final ProductStruct _self; + final $Res Function(ProductStruct) _then; + +/// 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 = freezed,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable +as String?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +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?, + )); +} + +} + + +/// @nodoc +@JsonSerializable() + +class _ProductStruct implements ProductStruct { + _ProductStruct({this.id, this.code, this.name, this.description, this.price, this.quantity}); + factory _ProductStruct.fromJson(Map json) => _$ProductStructFromJson(json); + +@override final String? id; +@override final String? code; +@override final String? name; +@override final String? description; +@override final String? price; +@override final String? quantity; + +/// Create a copy of ProductStruct +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ProductStructCopyWith<_ProductStruct> get copyWith => __$ProductStructCopyWithImpl<_ProductStruct>(this, _$identity); + +@override +Map toJson() { + return _$ProductStructToJson(this, ); +} + +@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)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,code,name,description,price,quantity); + +@override +String toString() { + return 'ProductStruct(id: $id, code: $code, name: $name, description: $description, price: $price, quantity: $quantity)'; +} + + +} + +/// @nodoc +abstract mixin class _$ProductStructCopyWith<$Res> implements $ProductStructCopyWith<$Res> { + factory _$ProductStructCopyWith(_ProductStruct value, $Res Function(_ProductStruct) _then) = __$ProductStructCopyWithImpl; +@override @useResult +$Res call({ + String? id, String? code, String? name, String? description, String? price, String? quantity +}); + + + + +} +/// @nodoc +class __$ProductStructCopyWithImpl<$Res> + implements _$ProductStructCopyWith<$Res> { + __$ProductStructCopyWithImpl(this._self, this._then); + + final _ProductStruct _self; + final $Res Function(_ProductStruct) _then; + +/// 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 = freezed,Object? code = freezed,Object? name = freezed,Object? description = freezed,Object? price = freezed,Object? quantity = freezed,}) { + return _then(_ProductStruct( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable +as String?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +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?, + )); +} + + +} + +// dart format on diff --git a/lib/backend/schema/product/product_struct.g.dart b/lib/backend/schema/product/product_struct.g.dart new file mode 100644 index 0000000..8d51cef --- /dev/null +++ b/lib/backend/schema/product/product_struct.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'product_struct.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_ProductStruct _$ProductStructFromJson(Map json) => + _ProductStruct( + id: json['id'] as String?, + code: json['code'] as String?, + name: json['name'] as String?, + description: json['description'] as String?, + price: json['price'] as String?, + quantity: json['quantity'] as String?, + ); + +Map _$ProductStructToJson(_ProductStruct instance) => + { + 'id': instance.id, + 'code': instance.code, + 'name': instance.name, + 'description': instance.description, + 'price': instance.price, + 'quantity': instance.quantity, + }; diff --git a/lib/backend/schema/user/user_struct.dart b/lib/backend/schema/user/user_struct.dart new file mode 100644 index 0000000..e65871c --- /dev/null +++ b/lib/backend/schema/user/user_struct.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; + +import 'package:barcode_scanner/provider_container.dart'; +import 'package:barcode_scanner/services/secure_storage.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'user_struct.freezed.dart'; +part 'user_struct.g.dart'; + +@Freezed(toJson: true) +abstract class UserStruct with _$UserStruct { + factory UserStruct({ + String? id, + String? firstName, + String? lastName, + String? email, + String? phone, + }) = _UserStruct; + + factory UserStruct.fromJson(Map json) => + _$UserStructFromJson(json); +} + +extension UserStructExt on UserStruct { + String get key => 'user'; + + String get fullName { + final sb = StringBuffer(); + sb.write(firstName); + if (firstName != null) { + sb.write(' '); + } + sb.write(lastName); + return sb.toString(); + } + + Future setToLocalStorage() { + final storage = providerContainer.read(sharedPrefsProvider); + return storage.write(key: id ?? key, value: jsonEncode(toJson())); + } + + Future getFromLocalStorage() async { + final storage = providerContainer.read(sharedPrefsProvider); + final jsonString = await storage.read(key: id ?? key); + if (jsonString == null) return null; + return UserStruct.fromJson(jsonDecode(jsonString)); + } + + Future deleteLocalStorage() { + final storage = providerContainer.read(sharedPrefsProvider); + return storage.delete(key: id ?? key); + } +} diff --git a/lib/backend/schema/user/user_struct.freezed.dart b/lib/backend/schema/user/user_struct.freezed.dart new file mode 100644 index 0000000..aad172b --- /dev/null +++ b/lib/backend/schema/user/user_struct.freezed.dart @@ -0,0 +1,160 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'user_struct.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$UserStruct { + + String? get id; String? get firstName; String? get lastName; String? get email; String? get phone; +/// Create a copy of UserStruct +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$UserStructCopyWith get copyWith => _$UserStructCopyWithImpl(this as UserStruct, _$identity); + + /// Serializes this UserStruct to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is UserStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,firstName,lastName,email,phone); + +@override +String toString() { + return 'UserStruct(id: $id, firstName: $firstName, lastName: $lastName, email: $email, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class $UserStructCopyWith<$Res> { + factory $UserStructCopyWith(UserStruct value, $Res Function(UserStruct) _then) = _$UserStructCopyWithImpl; +@useResult +$Res call({ + String? id, String? firstName, String? lastName, String? email, String? phone +}); + + + + +} +/// @nodoc +class _$UserStructCopyWithImpl<$Res> + implements $UserStructCopyWith<$Res> { + _$UserStructCopyWithImpl(this._self, this._then); + + final UserStruct _self; + final $Res Function(UserStruct) _then; + +/// Create a copy of UserStruct +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? firstName = freezed,Object? lastName = freezed,Object? email = freezed,Object? phone = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// @nodoc +@JsonSerializable() + +class _UserStruct implements UserStruct { + _UserStruct({this.id, this.firstName, this.lastName, this.email, this.phone}); + factory _UserStruct.fromJson(Map json) => _$UserStructFromJson(json); + +@override final String? id; +@override final String? firstName; +@override final String? lastName; +@override final String? email; +@override final String? phone; + +/// Create a copy of UserStruct +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UserStructCopyWith<_UserStruct> get copyWith => __$UserStructCopyWithImpl<_UserStruct>(this, _$identity); + +@override +Map toJson() { + return _$UserStructToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _UserStruct&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.email, email) || other.email == email)&&(identical(other.phone, phone) || other.phone == phone)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,firstName,lastName,email,phone); + +@override +String toString() { + return 'UserStruct(id: $id, firstName: $firstName, lastName: $lastName, email: $email, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class _$UserStructCopyWith<$Res> implements $UserStructCopyWith<$Res> { + factory _$UserStructCopyWith(_UserStruct value, $Res Function(_UserStruct) _then) = __$UserStructCopyWithImpl; +@override @useResult +$Res call({ + String? id, String? firstName, String? lastName, String? email, String? phone +}); + + + + +} +/// @nodoc +class __$UserStructCopyWithImpl<$Res> + implements _$UserStructCopyWith<$Res> { + __$UserStructCopyWithImpl(this._self, this._then); + + final _UserStruct _self; + final $Res Function(_UserStruct) _then; + +/// Create a copy of UserStruct +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? firstName = freezed,Object? lastName = freezed,Object? email = freezed,Object? phone = freezed,}) { + return _then(_UserStruct( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/lib/backend/schema/user/user_struct.g.dart b/lib/backend/schema/user/user_struct.g.dart new file mode 100644 index 0000000..0105995 --- /dev/null +++ b/lib/backend/schema/user/user_struct.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_struct.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_UserStruct _$UserStructFromJson(Map json) => _UserStruct( + id: json['id'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, + email: json['email'] as String?, + phone: json['phone'] as String?, +); + +Map _$UserStructToJson(_UserStruct instance) => + { + 'id': instance.id, + 'firstName': instance.firstName, + 'lastName': instance.lastName, + 'email': instance.email, + 'phone': instance.phone, + }; diff --git a/lib/pages/home_page/home_page.dart b/lib/pages/home_page/home_page.dart index d81d1b5..5155346 100644 --- a/lib/pages/home_page/home_page.dart +++ b/lib/pages/home_page/home_page.dart @@ -1,8 +1,11 @@ +import 'package:barcode_scanner/backend/schema/user/user_struct.dart'; +import 'package:barcode_scanner/pages/home_page/home_page_model.dart'; import 'package:barcode_scanner/pages/login_page/login_page_model.dart'; import 'package:barcode_scanner/router/go_router_builder.dart'; import 'package:barcode_scanner/router/go_secure_router_builder.dart'; import 'package:barcode_scanner/themes/app_theme.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class HomePage extends ConsumerStatefulWidget { @@ -13,23 +16,91 @@ class HomePage extends ConsumerStatefulWidget { } class _HomePageState extends ConsumerState { + @override + void initState() { + super.initState(); + SchedulerBinding.instance.addPostFrameCallback((_) { + ref.read(homePageModelProvider.notifier).getUserConnected(); + }); + } + @override Widget build(BuildContext context) { return Scaffold( + drawer: Drawer( + backgroundColor: AppTheme.of(context).primaryBackground, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + child: Column( + children: [ + SizedBox(height: 50), + Consumer( + builder: (context, ref, child) { + final state = ref.watch(homePageModelProvider); + return ListTile( + contentPadding: EdgeInsets.zero, + leading: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: AppTheme.of(context).secondaryBackground, + borderRadius: BorderRadius.circular(60), + ), + ), + title: Text( + state.user?.fullName ?? '', + style: AppTheme.of(context).titleMedium, + ), + subtitle: Text( + state.user?.email ?? '', + style: AppTheme.of(context).bodyMedium, + ), + ); + }, + ), + Divider(), + ListTile( + leading: Icon(Icons.person), + title: Text('Profil', style: AppTheme.of(context).bodyLarge), + ), + ListTile( + onTap: () { + Navigator.of(context).pop(); + ProductListRoute().push(context); + }, + leading: Icon(Icons.inventory), + title: Text( + 'Inventaire', + style: AppTheme.of(context).bodyLarge, + ), + ), + Spacer(), + SafeArea( + child: ListTile( + onTap: () async { + await ref.read(loginPageModelProvider.notifier).logOut(); + await UserStruct(id: '1').deleteLocalStorage(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + SplashRoute().go(context); + }); + }, + leading: Icon(Icons.logout), + title: Text( + 'Se deconnecter', + style: AppTheme.of(context).bodyLarge, + ), + ), + ), + ], + ), + ), + ), backgroundColor: AppTheme.of(context).primaryBackground, appBar: AppBar( - automaticallyImplyLeading: false, - actions: [ - IconButton( - onPressed: () async { - await ref.read(loginPageModelProvider.notifier).logOut(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - SplashRoute().go(context); - }); - }, - icon: Icon(Icons.login), - ), - ], + title: Text('Barcode Scanner', style: AppTheme.of(context).titleLarge), + centerTitle: true, + backgroundColor: AppTheme.of(context).primaryBackground, + actions: [], ), body: Center( child: SingleChildScrollView( diff --git a/lib/pages/home_page/home_page_model.dart b/lib/pages/home_page/home_page_model.dart new file mode 100644 index 0000000..fb314ea --- /dev/null +++ b/lib/pages/home_page/home_page_model.dart @@ -0,0 +1,42 @@ +import 'package:barcode_scanner/backend/schema/user/user_struct.dart'; +import 'package:barcode_scanner/services/secure_storage.dart'; +import 'package:barcode_scanner/services/token_provider.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'home_page_model.freezed.dart'; + +/// The provider for the AuthViewModel, using Riverpod's StateNotifierProvider +/// with autoDispose to manage the lifecycle of the view model. +final homePageModelProvider = + StateNotifierProvider((ref) { + return HomePageModel( + secureStorage: ref.read(sharedPrefsProvider), + tokenProvider: ref.read(tokenProvider), + ); + }); + +class HomePageModel extends StateNotifier { + /// Constructor initializes the TaskRepository using the provider reference. + HomePageModel({required this.secureStorage, required this.tokenProvider}) + : super(const HomePageState()); + + late FlutterSecureStorage secureStorage; + late TokenProvider tokenProvider; + + Future getUserConnected() async { + state = state.copyWith(loading: true); + final user = await UserStruct(id: '1').getFromLocalStorage(); + state = state.copyWith(user: user); + } +} + +@freezed +abstract class HomePageState with _$HomePageState { + const factory HomePageState({ + UserStruct? user, + @Default(false) bool loading, + }) = _HomePageState; +} diff --git a/lib/pages/home_page/home_page_model.freezed.dart b/lib/pages/home_page/home_page_model.freezed.dart new file mode 100644 index 0000000..d545e2b --- /dev/null +++ b/lib/pages/home_page/home_page_model.freezed.dart @@ -0,0 +1,181 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'home_page_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$HomePageState implements DiagnosticableTreeMixin { + + UserStruct? get user; bool get loading; +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$HomePageStateCopyWith get copyWith => _$HomePageStateCopyWithImpl(this as HomePageState, _$identity); + + +@override +void debugFillProperties(DiagnosticPropertiesBuilder properties) { + properties + ..add(DiagnosticsProperty('type', 'HomePageState')) + ..add(DiagnosticsProperty('user', user))..add(DiagnosticsProperty('loading', loading)); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is HomePageState&&(identical(other.user, user) || other.user == user)&&(identical(other.loading, loading) || other.loading == loading)); +} + + +@override +int get hashCode => Object.hash(runtimeType,user,loading); + +@override +String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { + return 'HomePageState(user: $user, loading: $loading)'; +} + + +} + +/// @nodoc +abstract mixin class $HomePageStateCopyWith<$Res> { + factory $HomePageStateCopyWith(HomePageState value, $Res Function(HomePageState) _then) = _$HomePageStateCopyWithImpl; +@useResult +$Res call({ + UserStruct? user, bool loading +}); + + +$UserStructCopyWith<$Res>? get user; + +} +/// @nodoc +class _$HomePageStateCopyWithImpl<$Res> + implements $HomePageStateCopyWith<$Res> { + _$HomePageStateCopyWithImpl(this._self, this._then); + + final HomePageState _self; + final $Res Function(HomePageState) _then; + +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? user = freezed,Object? loading = null,}) { + return _then(_self.copyWith( +user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserStruct?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable +as bool, + )); +} +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserStructCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserStructCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + + +/// @nodoc + + +class _HomePageState with DiagnosticableTreeMixin implements HomePageState { + const _HomePageState({this.user, this.loading = false}); + + +@override final UserStruct? user; +@override@JsonKey() final bool loading; + +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$HomePageStateCopyWith<_HomePageState> get copyWith => __$HomePageStateCopyWithImpl<_HomePageState>(this, _$identity); + + +@override +void debugFillProperties(DiagnosticPropertiesBuilder properties) { + properties + ..add(DiagnosticsProperty('type', 'HomePageState')) + ..add(DiagnosticsProperty('user', user))..add(DiagnosticsProperty('loading', loading)); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomePageState&&(identical(other.user, user) || other.user == user)&&(identical(other.loading, loading) || other.loading == loading)); +} + + +@override +int get hashCode => Object.hash(runtimeType,user,loading); + +@override +String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { + return 'HomePageState(user: $user, loading: $loading)'; +} + + +} + +/// @nodoc +abstract mixin class _$HomePageStateCopyWith<$Res> implements $HomePageStateCopyWith<$Res> { + factory _$HomePageStateCopyWith(_HomePageState value, $Res Function(_HomePageState) _then) = __$HomePageStateCopyWithImpl; +@override @useResult +$Res call({ + UserStruct? user, bool loading +}); + + +@override $UserStructCopyWith<$Res>? get user; + +} +/// @nodoc +class __$HomePageStateCopyWithImpl<$Res> + implements _$HomePageStateCopyWith<$Res> { + __$HomePageStateCopyWithImpl(this._self, this._then); + + final _HomePageState _self; + final $Res Function(_HomePageState) _then; + +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? user = freezed,Object? loading = null,}) { + return _then(_HomePageState( +user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserStruct?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable +as bool, + )); +} + +/// Create a copy of HomePageState +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserStructCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserStructCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + +// dart format on diff --git a/lib/pages/login_page/login_page_model.dart b/lib/pages/login_page/login_page_model.dart index 48dae94..6ee305d 100644 --- a/lib/pages/login_page/login_page_model.dart +++ b/lib/pages/login_page/login_page_model.dart @@ -1,3 +1,4 @@ +import 'package:barcode_scanner/backend/schema/user/user_struct.dart'; import 'package:barcode_scanner/services/secure_storage.dart'; import 'package:barcode_scanner/services/token_provider.dart'; import 'package:flutter/foundation.dart'; @@ -57,7 +58,15 @@ class LoginPageModel extends StateNotifier { state = state.copyWith(loading: true); await Future.delayed(Duration(seconds: 5)); if (email == "user@yopmail.com" && password == "password") { - setTokenInLocal('token'); + setTokenInLocal( + 'token', + UserStruct( + id: '1', + firstName: 'User', + lastName: 'Anonymous', + email: 'user@yopmail.com', + ), + ); state = state.copyWith( loading: false, status: LoginPageStateStatus.logOut, @@ -79,12 +88,12 @@ class LoginPageModel extends StateNotifier { } } - Future setTokenInLocal(String token) async { + Future setTokenInLocal(String token, UserStruct user) async { await Future.wait([ tokenProvider.setToken(token), tokenProvider.setRefreshToken(token), + user.setToLocalStorage(), ]); - state = state.copyWith(loading: false, status: LoginPageStateStatus.logged); debugPrint("$token"); } diff --git a/lib/pages/pages.dart b/lib/pages/pages.dart index 3d6a5e9..2c8d06b 100644 --- a/lib/pages/pages.dart +++ b/lib/pages/pages.dart @@ -3,3 +3,4 @@ export 'login_page/login_page.dart'; export 'product_form_page/product_form_page.dart'; export 'scanner_page/scanner_page.dart'; export 'splash_page/splash_page.dart'; +export 'product_list_page/product_list_page.dart'; diff --git a/lib/pages/product_form_page/product_form_page.dart b/lib/pages/product_form_page/product_form_page.dart index 7827b94..37f330b 100644 --- a/lib/pages/product_form_page/product_form_page.dart +++ b/lib/pages/product_form_page/product_form_page.dart @@ -53,10 +53,7 @@ class _ProductFormPageState extends State { Navigator.of(context).pop(); }, ), - title: Text( - 'Formulaire Produit', - style: AppTheme.of(context).titleLarge, - ), + title: Text('Fiche Produit', style: AppTheme.of(context).titleLarge), centerTitle: true, backgroundColor: AppTheme.of(context).primaryBackground, elevation: 0, @@ -88,7 +85,7 @@ class _ProductFormPageState extends State { /// Description TextFormField( controller: description, - decoration: _inputStyle("Description"), + decoration: _inputStyle("Commentaires"), maxLines: 3, ), const SizedBox(height: 16), @@ -96,7 +93,7 @@ class _ProductFormPageState extends State { /// Prix TextFormField( controller: price, - decoration: _inputStyle("Prix"), + decoration: _inputStyle("Quantités"), keyboardType: TextInputType.number, validator: (value) => (value == null || value.isEmpty) ? 'Champ requis' : null, diff --git a/lib/pages/product_list_page/product_list_page.dart b/lib/pages/product_list_page/product_list_page.dart new file mode 100644 index 0000000..4173c16 --- /dev/null +++ b/lib/pages/product_list_page/product_list_page.dart @@ -0,0 +1,38 @@ +import 'package:barcode_scanner/themes/app_theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class ProductListPage extends ConsumerStatefulWidget { + const ProductListPage({super.key}); + + @override + ConsumerState createState() => + _ProductListPageState(); +} + +class _ProductListPageState extends ConsumerState { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppTheme.of(context).primaryBackground, + appBar: AppBar( + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + color: AppTheme.of(context).primaryText, + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + title: Text( + 'Inventaire des produits', + style: AppTheme.of(context).titleLarge, + ), + centerTitle: true, + backgroundColor: AppTheme.of(context).primaryBackground, + elevation: 0, + ), + ); + } +} diff --git a/lib/router/go_secure_router_builder.dart b/lib/router/go_secure_router_builder.dart index 9b00791..898571d 100644 --- a/lib/router/go_secure_router_builder.dart +++ b/lib/router/go_secure_router_builder.dart @@ -12,6 +12,7 @@ const String _securePage = 'SecurePage'; const String _homePage = 'HomePage'; const String _scannerPage = 'ScannerPage'; const String _productFormPage = 'ProductFormPage'; +const String _productListPage = 'ProductListPage'; // Groupe des routes sécurisées @TypedGoRoute( @@ -20,6 +21,7 @@ const String _productFormPage = 'ProductFormPage'; TypedGoRoute(path: _homePage), TypedGoRoute(path: _scannerPage), TypedGoRoute(path: _productFormPage), + TypedGoRoute(path: _productListPage), ], ) class SecureRoute extends GoRouteData with _$SecureRoute { @@ -59,3 +61,10 @@ class ProductFormRoute extends GoRouteData with _$ProductFormRoute { @override Widget build(BuildContext context, GoRouterState state) => ProductFormPage(); } + +class ProductListRoute extends GoRouteData with _$ProductListRoute { + const ProductListRoute(); + + @override + Widget build(BuildContext context, GoRouterState state) => ProductListPage(); +} diff --git a/lib/router/go_secure_router_builder.g.dart b/lib/router/go_secure_router_builder.g.dart index 59062c4..78f141f 100644 --- a/lib/router/go_secure_router_builder.g.dart +++ b/lib/router/go_secure_router_builder.g.dart @@ -20,6 +20,11 @@ RouteBase get $secureRoute => GoRouteData.$route( factory: _$ProductFormRoute._fromState, ), + GoRouteData.$route( + path: 'ProductListPage', + + factory: _$ProductListRoute._fromState, + ), ], ); @@ -103,3 +108,24 @@ mixin _$ProductFormRoute on GoRouteData { @override void replace(BuildContext context) => context.replace(location); } + +mixin _$ProductListRoute on GoRouteData { + static ProductListRoute _fromState(GoRouterState state) => + const ProductListRoute(); + + @override + String get location => GoRouteData.$location('/SecurePage/ProductListPage'); + + @override + void go(BuildContext context) => context.go(location); + + @override + Future push(BuildContext context) => context.push(location); + + @override + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + @override + void replace(BuildContext context) => context.replace(location); +}