feat: enhance profile screen with tab navigation and admin panels

- Added tab navigation for profile, database, users, suggestions, and AI sections.
- Implemented database management with inventory, pantry, and products tabs.
- Created Admin AI panel to display AI model information.
- Introduced Admin Pending Products panel for managing product approvals.
- Developed Admin Users panel for user management, including role changes and password resets.
- Added data models for AI models and pending products.
This commit is contained in:
Nils-Johan Gynther
2026-04-25 08:22:14 +02:00
parent 53afcc98a9
commit 8ea2b97c27
10 changed files with 1289 additions and 488 deletions
+6
View File
@@ -4,6 +4,12 @@ class AuthApiPaths {
class ProductApiPaths {
static const list = '/products';
static const pending = '/products/pending';
static String setStatus(int id) => '/products/$id/status';
}
class AiApiPaths {
static const models = '/ai/models';
}
class RecipeApiPaths {
+38 -11
View File
@@ -81,13 +81,6 @@ class AppShell extends ConsumerWidget {
final selectedDestination = dests[selectedIndex];
final isWide = MediaQuery.of(context).size.width >= 900;
Future<void> logout() async {
await ref.read(authStateProvider.notifier).logout();
if (context.mounted) {
context.go('/login');
}
}
void navigateTo(int index) {
final target = dests[index].path;
if (target != location && context.mounted) {
@@ -98,6 +91,13 @@ class AppShell extends ConsumerWidget {
final isRecipesRoute = location.startsWith('/recipes') &&
!location.startsWith('/recipes/');
Future<void> logout() async {
await ref.read(authStateProvider.notifier).logout();
if (context.mounted) {
context.go('/login');
}
}
return Scaffold(
appBar: AppBar(
title: Text(selectedDestination.title),
@@ -139,10 +139,37 @@ class AppShell extends ConsumerWidget {
);
},
),
IconButton(
tooltip: 'Logga ut',
icon: const Icon(Icons.logout),
onPressed: logout,
PopupMenuButton<String>(
tooltip: 'Profil och konto',
icon: const Icon(Icons.account_circle_outlined),
onSelected: (value) {
switch (value) {
case 'profile':
if (location != '/profile' && context.mounted) {
context.go('/profile');
}
case 'logout':
logout();
}
},
itemBuilder: (context) => const [
PopupMenuItem<String>(
value: 'profile',
child: ListTile(
leading: Icon(Icons.person_outline),
title: Text('Profil'),
contentPadding: EdgeInsets.zero,
),
),
PopupMenuItem<String>(
value: 'logout',
child: ListTile(
leading: Icon(Icons.logout),
title: Text('Logga ut'),
contentPadding: EdgeInsets.zero,
),
),
],
),
],
),