Files
minstrel/flutter_client/lib/admin/widgets/admin_user_row.dart
T
bvandeusen afcaf56b9c feat(flutter/admin): user row + edit sheet (toggles, reset, delete)
AdminUserRow shows username + admin/auto-approve badges; tap opens
AdminUserEditSheet bottom sheet.

Edit sheet: SwitchListTile pair for is_admin and auto_approve_requests
(both surface server errors via SnackBar, including the last-admin
guard). Reset password takes a typed-input dialog (>=8 chars enforced
client-side; admin supplies the new password). Delete routes through
TypedConfirmSheet ("DELETE") and pops the sheet on success.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 21:57:10 -04:00

59 lines
1.5 KiB
Dart

import 'package:flutter/material.dart';
import '../../models/admin_user.dart';
import '../../theme/theme_extension.dart';
class AdminUserRow extends StatelessWidget {
const AdminUserRow({super.key, required this.user, required this.onTap});
final AdminUser user;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
return ListTile(
title: Text(
user.username,
style: TextStyle(
color: fs.parchment,
fontFamily: 'Fraunces',
fontSize: 16,
),
),
subtitle: Wrap(
spacing: 6,
children: [
if (user.isAdmin) _Badge(label: 'admin', color: fs.bronze),
if (user.autoApproveRequests)
_Badge(label: 'auto-approve', color: fs.moss),
],
),
trailing: Icon(Icons.chevron_right, color: fs.ash),
onTap: onTap,
);
}
}
class _Badge extends StatelessWidget {
const _Badge({required this.label, required this.color});
final String label;
final Color color;
@override
Widget build(BuildContext context) {
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
),
child: Text(
label,
style: TextStyle(color: fs.obsidian, fontSize: 11),
),
);
}
}