A better state and alerts

This commit is contained in:
2026-02-23 20:19:07 +08:00
parent 0b900d3480
commit 1074572905
17 changed files with 673 additions and 428 deletions
+12 -20
View File
@@ -11,6 +11,7 @@ import '../../utils/supabase_response.dart';
import 'package:tasq/widgets/multi_select_picker.dart';
import '../../theme/app_surfaces.dart';
import '../../widgets/tasq_adaptive_list.dart';
import '../../utils/snackbar.dart';
// Note: `officesProvider` is provided globally in `tickets_provider.dart` so
// we reuse that StreamProvider here (avoids duplicate queries).
@@ -368,26 +369,18 @@ class _TeamsScreenState extends ConsumerState<TeamsScreen> {
}
Future<void> onSave(StateSetter setState, NavigatorState navigator) async {
final messenger = ScaffoldMessenger.of(navigator.context);
final ctx = context; // capture for async use
final name = nameController.text.trim();
if (name.isEmpty) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Team name is required')));
showWarningSnackBar(ctx, 'Team name is required');
return;
}
if (leaderId == null) {
messenger.showSnackBar(
const SnackBar(content: Text('Please select a team leader')),
);
showWarningSnackBar(ctx, 'Please select a team leader');
return;
}
if (selectedOffices.isEmpty) {
messenger.showSnackBar(
const SnackBar(
content: Text('Assign at least one office to the team'),
),
);
showWarningSnackBar(ctx, 'Assign at least one office to the team');
return;
}
@@ -506,9 +499,9 @@ class _TeamsScreenState extends ConsumerState<TeamsScreen> {
}
}
} catch (e) {
messenger.showSnackBar(
SnackBar(content: Text('Failed to save team: $e')),
);
if (!mounted) return;
// ignore: use_build_context_synchronously
showErrorSnackBar(context, 'Failed to save team: $e');
return;
}
@@ -604,8 +597,6 @@ class _TeamsScreenState extends ConsumerState<TeamsScreen> {
}
void _deleteTeam(BuildContext context, String teamId) async {
final messenger = ScaffoldMessenger.of(context);
final confirmed = await showDialog<bool?>(
context: context,
builder: (dialogContext) => AlertDialog(
@@ -630,6 +621,7 @@ class _TeamsScreenState extends ConsumerState<TeamsScreen> {
if (confirmed != true) return;
final ctx = context; // capture before async gaps
try {
final delMembersRes = await ref
.read(supabaseClientProvider)
@@ -650,9 +642,9 @@ class _TeamsScreenState extends ConsumerState<TeamsScreen> {
ref.invalidate(teamsProvider);
ref.invalidate(teamMembersProvider);
} catch (e) {
messenger.showSnackBar(
SnackBar(content: Text('Failed to delete team: $e')),
);
if (!mounted) return;
// ignore: use_build_context_synchronously
showErrorSnackBar(ctx, 'Failed to delete team: $e');
return;
}
}