Closed FrederG closed 2 weeks ago
El metodo que utilizamos anteriormente para la visualización de la malla se hizo complejo al momento de adaptar la aplicación a moviles, por lo que se tuvo que rediseñar este apartado.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
class MallaCurricularScreen extends StatefulWidget {
const MallaCurricularScreen({super.key});
@override
_MallaCurricularScreenState createState() => _MallaCurricularScreenState();
}
class _MallaCurricularScreenState extends State<MallaCurricularScreen> {
// Datos simulados para los cursos de cada semestre con el estado "aprobado"
List<Map<String, dynamic>> mallaCurricular = [
{
'semestre': 'Nivel I',
'cursos': [
{'nombre': 'Taller de comprension lectora', 'aprobado': false},
{'nombre': 'Cálculo Diferencial', 'aprobado': false},
{'nombre': 'Matemáticas Básicas', 'aprobado': false},
{'nombre': 'Química General', 'aprobado': false},
{'nombre': 'Desarrollo Universitario', 'aprobado': false},
{'nombre': 'Seminario Ing sistemas', 'aprobado': false},
{'nombre': 'Fundamentos de programacion', 'aprobado': false}
]
},
{
'semestre': 'Nivel II',
'cursos': [
{'nombre': 'Física Mecánica', 'aprobado': false},
{'nombre': 'Cálculo Integral', 'aprobado': false},
{'nombre': 'Lengua Extranjera I', 'aprobado': false},
{'nombre': 'Algebra lineal', 'aprobado': false},
{'nombre': 'Programacion', 'aprobado': false}
]
},
{
'semestre': 'Nivel III',
'cursos': [
{'nombre': 'Física electrica', 'aprobado': false},
{'nombre': 'Cálculo Vectorial', 'aprobado': false},
{'nombre': 'Lengua Extranjera II', 'aprobado': false},
{'nombre': 'Taller de escritura academica', 'aprobado': false},
{'nombre': 'Programacion orientada a objetos', 'aprobado': false}
]
},
{
'semestre': 'Nivel IV',
'cursos': [
{'nombre': 'Física calor y ondas', 'aprobado': false},
{'nombre': 'Ecuaciones diferenciales', 'aprobado': false},
{'nombre': 'Lengua Extranjera III', 'aprobado': false},
{'nombre': 'Estructura de datos', 'aprobado': false},
{'nombre': 'Matematica Discreta', 'aprobado': false}
]
},
{
'semestre': 'Nivel V',
'cursos': [
{'nombre': 'Constitución politica', 'aprobado': false},
{'nombre': 'Estadistica y probabilidad', 'aprobado': false},
{'nombre': 'Lengua Extranjera IV', 'aprobado': false},
{'nombre': 'Base de datos', 'aprobado': false},
{'nombre': 'Desarrollo de software', 'aprobado': false},
{'nombre': 'Algoritmo y complejidad', 'aprobado': false}
]
},
{
'semestre': 'Nivel VI',
'cursos': [
{'nombre': 'Creatividad y emprendimiento', 'aprobado': false},
{'nombre': 'Estadistica inferencial', 'aprobado': false},
{'nombre': 'Lengua Extranjera V', 'aprobado': false},
{'nombre': 'Procesamiento numerico', 'aprobado': false},
{'nombre': 'Arquitectura de software', 'aprobado': false},
{'nombre': 'Comunicaciones y redes', 'aprobado': false}
]
},
{
'semestre': 'Nivel VII',
'cursos': [
{'nombre': 'Ciudadania global', 'aprobado': false},
{'nombre': 'Formulación y evaluación de proyectos', 'aprobado': false},
{'nombre': 'Ingenieria de software', 'aprobado': false},
{'nombre': 'Arquitectura del computador', 'aprobado': false},
{'nombre': 'Sistemas y modelos', 'aprobado': false},
{'nombre': 'Electiva complementaria I', 'aprobado': false}
]
},
{
'semestre': 'Nivel VIII',
'cursos': [
{'nombre': 'Electiva de humanidades I', 'aprobado': false},
{'nombre': 'Inteligencia artificial', 'aprobado': false},
{'nombre': 'Infraestructura para TI', 'aprobado': false},
{'nombre': 'Sistemas operativos', 'aprobado': false},
{'nombre': 'Proyecto de ingenieria I', 'aprobado': false},
{'nombre': 'Electiva complementaria II', 'aprobado': false}
]
},
{
'semestre': 'Nivel IX',
'cursos': [
{'nombre': 'Electiva de humanidades II', 'aprobado': false},
{'nombre': 'Electiva empresarial', 'aprobado': false},
{'nombre': 'Computación en paralelo', 'aprobado': false},
{'nombre': 'TOP ESP de ciencias computacionales', 'aprobado': false},
{'nombre': 'Proyecto de ingenieria II', 'aprobado': false},
{'nombre': 'Electiva complementaria III', 'aprobado': false}
]
},
{
'semestre': 'Nivel X',
'cursos': [
{'nombre': 'Etica', 'aprobado': false},
{'nombre': 'Electiva de humanidades IV', 'aprobado': false},
{'nombre': 'Práctica profesional', 'aprobado': false},
]
}
];
@override
void initState() {
super.initState();
_cargarEstado();
}
// Cargar el estado de los cursos aprobados desde SharedPreferences
Future<void> _cargarEstado() async {
final prefs = await SharedPreferences.getInstance();
final String? estadoJson = prefs.getString('estadoMallaCurricular');
if (estadoJson != null) {
setState(() {
mallaCurricular = List<Map<String, dynamic>>.from(
jsonDecode(estadoJson),
);
});
}
}
// Guardar el estado de los cursos aprobados en SharedPreferences
Future<void> _guardarEstado() async {
final prefs = await SharedPreferences.getInstance();
final String estadoJson = jsonEncode(mallaCurricular);
prefs.setString('estadoMallaCurricular', estadoJson);
}
// Función para alternar el estado de aprobado de un curso
void toggleAprobado(int semestreIndex, int cursoIndex) {
setState(() {
mallaCurricular[semestreIndex]['cursos'][cursoIndex]['aprobado'] =
!mallaCurricular[semestreIndex]['cursos'][cursoIndex]['aprobado'];
});
_guardarEstado();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Malla Curricular'),
),
body: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: mallaCurricular.length,
itemBuilder: (context, semestreIndex) {
final nivel = mallaCurricular[semestreIndex];
return Card(
margin: const EdgeInsets.symmetric(vertical: 8.0),
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
nivel['semestre'],
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Column(
children: List.generate(nivel['cursos'].length, (cursoIndex) {
final curso = nivel['cursos'][cursoIndex];
return ListTile(
title: Text(
curso['nombre'],
style: TextStyle(
decoration: curso['aprobado']
? TextDecoration.lineThrough
: TextDecoration.none,
),
),
trailing: Icon(
curso['aprobado']
? Icons.check_box
: Icons.check_box_outline_blank,
color: curso['aprobado'] ? Colors.green : null,
),
onTap: () => toggleAprobado(semestreIndex, cursoIndex),
);
}),
),
],
),
),
);
},
),
);
}
}