leafittome/lib/core/widgets/app_drawer.dart
cschlaefke 1ca02f224b V2.1: Mehrere Haushalte je Nutzer – Mitgliedschaft bleibt beim Beitritt erhalten
- memberUids ist Quelle der Wahrheit, users.householdId nur noch aktiver Zeiger
- Haushalts-Screen: Liste „Meine Haushalte" mit Rolle, Aktiv-Markierung und Wechsel per Tipp
- Beitritts-Dialog warnt nicht mehr vor Datenverlust, sondern erklärt das Zurückwechseln
- sendDailyReminders sammelt fällige Aufgaben aus allen Haushalten des Nutzers
- FirebaseFunctions im HouseholdRepository lazy erzeugt (Widget-Tests ohne Firebase-Init)
- Drawer-Titel mit Ellipsis gegen Overflow auf schmalen Breiten
- Widget-Test für den Haushaltswechsel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 21:18:25 +02:00

120 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../features/today/application/due_tasks_provider.dart';
import '../../l10n/generated/app_localizations.dart';
import '../router/app_router.dart';
/// Das Hamburger-Menü: von jedem Haupt-Screen aus erreichbar,
/// listet alle Funktionen klassisch untereinander auf.
class AppDrawer extends ConsumerWidget {
const AppDrawer({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final currentPath = GoRouterState.of(context).uri.path;
final openTaskCount = ref.watch(dueTasksProvider).length;
void goTo(String path) {
Navigator.pop(context);
if (path != currentPath) {
context.go(path);
}
}
return Drawer(
child: SafeArea(
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Row(
children: [
Icon(
Icons.eco,
size: 36,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(width: 12),
Expanded(
child: Text(
l10n.appTitle,
style: Theme.of(context).textTheme.headlineSmall,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
const Divider(),
_DrawerItem(
icon: Icons.checklist,
label: l10n.menuToday,
selected: currentPath == AppRoutes.today,
badgeCount: openTaskCount,
onTap: () => goTo(AppRoutes.today),
),
_DrawerItem(
icon: Icons.local_florist,
label: l10n.menuPlants,
selected: currentPath == AppRoutes.plants,
onTap: () => goTo(AppRoutes.plants),
),
_DrawerItem(
icon: Icons.place,
label: l10n.menuLocations,
selected: currentPath == AppRoutes.locations,
onTap: () => goTo(AppRoutes.locations),
),
_DrawerItem(
icon: Icons.group,
label: l10n.menuHousehold,
selected: currentPath == AppRoutes.household,
onTap: () => goTo(AppRoutes.household),
),
_DrawerItem(
icon: Icons.settings,
label: l10n.menuSettings,
selected: currentPath == AppRoutes.settings,
onTap: () => goTo(AppRoutes.settings),
),
],
),
),
);
}
}
class _DrawerItem extends StatelessWidget {
const _DrawerItem({
required this.icon,
required this.label,
required this.selected,
required this.onTap,
this.badgeCount = 0,
});
final IconData icon;
final String label;
final bool selected;
final VoidCallback onTap;
final int badgeCount;
@override
Widget build(BuildContext context) {
return ListTile(
leading: Icon(icon),
title: Text(label, style: const TextStyle(fontSize: 17)),
selected: selected,
trailing: badgeCount > 0
? Badge.count(
count: badgeCount,
backgroundColor: Theme.of(context).colorScheme.primary,
)
: null,
onTap: onTap,
);
}
}