Eliminar creche_app/lib/features/auth/waiting_approval_screen.dart

This commit is contained in:
Alberto 2026-03-11 19:24:00 +00:00
parent 8e10d73296
commit 30a5dfdd2f
1 changed files with 0 additions and 167 deletions

View File

@ -1,167 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:go_router/go_router.dart';
import '/core/auth_provider.dart';
import '/models/daily_access_approval.dart';
class WaitingApprovalScreen extends ConsumerStatefulWidget {
const WaitingApprovalScreen({super.key});
@override
ConsumerState<WaitingApprovalScreen> createState() => _State();
}
class _State extends ConsumerState<WaitingApprovalScreen> {
String? _profileId;
bool _requesting = false;
@override
void initState() {
super.initState();
_loadProfileAndRequest();
}
Future<void> _loadProfileAndRequest() async {
final sb = Supabase.instance.client;
final uid = sb.auth.currentUser?.id;
if (uid == null) return;
// Buscar profiles.id (NÃO auth.uid!)
final profile = await sb.from('profiles').select('id').eq('user_id', uid).maybeSingle();
if (profile == null || !mounted) return;
final profileId = profile['id'] as String;
setState(() => _profileId = profileId);
// Criar pedido de aprovação se não existir hoje
final today = DateTime.now().toIso8601String().split('T')[0];
final existing = await sb.from('daily_access_approvals')
.select().eq('user_id', profileId).eq('approval_date', today).maybeSingle();
if (existing == null && mounted) {
setState(() => _requesting = true);
try {
await sb.from('daily_access_approvals').insert({
'user_id': profileId,
'approval_date': today,
'status': 'pending',
});
} catch (_) {}
if (mounted) setState(() => _requesting = false);
}
}
@override
Widget build(BuildContext context) {
final sb = Supabase.instance.client;
final today = DateTime.now().toIso8601String().split('T')[0];
return Scaffold(
backgroundColor: const Color(0xFF0D1117),
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Image.asset('assets/logo.png', height: 72,
errorBuilder: (_, __, ___) =>
const Icon(Icons.child_care, size: 72, color: Color(0xFF4FC3F7))),
const SizedBox(height: 24),
Lottie.asset('assets/waiting.json', height: 160,
errorBuilder: (_, __, ___) =>
const Icon(Icons.hourglass_top, size: 80, color: Color(0xFF4FC3F7))),
const SizedBox(height: 20),
const Text('Sala de Espera',
style: TextStyle(color: Color(0xFF4FC3F7), fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
const Text('Aguardando aprovação da Diretora',
style: TextStyle(color: Colors.white, fontSize: 15), textAlign: TextAlign.center),
const SizedBox(height: 6),
Text('O teu acesso de hoje será aprovado em breve.',
style: TextStyle(color: Colors.white.withOpacity(0.4), fontSize: 12),
textAlign: TextAlign.center),
const SizedBox(height: 32),
if (_requesting)
const CircularProgressIndicator(color: Color(0xFF4FC3F7))
else if (_profileId != null)
StreamBuilder<List<Map<String, dynamic>>>(
stream: sb.from('daily_access_approvals')
.stream(primaryKey: ['id'])
.eq('user_id', _profileId!) // usa profiles.id CORRECTO
.order('created_at', ascending: false),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const CircularProgressIndicator(color: Color(0xFF4FC3F7));
}
final todayRows = snapshot.data!
.where((r) => r['approval_date'] == today).toList();
if (todayRows.isEmpty) {
return Column(children: [
const CircularProgressIndicator(color: Color(0xFF4FC3F7)),
const SizedBox(height: 12),
Text('A criar pedido...', style: TextStyle(color: Colors.white.withOpacity(0.4))),
]);
}
final approval = DailyAccessApproval.fromMap(todayRows.first);
if (approval.status == 'approved') {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) context.go('/home');
});
return const Column(children: [
Icon(Icons.check_circle, color: Color(0xFF2ECC71), size: 48),
SizedBox(height: 8),
Text('Aprovado! A redirecionar...', style: TextStyle(color: Color(0xFF2ECC71))),
]);
}
if (approval.status == 'rejected') {
return Column(children: [
const Icon(Icons.block, color: Colors.red, size: 48),
const SizedBox(height: 8),
const Text('Acesso negado hoje',
style: TextStyle(color: Colors.red, fontSize: 17, fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Text('Contacta a Diretora para mais informações.',
style: TextStyle(color: Colors.white.withOpacity(0.4), fontSize: 12),
textAlign: TextAlign.center),
]);
}
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
const SizedBox(width: 20, height: 20,
child: CircularProgressIndicator(color: Color(0xFF4FC3F7), strokeWidth: 2)),
const SizedBox(width: 12),
Text('Pendente... aguarda',
style: TextStyle(color: Colors.white.withOpacity(0.5), fontSize: 13)),
]);
},
)
else
const CircularProgressIndicator(color: Color(0xFF4FC3F7)),
const SizedBox(height: 36),
OutlinedButton.icon(
icon: const Icon(Icons.logout, color: Colors.red, size: 18),
label: const Text('Terminar Sessão', style: TextStyle(color: Colors.red)),
onPressed: () async {
await ref.read(authNotifierProvider.notifier).signOut();
if (context.mounted) context.go('/login');
},
style: OutlinedButton.styleFrom(
minimumSize: const Size(double.infinity, 46),
side: const BorderSide(color: Colors.red),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
),
]),
),
),
),
);
}
}