Add Swedish localization for various app actions and inventory management strings

This commit is contained in:
Nils-Johan Gynther
2026-05-02 15:42:00 +02:00
parent 4e81f56225
commit 2563738fcf
24 changed files with 4510 additions and 366 deletions
@@ -3,6 +3,7 @@ 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';
import '../../admin/presentation/admin_ai_panel.dart';
import '../../admin/presentation/admin_pending_products_panel.dart';
import '../../admin/presentation/admin_products_panel.dart';
@@ -86,7 +87,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
if (!mounted) return;
setState(() => _profile = updated);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Profil sparad!')),
SnackBar(content: Text(context.l10n.profileSaved)),
);
} catch (e) {
if (!mounted) return;
@@ -119,15 +120,15 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
String _tabLabel(_ProfileTab tab) {
switch (tab) {
case _ProfileTab.profile:
return 'Min profil';
return context.l10n.profileMyProfileTab;
case _ProfileTab.database:
return 'Databas';
return context.l10n.profileDatabaseTab;
case _ProfileTab.users:
return 'Användare';
return context.l10n.profileUsersTab;
case _ProfileTab.suggestions:
return 'Förslag';
return context.l10n.profilePendingTab;
case _ProfileTab.ai:
return 'AI';
return context.l10n.profileAiTab;
}
}
@@ -158,7 +159,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Användarnamn',
context.l10n.profileUsernameLabel,
style: theme.textTheme.labelMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
@@ -168,15 +169,15 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
const Divider(height: 32),
TextFormField(
controller: _emailCtrl,
decoration: const InputDecoration(
labelText: 'E-post',
border: OutlineInputBorder(),
decoration: InputDecoration(
labelText: context.l10n.profileEmailLabel,
border: const OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
validator: (v) {
if (v == null || v.isEmpty) return 'Ange en e-postadress';
if (v == null || v.isEmpty) return context.l10n.profileEmailHint;
if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(v)) {
return 'Ogiltig e-postadress';
return context.l10n.profileEmailInvalid;
}
return null;
},
@@ -184,17 +185,17 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
const SizedBox(height: 16),
TextFormField(
controller: _firstNameCtrl,
decoration: const InputDecoration(
labelText: 'Förnamn',
border: OutlineInputBorder(),
decoration: InputDecoration(
labelText: context.l10n.profileFirstNameLabel,
border: const OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextFormField(
controller: _lastNameCtrl,
decoration: const InputDecoration(
labelText: 'Efternamn',
border: OutlineInputBorder(),
decoration: InputDecoration(
labelText: context.l10n.profileLastNameLabel,
border: const OutlineInputBorder(),
),
),
const SizedBox(height: 24),
@@ -208,7 +209,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Spara ändringar'),
: Text(context.l10n.profileSaveAction),
),
),
],
@@ -230,11 +231,11 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
String tabLabel(_DatabaseTab tab) {
switch (tab) {
case _DatabaseTab.inventory:
return 'Inventarie';
return context.l10n.profileInventoryTab;
case _DatabaseTab.pantry:
return 'Baslager';
return context.l10n.profilePantryTab;
case _DatabaseTab.products:
return 'Produkter';
return context.l10n.profileProductsTab;
}
}
@@ -282,20 +283,18 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
case _DatabaseTab.inventory:
activeSection = sectionCard(
icon: Icons.inventory_2_outlined,
title: 'Inventarie',
description:
'Lägg till, uppdatera och konsumera varor i ditt inventarie. Detta motsvarar inventarievyn under Databas i recipe-frontend.',
title: context.l10n.profileInventoryTab,
description: context.l10n.profileInventoryDescription,
onPressed: () => context.go('/inventory'),
buttonLabel: 'Öppna inventarie',
buttonLabel: context.l10n.profileOpenInventory,
);
case _DatabaseTab.pantry:
activeSection = sectionCard(
icon: Icons.storefront_outlined,
title: 'Baslager',
description:
'Hantera varor du alltid räknar med att ha hemma. Detta motsvarar baslagervyn under Databas i recipe-frontend.',
title: context.l10n.profilePantryTab,
description: context.l10n.profilePantryDescription,
onPressed: () => context.go('/baslager'),
buttonLabel: 'Öppna baslager',
buttonLabel: context.l10n.profileOpenPantry,
);
case _DatabaseTab.products:
activeSection = const AdminProductsPanel(embedded: true);
@@ -305,7 +304,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Databasfliken samlar samma huvudområden som i recipe-frontend.',
context.l10n.profileDatabaseDescription,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 12),
@@ -366,7 +365,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
children: [
Text(_error!, style: TextStyle(color: theme.colorScheme.error)),
const SizedBox(height: 16),
FilledButton(onPressed: _loadProfile, child: const Text('Försök igen')),
FilledButton(onPressed: _loadProfile, child: Text(context.l10n.retryAction)),
],
),
);
@@ -424,7 +423,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
child: OutlinedButton.icon(
onPressed: _logout,
icon: const Icon(Icons.logout),
label: const Text('Logga ut'),
label: Text(context.l10n.logoutAction),
),
),
],