import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../models/admin_user.dart'; import '../../theme/theme_extension.dart'; import '../admin_providers.dart'; import 'typed_confirm_sheet.dart'; class AdminUserEditSheet extends ConsumerWidget { const AdminUserEditSheet({super.key, required this.user}); final AdminUser user; static Future show(BuildContext context, AdminUser user) => showModalBottomSheet( context: context, isScrollControlled: true, builder: (_) => AdminUserEditSheet(user: user), ); @override Widget build(BuildContext context, WidgetRef ref) { final fs = Theme.of(context).extension()!; final users = ref.read(adminUsersProvider.notifier); return Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, ), child: Container( color: fs.iron, padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( user.username, style: TextStyle( color: fs.parchment, fontFamily: 'Fraunces', fontSize: 20, ), ), const SizedBox(height: 12), SwitchListTile( key: const Key('user_edit_is_admin'), title: Text('Admin', style: TextStyle(color: fs.parchment)), value: user.isAdmin, onChanged: (v) async { try { await users.setAdmin(user.id, v); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('$e'))); } } }, ), SwitchListTile( key: const Key('user_edit_auto_approve'), title: Text('Auto-approve requests', style: TextStyle(color: fs.parchment)), value: user.autoApproveRequests, onChanged: (v) async { try { await users.setAutoApprove(user.id, v); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('$e'))); } } }, ), const SizedBox(height: 12), Row( children: [ TextButton( key: const Key('user_edit_reset_password'), onPressed: () => _resetPassword(context, users), child: const Text('Reset password'), ), const Spacer(), TextButton( key: const Key('user_edit_delete'), style: TextButton.styleFrom(foregroundColor: fs.oxblood), onPressed: () => _deleteUser(context, users), child: const Text('Delete'), ), ], ), ], ), ), ); } Future _resetPassword( BuildContext context, AdminUsersController users) async { final controller = TextEditingController(); final newPw = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Reset password'), content: TextField( controller: controller, obscureText: true, decoration: const InputDecoration( labelText: 'New password', helperText: 'Minimum 8 characters', ), ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Cancel'), ), TextButton( onPressed: () { if (controller.text.length >= 8) { Navigator.pop(ctx, controller.text); } }, child: const Text('Reset'), ), ], ), ); if (newPw == null || !context.mounted) return; try { await users.resetPassword(user.id, newPw); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Password reset.')), ); } } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('$e'))); } } } Future _deleteUser( BuildContext context, AdminUsersController users) async { if (!await TypedConfirmSheet.show( context, title: 'Delete user?', message: 'Permanently delete user "${user.username}" and all their data. ' 'Cannot be undone.', )) { return; } try { await users.delete(user.id); if (context.mounted) Navigator.pop(context); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('$e'))); } } } }