Eliminar creche_app/lib/features/auth/waiting_approval_screen.dart
This commit is contained in:
parent
8e10d73296
commit
30a5dfdd2f
|
|
@ -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)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue