feat(flutter/settings): admin card visible to admins

Settings gains an _AdminSection that renders an "Admin" tile (Shield
icon → /admin) only when the current profile has is_admin = true.
Non-admins see the section as SizedBox.shrink() so the const ListView
children stay const.

Provides a discoverable second entry to the admin landing alongside
the kebab overflow shortcut.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 21:53:35 -04:00
parent 6b5d12f3a1
commit 408eed1f3d
@@ -48,6 +48,7 @@ class SettingsScreen extends ConsumerWidget {
_PasswordSection(),
_Divider(),
_ListenBrainzSection(),
_AdminSection(),
SizedBox(height: 96),
],
),
@@ -87,6 +88,44 @@ class _SectionHeader extends StatelessWidget {
}
}
/// Renders an "Admin" entry only when the current profile has
/// `is_admin = true`. Returns an empty SizedBox otherwise so the
/// const-children layout above stays valid.
class _AdminSection extends ConsumerWidget {
const _AdminSection();
@override
Widget build(BuildContext context, WidgetRef ref) {
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
final profile = ref.watch(_profileProvider).valueOrNull;
if (profile == null || !profile.isAdmin) return const SizedBox.shrink();
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const _Divider(),
ListTile(
key: const Key('settings_admin_card'),
leading: Icon(Icons.shield, color: fs.parchment),
title: Text(
'Admin',
style: TextStyle(
color: fs.parchment,
fontFamily: 'Fraunces',
fontSize: 18,
),
),
subtitle: Text(
'Manage requests, quarantine, and users',
style: TextStyle(color: fs.ash),
),
trailing: Icon(Icons.chevron_right, color: fs.ash),
onTap: () => context.push('/admin'),
),
],
);
}
}
class _ProfileSection extends ConsumerStatefulWidget {
const _ProfileSection();
@override