diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index 3bb86a8..00f1f75 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -35,7 +35,7 @@ class _HomePageState extends State { return screens; } - List _navItemsForRole(String? role) { + List _navItemsForRole(String? role, AppState state) { final items = [ const BottomNavigationBarItem( icon: Icon(Icons.point_of_sale), @@ -48,8 +48,12 @@ class _HomePageState extends State { icon: Icon(Icons.inventory_2), label: 'Produk', ), - const BottomNavigationBarItem( - icon: Icon(Icons.receipt_long), + BottomNavigationBarItem( + icon: Badge( + isLabelVisible: state.unseenSalesCount > 0, + label: Text('${state.unseenSalesCount}'), + child: const Icon(Icons.receipt_long), + ), label: 'Riwayat', ), const BottomNavigationBarItem( @@ -76,7 +80,7 @@ class _HomePageState extends State { Widget build(BuildContext context) { final state = context.watch(); final screens = _screensForRole(state.userRole); - final navItems = _navItemsForRole(state.userRole); + final navItems = _navItemsForRole(state.userRole, state); final safeIndex = _index >= screens.length ? 0 : _index; @@ -109,7 +113,14 @@ class _HomePageState extends State { bottomNavigationBar: navItems.length >= 2 ? BottomNavigationBar( currentIndex: safeIndex, - onTap: (i) => setState(() => _index = i), + onTap: (i) { + setState(() => _index = i); + // Reset badge saat tab Riwayat dibuka. + final riwayatIdx = state.userRole == 'admin' ? 2 : 1; + if (i == riwayatIdx) { + context.read().markSalesSeen(); + } + }, items: navItems, ) : null, diff --git a/lib/state/app_state.dart b/lib/state/app_state.dart index c0f9dff..4afabdf 100644 --- a/lib/state/app_state.dart +++ b/lib/state/app_state.dart @@ -33,6 +33,16 @@ class AppState extends ChangeNotifier { StreamController.broadcast(); final Set _notifiedSaleIds = {}; + // Jumlah transaksi baru yang belum dilihat admin (badge di tab Riwayat). + int unseenSalesCount = 0; + + void markSalesSeen() { + if (unseenSalesCount != 0) { + unseenSalesCount = 0; + notifyListeners(); + } + } + // Client dengan service_role key untuk operasi admin (buat/edit/hapus akun kasir). // PERINGATAN: key ini bypass RLS — hanya untuk app POS di device terpercaya. final SupabaseClient _admin = SupabaseClient(supabaseUrl, supabaseServiceKey); @@ -159,6 +169,7 @@ class AppState extends ChangeNotifier { return; } final now = DateTime.now(); + bool newSeen = false; for (final s in sales) { if (!_notifiedSaleIds.contains(s.id)) { _notifiedSaleIds.add(s.id); @@ -166,12 +177,16 @@ class AppState extends ChangeNotifier { // Lewati juga transaksi sendiri — admin tahu kalau dia yang jualan. if (!_salesFirstLoad && s.userId != userId && - now.difference(s.date).inMinutes.abs() <= 5 && - !newSaleNotifications.isClosed) { - newSaleNotifications.add(s); + now.difference(s.date).inMinutes.abs() <= 5) { + newSeen = true; + unseenSalesCount++; + if (!newSaleNotifications.isClosed) { + newSaleNotifications.add(s); + } } } } + if (newSeen) notifyListeners(); _salesFirstLoad = false; }