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:
@@ -0,0 +1,110 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../../core/api/api_error_mapper.dart';
|
||||
import '../data/admin_repository.dart';
|
||||
import '../domain/ai_model_info.dart';
|
||||
|
||||
class AdminAiPanel extends ConsumerStatefulWidget {
|
||||
final bool embedded;
|
||||
|
||||
const AdminAiPanel({super.key, this.embedded = false});
|
||||
|
||||
@override
|
||||
ConsumerState<AdminAiPanel> createState() => _AdminAiPanelState();
|
||||
}
|
||||
|
||||
class _AdminAiPanelState extends ConsumerState<AdminAiPanel> {
|
||||
bool _isLoading = true;
|
||||
String? _error;
|
||||
List<AiModelInfo> _models = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_load();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
});
|
||||
try {
|
||||
final models = await ref.read(adminRepositoryProvider).listAiModels();
|
||||
if (!mounted) return;
|
||||
setState(() => _models = models);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() => _error = mapErrorToUserMessage(e, context));
|
||||
} finally {
|
||||
if (mounted) setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
Color _chipColor(String value, ColorScheme scheme) {
|
||||
final lower = value.toLowerCase();
|
||||
if (lower.contains('admin')) return scheme.primaryContainer;
|
||||
if (lower.contains('premium')) return scheme.tertiaryContainer;
|
||||
return scheme.secondaryContainer;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
if (_isLoading) return const Center(child: CircularProgressIndicator());
|
||||
if (_error != null) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(_error!, style: TextStyle(color: theme.colorScheme.error)),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(onPressed: _load, child: const Text('Försök igen')),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Översikt över AI-funktioner som backend exponerar.',
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
..._models.map(
|
||||
(model) => Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(model.name, style: theme.textTheme.titleMedium),
|
||||
const SizedBox(height: 8),
|
||||
Text(model.description),
|
||||
const SizedBox(height: 12),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
Chip(label: Text(model.model)),
|
||||
Chip(
|
||||
label: Text(model.access),
|
||||
backgroundColor: _chipColor(model.access, theme.colorScheme),
|
||||
),
|
||||
Chip(label: Text(model.trigger)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text('Sida: ${model.path}', style: theme.textTheme.bodySmall),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user