user admin capability

This commit is contained in:
davmar
2026-09-10 22:58:52 +02:00
parent 6cc0de8945
commit c4f0ca785e
7 changed files with 420 additions and 21 deletions
+66 -1
View File
@@ -1,6 +1,8 @@
/// Signed-in account details, sync status, bank link, and sign-out.
library;
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -10,11 +12,26 @@ import '../providers/sync_provider.dart';
import '../providers/tx_meta_provider.dart';
import '../utils/connect_bank.dart';
import '../utils/constants.dart';
import '../widgets/admin_create_transaction_dialog.dart';
import '../widgets/responsive_body.dart';
class AccountScreen extends StatelessWidget {
class AccountScreen extends StatefulWidget {
const AccountScreen({super.key});
@override
State<AccountScreen> createState() => _AccountScreenState();
}
class _AccountScreenState extends State<AccountScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
unawaited(context.read<AuthController>().refreshSession());
});
}
@override
Widget build(BuildContext context) {
final auth = context.watch<AuthController>();
@@ -62,6 +79,24 @@ class AccountScreen extends StatelessWidget {
),
),
),
if (auth.isAdmin)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Chip(
avatar: Icon(
Icons.shield_outlined,
size: 16,
color: colors.onSecondaryContainer,
),
label: const Text('Admin'),
visualDensity: VisualDensity.compact,
backgroundColor: colors.secondaryContainer,
labelStyle: theme.textTheme.labelMedium?.copyWith(
color: colors.onSecondaryContainer,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(height: 24),
Card(
child: Column(
@@ -90,6 +125,36 @@ class AccountScreen extends StatelessWidget {
],
),
),
if (auth.isAdmin) ...[
const SizedBox(height: 16),
Card(
child: ListTile(
leading: const Icon(Icons.add_card_outlined),
title: const Text('Create test transaction'),
subtitle: const Text(
'Admin only · local + syncs to PocketBase',
),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
final tx = await showAdminCreateTransactionDialog(context);
if (tx == null || !context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Created “${tx.description}” · '
'${tx.amount.toStringAsFixed(2)} ${tx.currency}',
),
),
);
// Push so other devices / PB see it soon.
final sync = context.read<SyncController>();
if (sync.canSync && !sync.isSyncing) {
unawaited(sync.syncNow());
}
},
),
),
],
const SizedBox(height: 16),
Card(
child: ListTile(