kz_educa/lib/screens/lessons_screen.dart

227 lines
9.2 KiB
Dart
Executable File

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:kzeduca_app/services/i18n_service.dart';
import 'package:kzeduca_app/services/firebase_service.dart';
import 'package:kzeduca_app/models/app_models.dart';
import 'package:kzeduca_app/widgets/lesson_detail_sheet.dart';
class LessonsScreen extends StatefulWidget {
const LessonsScreen({super.key});
@override
State<LessonsScreen> createState() => _LessonsScreenState();
}
class _LessonsScreenState extends State<LessonsScreen> {
final Set<String> _completedLessons = {};
@override
void initState() {
super.initState();
_listenForCompletedLessons();
}
void _listenForCompletedLessons() {
final firebaseService = Provider.of<FirebaseService>(context, listen: false);
final userId = FirebaseAuth.instance.currentUser?.uid;
if (userId != null) {
firebaseService.streamUserCompletedLessons(userId).listen((snapshot) {
if (mounted) {
setState(() {
_completedLessons.clear();
for (var doc in snapshot.docs) {
_completedLessons.add(doc.id);
}
});
}
});
}
}
void _markLessonAsComplete(QuickLesson lesson) async {
final firebaseService = Provider.of<FirebaseService>(context, listen: false);
final userId = firebaseService.auth.currentUser?.uid;
if (userId != null) {
await firebaseService.markLessonAsComplete(userId, lesson.id);
}
}
@override
Widget build(BuildContext context) {
final firebaseService = Provider.of<FirebaseService>(context);
final i18n = Provider.of<I18nService>(context);
return Scaffold(
backgroundColor: const Color(0xFF1A1A2E),
appBar: AppBar(
title: Text(
i18n.t('quick_lessons'),
style: const TextStyle(
color: Color.fromARGB(255, 255, 255, 255),
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
),
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF1A1A2E),
Color(0xFF282A52),
Color(0xFF553C9A)
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: StreamBuilder<QuerySnapshot>(
stream: firebaseService.streamPublicLessons(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(color: Color(0xFFE94560)));
}
if (snapshot.hasError) {
return Center(child: Text('Ocorreu um erro: ${snapshot.error}', textAlign: TextAlign.center, style: const TextStyle(color: Colors.white70)));
}
if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
return Center(child: Text(i18n.t('no_lessons_available'), textAlign: TextAlign.center, style: const TextStyle(color: Colors.white70)));
}
final lessons = snapshot.data!.docs.map((doc) {
return QuickLesson.fromFirestore(doc);
}).toList();
return ListView.builder(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(20),
itemCount: lessons.length,
itemBuilder: (context, index) {
final lesson = lessons[index];
final isCompleted = _completedLessons.contains(lesson.id);
return Padding(
padding: const EdgeInsets.only(bottom: 20),
// ✅ NOVO: Alterações de Design para o cartão de lição.
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: BoxDecoration(
// ✅ NOVO: Gradiente de fundo escuro para combinar com o tema do app.
gradient: LinearGradient(
colors: [
const Color(0xFF282A52).withOpacity(0.9),
const Color(0xFF1A1A2E).withOpacity(0.9),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.white10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => LessonDetailSheet(
lesson: lesson,
isCompleted: isCompleted,
onMarkComplete: _markLessonAsComplete,
),
);
},
borderRadius: BorderRadius.circular(20),
child: Padding(
padding: const EdgeInsets.all(20),
child: Row(
children: [
// ✅ NOVO: Gradiente no ícone para um efeito premium.
ShaderMask(
shaderCallback: (Rect bounds) {
return const LinearGradient(
colors: [Color(0xFFE94560), Color(0xFFF07E3F)],
tileMode: TileMode.mirror,
).createShader(bounds);
},
child: Icon(
isCompleted ? Icons.check_circle_rounded : Icons.menu_book_rounded,
color: Colors.white, // A cor é mascarada pelo ShaderMask
size: 40,
),
),
const SizedBox(width: 15),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
lesson.titulo,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
const SizedBox(height: 5),
// ✅ NOVO: Texto da duração com estilo mais atraente.
Text(
'${i18n.t('lesson_duration')}: ${lesson.duracao}',
style: TextStyle(
color: Colors.white.withOpacity(0.7),
fontSize: 14,
fontStyle: FontStyle.italic,
),
),
],
),
),
// ✅ NOVO: Ícone de seta com gradiente para combinar com o design.
ShaderMask(
shaderCallback: (Rect bounds) {
return const LinearGradient(
colors: [Color(0xFFE94560), Color(0xFFF07E3F)],
).createShader(bounds);
},
child: const Icon(
Icons.arrow_forward_ios,
color: Colors.white,
),
),
],
),
),
),
),
),
);
},
);
},
),
),
);
}
}