Eliminar creche_app/lib/features/home/home_dashboard.dart
This commit is contained in:
parent
f2f795cf38
commit
7efc7e3c9e
|
|
@ -1,741 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '/core/auth_provider.dart';
|
||||
import '/models/profile.dart';
|
||||
import '/models/child.dart';
|
||||
import '/models/daily_access_approval.dart';
|
||||
|
||||
class HomeDashboard extends ConsumerWidget {
|
||||
const HomeDashboard({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final profileAsync = ref.watch(currentProfileProvider);
|
||||
|
||||
return profileAsync.when(
|
||||
data: (profile) {
|
||||
if (profile == null) {
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('Perfil não encontrado')),
|
||||
);
|
||||
}
|
||||
switch (profile.role) {
|
||||
case 'principal':
|
||||
case 'admin':
|
||||
return _AdminDashboard(profile: profile);
|
||||
case 'teacher':
|
||||
return _TeacherDashboard(profile: profile);
|
||||
case 'parent':
|
||||
return _ParentDashboard(profile: profile);
|
||||
default:
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('Role desconhecido')));
|
||||
}
|
||||
},
|
||||
loading: () =>
|
||||
const Scaffold(body: Center(child: CircularProgressIndicator())),
|
||||
error: (e, _) => Scaffold(body: Center(child: Text('Erro: $e'))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────── ADMIN DASHBOARD ───────────────
|
||||
class _AdminDashboard extends ConsumerWidget {
|
||||
final Profile profile;
|
||||
const _AdminDashboard({required this.profile});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final supabase = Supabase.instance.client;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFF0D1117),
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
title: Row(
|
||||
children: [
|
||||
Image.asset('assets/logo.png', height: 36,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.child_care, color: Color(0xFF4FC3F7))),
|
||||
const SizedBox(width: 10),
|
||||
const Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Sementes do Futuro',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF4FC3F7),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold)),
|
||||
Text('Dashboard Admin',
|
||||
style:
|
||||
TextStyle(color: Color(0xFF888888), fontSize: 11)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.notifications_outlined,
|
||||
color: Color(0xFF4FC3F7)),
|
||||
onPressed: () => context.go('/announcements'),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings_outlined,
|
||||
color: Color(0xFF4FC3F7)),
|
||||
onPressed: () => context.go('/settings'),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Olá, ${profile.fullName.split(' ').first}! 👋',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 4),
|
||||
Text(DateFormat('EEEE, d MMMM yyyy', 'pt_PT').format(DateTime.now()),
|
||||
style: const TextStyle(color: Color(0xFF888888), fontSize: 13)),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Quick actions
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_QuickAction(
|
||||
icon: Icons.add_circle,
|
||||
label: 'Diário',
|
||||
onTap: () => context.go('/new-diary')),
|
||||
_QuickAction(
|
||||
icon: Icons.check_circle,
|
||||
label: 'Presença',
|
||||
onTap: () => context.go('/attendance')),
|
||||
_QuickAction(
|
||||
icon: Icons.attach_money,
|
||||
label: 'Pagamentos',
|
||||
onTap: () => context.go('/payments')),
|
||||
_QuickAction(
|
||||
icon: Icons.campaign,
|
||||
label: 'Avisos',
|
||||
onTap: () => context.go('/announcements')),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Cards de estatísticas
|
||||
const Text('Visão Geral',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 12),
|
||||
GridView.count(
|
||||
crossAxisCount: 2,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
childAspectRatio: 1.5,
|
||||
children: const [
|
||||
_StatCard(title: 'Crianças Hoje', value: '–', icon: Icons.child_care, color: Color(0xFF4FC3F7)),
|
||||
_StatCard(title: 'Presença', value: '–%', icon: Icons.check_circle, color: Color(0xFFA5D6A7)),
|
||||
_StatCard(title: 'Pendentes', value: '–', icon: Icons.payment, color: Color(0xFFFFCC02)),
|
||||
_StatCard(title: 'Avisos', value: '–', icon: Icons.campaign, color: Color(0xFFFF7043)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Aprovações pendentes
|
||||
const Text('Pedidos de Acesso Hoje',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 12),
|
||||
StreamBuilder<List<Map<String, dynamic>>>(
|
||||
stream: supabase
|
||||
.from('daily_access_approvals')
|
||||
.stream(primaryKey: ['id']).eq('status', 'pending'),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xFF4FC3F7)));
|
||||
}
|
||||
final approvals = snapshot.data!;
|
||||
if (approvals.isEmpty) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.check_circle, color: Color(0xFFA5D6A7)),
|
||||
SizedBox(width: 8),
|
||||
Text('Nenhum pedido pendente',
|
||||
style: TextStyle(color: Color(0xFF888888))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: approvals.length,
|
||||
itemBuilder: (context, index) {
|
||||
final approval =
|
||||
DailyAccessApproval.fromMap(approvals[index]);
|
||||
return _ApprovalCard(
|
||||
approval: approval,
|
||||
onApprove: () => _approve(supabase, approval.id),
|
||||
onReject: () => _reject(supabase, approval.id),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 80),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: _AdminBottomNav(),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
backgroundColor: const Color(0xFF4FC3F7),
|
||||
icon: const Icon(Icons.person_add, color: Colors.white),
|
||||
label:
|
||||
const Text('Nova Criança', style: TextStyle(color: Colors.white)),
|
||||
onPressed: () => context.go('/child/new'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _approve(SupabaseClient supabase, String id) async {
|
||||
await supabase.from('daily_access_approvals').update({
|
||||
'status': 'approved',
|
||||
'approved_at': DateTime.now().toIso8601String(),
|
||||
'approved_by': supabase.auth.currentUser!.id,
|
||||
}).eq('id', id);
|
||||
}
|
||||
|
||||
Future<void> _reject(SupabaseClient supabase, String id) async {
|
||||
await supabase
|
||||
.from('daily_access_approvals')
|
||||
.update({'status': 'rejected'}).eq('id', id);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────── TEACHER DASHBOARD ───────────────
|
||||
class _TeacherDashboard extends ConsumerWidget {
|
||||
final Profile profile;
|
||||
const _TeacherDashboard({required this.profile});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final supabase = Supabase.instance.client;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFF0D1117),
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
title: const Text('Minha Turma',
|
||||
style: TextStyle(color: Color(0xFF4FC3F7))),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.chat_outlined, color: Color(0xFF4FC3F7)),
|
||||
onPressed: () => context.go('/chat'),
|
||||
),
|
||||
IconButton(
|
||||
icon:
|
||||
const Icon(Icons.person_outline, color: Color(0xFF4FC3F7)),
|
||||
onPressed: () => context.go('/profile'),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'Olá, ${profile.fullName.split(' ').first}! 👋',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text('Crianças da tua turma hoje:',
|
||||
style: TextStyle(color: Color(0xFF888888), fontSize: 14)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Expanded(
|
||||
child: StreamBuilder<List<Map<String, dynamic>>>(
|
||||
stream: supabase
|
||||
.from('children')
|
||||
.stream(primaryKey: ['id']).eq('teacher_id', profile.id),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(
|
||||
child:
|
||||
CircularProgressIndicator(color: Color(0xFF4FC3F7)));
|
||||
}
|
||||
final children =
|
||||
snapshot.data!.map(Child.fromMap).toList();
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
itemCount: children.length,
|
||||
itemBuilder: (context, index) {
|
||||
final child = children[index];
|
||||
return _ChildCard(
|
||||
child: child,
|
||||
onTap: () => context.go('/child/${child.id}'),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
backgroundColor: const Color(0xFF4FC3F7),
|
||||
icon: const Icon(Icons.add, color: Colors.white),
|
||||
label:
|
||||
const Text('Novo Diário', style: TextStyle(color: Colors.white)),
|
||||
onPressed: () => context.go('/new-diary'),
|
||||
),
|
||||
bottomNavigationBar: _TeacherBottomNav(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────── PARENT DASHBOARD ───────────────
|
||||
class _ParentDashboard extends ConsumerWidget {
|
||||
final Profile profile;
|
||||
const _ParentDashboard({required this.profile});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFF0D1117),
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
title: Image.asset('assets/logo.png', height: 36,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.child_care, color: Color(0xFF4FC3F7))),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon:
|
||||
const Icon(Icons.notifications_outlined, color: Color(0xFF4FC3F7)),
|
||||
onPressed: () => context.go('/announcements'),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 30,
|
||||
backgroundColor: const Color(0xFF4FC3F7),
|
||||
child: Text(
|
||||
profile.fullName.isNotEmpty
|
||||
? profile.fullName[0].toUpperCase()
|
||||
: 'P',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Bem-vindo(a)!',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF888888), fontSize: 12)),
|
||||
Text(profile.fullName,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const Text('Ações Rápidas',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
icon: Icons.book_outlined,
|
||||
label: 'Ver Diário',
|
||||
onTap: () => context.go('/children'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
icon: Icons.restaurant_menu,
|
||||
label: 'Cardápio',
|
||||
onTap: () => context.go('/menu'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
icon: Icons.medication,
|
||||
label: 'Medicação',
|
||||
onTap: () => context.go('/medication'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
icon: Icons.chat_outlined,
|
||||
label: 'Falar c/ Educadora',
|
||||
onTap: () => context.go('/chat'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: _ParentBottomNav(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────── WIDGETS AUXILIARES ───────────────
|
||||
|
||||
class _QuickAction extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final VoidCallback onTap;
|
||||
const _QuickAction(
|
||||
{required this.icon, required this.label, required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFF333366)),
|
||||
),
|
||||
child: Icon(icon, color: const Color(0xFF4FC3F7), size: 26),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(label,
|
||||
style: const TextStyle(color: Color(0xFF888888), fontSize: 12)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StatCard extends StatelessWidget {
|
||||
final String title;
|
||||
final String value;
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
const _StatCard(
|
||||
{required this.title,
|
||||
required this.value,
|
||||
required this.icon,
|
||||
required this.color});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: color.withOpacity(0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, color: color, size: 22),
|
||||
const SizedBox(height: 4),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(value,
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold)),
|
||||
),
|
||||
Text(title,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF888888), fontSize: 10),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ApprovalCard extends StatelessWidget {
|
||||
final DailyAccessApproval approval;
|
||||
final VoidCallback onApprove;
|
||||
final VoidCallback onReject;
|
||||
const _ApprovalCard(
|
||||
{required this.approval,
|
||||
required this.onApprove,
|
||||
required this.onReject});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: const Color(0xFFFFCC02).withOpacity(0.3)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.person_outline, color: Color(0xFF4FC3F7)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Funcionário: ${approval.userId.substring(0, 8)}...',
|
||||
style: const TextStyle(color: Colors.white, fontSize: 13)),
|
||||
Text(
|
||||
'IP: ${approval.ipAddress ?? 'N/A'} • ${DateFormat('HH:mm').format(approval.approvalDate)}',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF888888), fontSize: 11)),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.check_circle, color: Color(0xFFA5D6A7)),
|
||||
onPressed: onApprove,
|
||||
tooltip: 'Aprovar',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.cancel, color: Colors.red),
|
||||
onPressed: onReject,
|
||||
tooltip: 'Rejeitar',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ChildCard extends StatelessWidget {
|
||||
final Child child;
|
||||
final VoidCallback onTap;
|
||||
const _ChildCard({required this.child, required this.onTap});
|
||||
|
||||
String get _moodEmoji {
|
||||
switch (child.mood) {
|
||||
case 'happy': return '😊';
|
||||
case 'sad': return '😟';
|
||||
case 'sick': return '🤒';
|
||||
case 'excited': return '😃';
|
||||
default: return '😐';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFF333366)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 26,
|
||||
backgroundImage: child.photoUrl != null
|
||||
? NetworkImage(child.photoUrl!)
|
||||
: null,
|
||||
backgroundColor: const Color(0xFF4FC3F7).withOpacity(0.2),
|
||||
child: child.photoUrl == null
|
||||
? const Icon(Icons.child_care,
|
||||
color: Color(0xFF4FC3F7), size: 28)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(child.fullName,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15)),
|
||||
Text('${child.age} anos',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF888888), fontSize: 12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(_moodEmoji, style: const TextStyle(fontSize: 28)),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.chevron_right, color: Color(0xFF888888)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActionButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final VoidCallback onTap;
|
||||
const _ActionButton(
|
||||
{required this.icon, required this.label, required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF161B22),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFF333366)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, color: const Color(0xFF4FC3F7), size: 28),
|
||||
const SizedBox(height: 8),
|
||||
Text(label,
|
||||
style:
|
||||
const TextStyle(color: Colors.white, fontSize: 13),
|
||||
textAlign: TextAlign.center),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom Navs
|
||||
class _AdminBottomNav extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BottomNavigationBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
selectedItemColor: const Color(0xFF4FC3F7),
|
||||
unselectedItemColor: const Color(0xFF888888),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
items: const [
|
||||
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Início'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.child_care), label: 'Crianças'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.check_box), label: 'Presença'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.people), label: 'Utilizadores'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Perfil'),
|
||||
],
|
||||
onTap: (i) {
|
||||
final routes = ['/home', '/children', '/attendance', '/users', '/profile'];
|
||||
context.go(routes[i]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TeacherBottomNav extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BottomNavigationBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
selectedItemColor: const Color(0xFF4FC3F7),
|
||||
unselectedItemColor: const Color(0xFF888888),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
items: const [
|
||||
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Início'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.child_care), label: 'Crianças'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.book), label: 'Diários'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'Chat'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Perfil'),
|
||||
],
|
||||
onTap: (i) {
|
||||
final routes = ['/home', '/children', '/new-diary', '/chat', '/profile'];
|
||||
context.go(routes[i]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ParentBottomNav extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BottomNavigationBar(
|
||||
backgroundColor: const Color(0xFF161B22),
|
||||
selectedItemColor: const Color(0xFF4FC3F7),
|
||||
unselectedItemColor: const Color(0xFF888888),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
items: const [
|
||||
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Início'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.child_care), label: 'Filhos'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.restaurant_menu), label: 'Cardápio'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'Chat'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Perfil'),
|
||||
],
|
||||
onTap: (i) {
|
||||
final routes = ['/home', '/children', '/menu', '/chat', '/profile'];
|
||||
context.go(routes[i]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue