
Introduces a side navigation drawer on the home page to improve navigation and centralize user actions. Displays the logged-in user's information (name, email) in the drawer header. Adds a link to the Product List page ("Inventaire") within the drawer. Moves the logout functionality to the drawer, ensuring user data is also cleared from local storage upon logout. Ensures user data is saved to local storage during the login process and fetched when the home page loads. Includes minor text updates on the Product Form page.
222 lines
7.4 KiB
Dart
222 lines
7.4 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(
|
|
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(
|
|
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,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|