Eliminar creche_app/lib/features/attendance/attendance_screen.dart

This commit is contained in:
Alberto 2026-03-11 19:23:00 +00:00
parent 27f81e1b13
commit 70356f8863
1 changed files with 0 additions and 243 deletions

View File

@ -1,243 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import '/core/supabase_client.dart';
import '/models/child.dart';
class AttendanceScreen extends ConsumerStatefulWidget {
const AttendanceScreen({super.key});
@override
ConsumerState<AttendanceScreen> createState() => _AttendanceScreenState();
}
class _AttendanceScreenState extends ConsumerState<AttendanceScreen> {
DateTime _selectedDate = DateTime.now();
final Map<String, bool> _presence = {};
final Map<String, String?> _timeIn = {};
bool _isSaving = false;
Future<void> _pickDate() async {
final picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(2024),
lastDate: DateTime.now(),
builder: (c, child) => Theme(
data: ThemeData.dark()
.copyWith(colorScheme: const ColorScheme.dark(primary: Color(0xFF4FC3F7))),
child: child!,
),
);
if (picked != null) setState(() => _selectedDate = picked);
}
Future<void> _markAllPresent(List<Child> children) async {
setState(() {
for (final c in children) {
_presence[c.id] = true;
}
});
}
Future<void> _saveAttendance(List<Child> children) async {
setState(() => _isSaving = true);
final supabase = ref.read(supabaseProvider);
final today = _selectedDate.toIso8601String().split('T')[0];
try {
for (final child in children) {
final isPresent = _presence[child.id] ?? false;
await supabase.from('attendance').upsert({
'child_id': child.id,
'date': today,
'status': isPresent ? 'present' : 'absent',
'time_in': _timeIn[child.id],
});
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Presença guardada com sucesso!'),
backgroundColor: Color(0xFFA5D6A7),
),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Erro: $e'), backgroundColor: Colors.red));
}
} finally {
if (mounted) setState(() => _isSaving = false);
}
}
@override
Widget build(BuildContext context) {
final supabase = ref.read(supabaseProvider);
return Scaffold(
backgroundColor: const Color(0xFF1A1A2E),
appBar: AppBar(
backgroundColor: const Color(0xFF16213E),
title: const Text('Presença',
style: TextStyle(color: Color(0xFF4FC3F7))),
),
body: Column(
children: [
// Header: data + filtro
Container(
padding: const EdgeInsets.all(16),
color: const Color(0xFF16213E),
child: Row(
children: [
const Icon(Icons.calendar_today, color: Color(0xFF4FC3F7)),
const SizedBox(width: 10),
Text(
DateFormat('d MMMM yyyy', 'pt_PT').format(_selectedDate),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15),
),
const Spacer(),
TextButton(
onPressed: _pickDate,
child: const Text('Alterar',
style: TextStyle(color: Color(0xFF4FC3F7))),
),
],
),
),
// Lista de crianças
Expanded(
child: StreamBuilder<List<Map<String, dynamic>>>(
stream: supabase.from('children').stream(primaryKey: ['id']),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
color: Color(0xFF4FC3F7)));
}
final children = snapshot.data!.map(Child.fromMap).toList();
return Column(
children: [
// Botão marcar todos
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 8),
child: ElevatedButton.icon(
icon: const Icon(Icons.check_circle_outline,
color: Colors.white),
label: const Text('Marcar Todos Presentes',
style: TextStyle(color: Colors.white)),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFA5D6A7),
minimumSize: const Size(double.infinity, 46),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
),
onPressed: () => _markAllPresent(children),
),
),
Expanded(
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: children.length,
itemBuilder: (context, i) {
final child = children[i];
final isPresent = _presence[child.id] ?? false;
return Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(
horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFF16213E),
borderRadius: BorderRadius.circular(14),
border: Border.all(
color: isPresent
? const Color(0xFFA5D6A7).withOpacity(0.5)
: const Color(0xFF333366),
),
),
child: Row(
children: [
CircleAvatar(
radius: 20,
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: 20)
: null,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(child.fullName,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold)),
Text(child.classId,
style: const TextStyle(
color: Color(0xFF888888),
fontSize: 12)),
],
),
),
Switch(
value: isPresent,
activeColor: const Color(0xFFA5D6A7),
onChanged: (v) => setState(
() => _presence[child.id] = v),
),
],
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16),
child: ElevatedButton.icon(
icon: _isSaving
? const SizedBox(
height: 18,
width: 18,
child: CircularProgressIndicator(
color: Colors.white, strokeWidth: 2))
: const Icon(Icons.save, color: Colors.white),
label: Text(
_isSaving ? 'A guardar...' : 'Guardar Presenças',
style: const TextStyle(color: Colors.white),
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF4FC3F7),
minimumSize: const Size(double.infinity, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
),
onPressed: _isSaving
? null
: () => _saveAttendance(children),
),
),
],
);
},
),
),
],
),
);
}
}