feat: Enhance admin panel navigation and UI by implementing tab management and improving layout structure
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-11 10:10:03 +02:00
parent 06492ff099
commit afbc5b91b2
5 changed files with 128 additions and 148 deletions
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/api/api_error_mapper.dart';
import '../../../core/l10n/l10n.dart';
@@ -18,14 +17,12 @@ enum _DatabaseTab { inventory, pantry, products, privateProducts, pending, alias
class _DatabaseTabConfig {
final _DatabaseTab tab;
final String title;
final String summary;
final Widget Function(BuildContext context) buildPanel;
final Widget panel;
const _DatabaseTabConfig({
required this.tab,
required this.title,
required this.summary,
required this.buildPanel,
required this.panel,
});
}
@@ -46,44 +43,37 @@ class _AdminDatabasePanelState extends ConsumerState<AdminDatabasePanel> {
_DatabaseTabConfig(
tab: _DatabaseTab.inventory,
title: context.l10n.profileInventoryTab,
summary: 'Granska, filtrera och redigera inventory-poster. Välj användare för att arbeta på en specifik ägares data.',
buildPanel: (_) => const AdminInventoryPanel(embedded: true),
panel: const AdminInventoryPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.pantry,
title: context.l10n.profilePantryTab,
summary: 'Granska och redigera användarnas baslager. Flytta poster till inventarie eller ta bort dem vid behov.',
buildPanel: (_) => const AdminPantryPanel(embedded: true),
panel: const AdminPantryPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.products,
title: context.l10n.profileProductsTab,
summary: 'Hantera globala produkter: kategorisering, restaurering, merge och AI-stöd.',
buildPanel: (_) => const AdminProductsPanel(embedded: true),
panel: const AdminProductsPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.privateProducts,
title: 'Privata produkter',
summary: 'Promotera privata produkter till den globala produkt-tabellen.',
buildPanel: (_) => const AdminPrivateProductsPanel(embedded: true),
panel: const AdminPrivateProductsPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.pending,
title: context.l10n.profilePendingTab,
summary: 'Godkänn eller avslå nya produkter som föreslagits av användare.',
buildPanel: (_) => const AdminPendingProductsPanel(embedded: true),
panel: const AdminPendingProductsPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.aliases,
title: 'Alias',
summary: 'Hantera globala alias som används i receipt-importens första matchningssteg.',
buildPanel: (_) => const AdminAliasesPanel(embedded: true),
panel: const AdminAliasesPanel(embedded: true),
),
_DatabaseTabConfig(
tab: _DatabaseTab.ai,
title: 'AI',
summary: 'Se vilka AI-modeller som används och hur de är exponerade i systemet.',
buildPanel: (_) => const AdminAiPanel(embedded: true),
panel: const AdminAiPanel(embedded: true),
),
];
@@ -105,33 +95,6 @@ class _AdminDatabasePanelState extends ConsumerState<AdminDatabasePanel> {
}
}
Widget _panelShell({
required String title,
required String description,
required Widget child,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 8),
Text(description),
],
),
),
),
const SizedBox(height: 12),
Expanded(child: child),
],
);
}
@override
Widget build(BuildContext context) {
final currentTab = _tabConfigs.firstWhere((config) => config.tab == _activeTab);
@@ -178,10 +141,6 @@ class _AdminDatabasePanelState extends ConsumerState<AdminDatabasePanel> {
],
),
const SizedBox(height: 8),
Text(
currentTab.summary,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
@@ -192,9 +151,9 @@ class _AdminDatabasePanelState extends ConsumerState<AdminDatabasePanel> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(flex: 1, child: header),
header,
const SizedBox(height: 12),
Expanded(flex: 6, child: _panelShell(title: currentTab.title, description: currentTab.summary, child: currentTab.buildPanel(context))),
Expanded(child: currentTab.panel),
],
),
);