feat(receipt-import): add refresh categories endpoint and UI integration

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Nils-Johan Gynther
2026-05-03 10:48:06 +02:00
parent 6503d29801
commit b2eb870ec7
7 changed files with 79 additions and 16 deletions
+4
View File
@@ -25,6 +25,10 @@ class CategoryApiPaths {
static const tree = '/categories/tree';
}
class ReceiptImportApiPaths {
static const refreshCategories = '/receipt-import/refresh-categories';
}
class RecipeApiPaths {
static const list = '/recipes';
static String detail(int id) => '/recipes/$id';
@@ -41,4 +41,12 @@ class ProfileRepository {
);
return UserProfile.fromJson(data);
}
Future<void> refreshCategories() async {
final token = await _ref.read(authStateProvider.future);
await guardedApiCall(
_ref,
() => _apiClient.postJson(ReceiptImportApiPaths.refreshCategories, body: {}, token: token),
);
}
}
@@ -27,6 +27,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
final _formKey = GlobalKey<FormState>();
bool _isLoading = true;
bool _isSaving = false;
bool _isRefreshingCategories = false;
String? _error;
UserProfile? _profile;
_ProfileTab _activeTab = _ProfileTab.profile;
@@ -105,6 +106,24 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
context.go('/login');
}
Future<void> _refreshCategories() async {
setState(() => _isRefreshingCategories = true);
try {
await ref.read(profileRepositoryProvider).refreshCategories();
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Kategorier har uppdaterats.')),
);
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(mapErrorToUserMessage(e, context))),
);
} finally {
if (mounted) setState(() => _isRefreshingCategories = false);
}
}
List<_ProfileTab> _visibleTabs(bool isAdmin) {
return [
_ProfileTab.profile,
@@ -212,6 +231,23 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
: Text(context.l10n.profileSaveAction),
),
),
const SizedBox(height: 16),
const Divider(),
const SizedBox(height: 8),
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: _isRefreshingCategories ? null : _refreshCategories,
icon: _isRefreshingCategories
? const SizedBox(
height: 16,
width: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.refresh),
label: const Text('Uppdatera kategorier'),
),
),
],
),
);