Eliminar creche_app/lib/features/splash/splash_screen.dart
This commit is contained in:
parent
d07875afd3
commit
49b3a21dfe
|
|
@ -1,137 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:lottie/lottie.dart';
|
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
||||||
import '/core/auth_provider.dart';
|
|
||||||
import '/models/invite.dart';
|
|
||||||
import '/features/auth/invite_pending_screen.dart';
|
|
||||||
|
|
||||||
class SplashScreen extends ConsumerStatefulWidget {
|
|
||||||
const SplashScreen({super.key});
|
|
||||||
@override
|
|
||||||
ConsumerState<SplashScreen> createState() => _SplashScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SplashScreenState extends ConsumerState<SplashScreen>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
late AnimationController _ctrl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_ctrl = AnimationController(vsync: this, duration: const Duration(seconds: 2));
|
|
||||||
_ctrl.forward();
|
|
||||||
Future.delayed(const Duration(milliseconds: 2200), _navigate);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _navigate() async {
|
|
||||||
if (!mounted) return;
|
|
||||||
try {
|
|
||||||
await ref.read(authNotifierProvider.future);
|
|
||||||
final session = await ref.read(currentSessionProvider.future);
|
|
||||||
if (!mounted) return;
|
|
||||||
|
|
||||||
if (session == null) { context.go('/login'); return; }
|
|
||||||
|
|
||||||
// ─── Verificar se o utilizador tem perfil
|
|
||||||
final supabase = Supabase.instance.client;
|
|
||||||
final profile = await supabase
|
|
||||||
.from('profiles')
|
|
||||||
.select()
|
|
||||||
.eq('user_id', session.user.id)
|
|
||||||
.maybeSingle();
|
|
||||||
|
|
||||||
// ─── Verificar convite pendente pelo email
|
|
||||||
final email = session.user.email ?? '';
|
|
||||||
final inviteData = await supabase
|
|
||||||
.from('invites')
|
|
||||||
.select()
|
|
||||||
.eq('email', email)
|
|
||||||
.eq('status', 'pending')
|
|
||||||
.gt('expires_at', DateTime.now().toIso8601String())
|
|
||||||
.order('created_at', ascending: false)
|
|
||||||
.limit(1)
|
|
||||||
.maybeSingle();
|
|
||||||
|
|
||||||
if (!mounted) return;
|
|
||||||
|
|
||||||
if (inviteData != null) {
|
|
||||||
final invite = Invite.fromMap(inviteData);
|
|
||||||
if (!invite.isExpired) {
|
|
||||||
// Mostrar ecrã de aceitação de convite
|
|
||||||
Navigator.of(context).pushReplacement(
|
|
||||||
MaterialPageRoute(builder: (_) => InvitePendingScreen(invite: invite)),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile == null) {
|
|
||||||
// Sem perfil e sem convite → ecrã de espera / registo incompleto
|
|
||||||
context.go('/login');
|
|
||||||
} else {
|
|
||||||
context.go('/home');
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
if (mounted) context.go('/login');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() { _ctrl.dispose(); super.dispose(); }
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: const Color(0xFF0D1117),
|
|
||||||
body: Stack(children: [
|
|
||||||
// Orbs
|
|
||||||
Positioned(top: -100, right: -80,
|
|
||||||
child: _orb(300, const Color(0xFF4FC3F7).withOpacity(0.08))),
|
|
||||||
Positioned(bottom: -80, left: -60,
|
|
||||||
child: _orb(250, const Color(0xFFA5D6A7).withOpacity(0.06))),
|
|
||||||
SafeArea(
|
|
||||||
child: Center(
|
|
||||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
||||||
// Logo com glow
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
gradient: RadialGradient(colors: [
|
|
||||||
const Color(0xFF4FC3F7).withOpacity(0.15),
|
|
||||||
Colors.transparent,
|
|
||||||
]),
|
|
||||||
border: Border.all(color: const Color(0xFF4FC3F7).withOpacity(0.2), width: 1.5),
|
|
||||||
),
|
|
||||||
child: Image.asset('assets/logo.png', height: 100,
|
|
||||||
errorBuilder: (_, __, ___) => const Icon(Icons.child_care, size: 80, color: Color(0xFF4FC3F7))),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
const Text('SEMENTES DO FUTURO',
|
|
||||||
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: 2)),
|
|
||||||
const SizedBox(height: 6),
|
|
||||||
const Text('Diário do Candengue',
|
|
||||||
style: TextStyle(color: Color(0xFF4FC3F7), fontSize: 13, letterSpacing: 1.5)),
|
|
||||||
const SizedBox(height: 48),
|
|
||||||
Lottie.asset('assets/splash_animation.json',
|
|
||||||
controller: _ctrl, height: 80, repeat: false,
|
|
||||||
errorBuilder: (_, __, ___) => const SizedBox(
|
|
||||||
height: 40, width: 40,
|
|
||||||
child: CircularProgressIndicator(color: Color(0xFF4FC3F7), strokeWidth: 2),
|
|
||||||
)),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Text('"Conforto, cuidado e aprendizagem"',
|
|
||||||
style: TextStyle(color: Colors.white.withOpacity(0.3), fontSize: 12, fontStyle: FontStyle.italic)),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _orb(double size, Color color) => Container(width: size, height: size,
|
|
||||||
decoration: BoxDecoration(shape: BoxShape.circle, color: color,
|
|
||||||
boxShadow: [BoxShadow(color: color, blurRadius: size / 2)]));
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue