112 lines
3.4 KiB
Dart
112 lines
3.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../services/produit_repository.dart';
|
|
import 'etiquettes_screen.dart';
|
|
import 'produits_screen.dart';
|
|
import 'scan_screen.dart';
|
|
|
|
/// Coquille principale : contient les 3 onglets et la barre de navigation.
|
|
class HomeShell extends StatefulWidget {
|
|
const HomeShell({super.key});
|
|
|
|
@override
|
|
State<HomeShell> createState() => _HomeShellState();
|
|
}
|
|
|
|
class _HomeShellState extends State<HomeShell> {
|
|
int _index = 0;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final pages = [
|
|
ProduitsScreen(onAllerScanner: () => setState(() => _index = 1)),
|
|
ScanScreen(active: _index == 1),
|
|
const EtiquettesScreen(),
|
|
];
|
|
return Scaffold(
|
|
body: Column(
|
|
children: [
|
|
ListenableBuilder(
|
|
listenable: ProduitRepository.instance,
|
|
builder: (context, _) {
|
|
final repo = ProduitRepository.instance;
|
|
if (repo.connecte) return const SizedBox.shrink();
|
|
return _BanniereHorsLigne(onReessayer: () => repo.charger());
|
|
},
|
|
),
|
|
Expanded(child: IndexedStack(index: _index, children: pages)),
|
|
],
|
|
),
|
|
bottomNavigationBar: NavigationBar(
|
|
selectedIndex: _index,
|
|
height: 68,
|
|
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
|
onDestinationSelected: (i) => setState(() => _index = i),
|
|
destinations: const [
|
|
NavigationDestination(
|
|
icon: Icon(Icons.inventory_2_outlined),
|
|
selectedIcon: Icon(Icons.inventory_2),
|
|
label: 'Produits',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.qr_code_scanner_outlined),
|
|
selectedIcon: Icon(Icons.qr_code_scanner),
|
|
label: 'Scanner',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.print_outlined),
|
|
selectedIcon: Icon(Icons.print),
|
|
label: 'Étiquettes',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Fin bandeau affiché en haut quand la tablette n'est pas synchronisée au serveur.
|
|
class _BanniereHorsLigne extends StatelessWidget {
|
|
final VoidCallback onReessayer;
|
|
const _BanniereHorsLigne({required this.onReessayer});
|
|
|
|
static const _ambre = Color(0xFFB26B00);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Material(
|
|
color: const Color(0xFFFFF3E0),
|
|
child: SafeArea(
|
|
bottom: false,
|
|
child: InkWell(
|
|
onTap: onReessayer,
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 7),
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.cloud_off_rounded, size: 16, color: _ambre),
|
|
const SizedBox(width: 8),
|
|
const Expanded(
|
|
child: Text(
|
|
'Hors ligne — non synchronisé',
|
|
style: TextStyle(
|
|
color: _ambre,
|
|
fontSize: 12.5,
|
|
fontWeight: FontWeight.w600),
|
|
),
|
|
),
|
|
const Text('Réessayer',
|
|
style: TextStyle(
|
|
color: _ambre,
|
|
fontSize: 12.5,
|
|
fontWeight: FontWeight.w700)),
|
|
const SizedBox(width: 4),
|
|
const Icon(Icons.refresh, size: 15, color: _ambre),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|