
Adds an `image` field to the user data structure to support profile pictures. Introduces a new profile page and sets up navigation from the home screen. Changes the product list page provider to auto dispose for improved resource management.
228 lines
7.6 KiB
Dart
228 lines
7.6 KiB
Dart
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 {
|
|
const HomePage({super.key});
|
|
|
|
@override
|
|
ConsumerState<ConsumerStatefulWidget> createState() => _HomePageState();
|
|
}
|
|
|
|
class _HomePageState extends ConsumerState<HomePage> {
|
|
@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(
|
|
onTap: () {
|
|
ProfileRoute().push(context);
|
|
},
|
|
leading: Icon(Icons.person),
|
|
title: Text(
|
|
'Mon 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(
|
|
title: Text('Barcode Scanner', style: AppTheme.of(context).titleLarge),
|
|
centerTitle: true,
|
|
backgroundColor: AppTheme.of(context).primaryBackground,
|
|
actions: [],
|
|
),
|
|
body: Center(
|
|
child: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
/// HEADER ICON
|
|
Container(
|
|
width: 100,
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: AppTheme.of(context).primary,
|
|
shape: BoxShape.circle,
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Color(0x225F3DFF),
|
|
blurRadius: 20,
|
|
offset: Offset(0, 12),
|
|
),
|
|
],
|
|
),
|
|
child: const Center(
|
|
child: Icon(
|
|
Icons.qr_code_scanner_rounded,
|
|
color: Colors.white,
|
|
size: 50,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
/// TITLE
|
|
const Text(
|
|
'Barcode Scanner',
|
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
|
),
|
|
|
|
const SizedBox(height: 12),
|
|
|
|
/// SUBTITLE
|
|
const Text(
|
|
'Scannez facilement tous vos code barre\nen quelques secondes',
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(fontSize: 16, color: Colors.grey),
|
|
),
|
|
|
|
const SizedBox(height: 36),
|
|
|
|
/// SCANNER PREVIEW AREA (placeholder)
|
|
Container(
|
|
width: 260,
|
|
height: 200,
|
|
padding: const EdgeInsets.all(40),
|
|
decoration: BoxDecoration(
|
|
color: AppTheme.of(context).alternate,
|
|
borderRadius: BorderRadius.circular(24),
|
|
boxShadow: const [
|
|
BoxShadow(
|
|
color: Color(0x11000000),
|
|
blurRadius: 10,
|
|
offset: Offset(0, 8),
|
|
),
|
|
],
|
|
),
|
|
child: Icon(
|
|
Icons.qr_code_2_rounded,
|
|
size: 60,
|
|
color: AppTheme.of(context).primaryText,
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
const Text(
|
|
'Pointez votre caméra vers le code\nbarre',
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(color: Colors.grey),
|
|
),
|
|
|
|
const SizedBox(height: 40),
|
|
|
|
/// START BUTTON
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: ElevatedButton.icon(
|
|
onPressed: () {
|
|
ScannerRoute().push(context);
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppTheme.of(context).primary,
|
|
padding: const EdgeInsets.symmetric(vertical: 18),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
),
|
|
icon: const Icon(
|
|
Icons.qr_code_scanner_rounded,
|
|
color: Colors.white,
|
|
size: 30,
|
|
),
|
|
label: const Text(
|
|
'Commencer le scan',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|