1+ import "package:collection/collection.dart" ;
12import "package:flutter/material.dart" ;
2- import "package:flutter/services.dart" ;
33import "package:get/get.dart" ;
44import "package:miutem/core/models/evaluacion/evaluacion.dart" ;
55import "package:miutem/core/services/controllers/notas_controller.dart" ;
66import "package:miutem/core/utils/utils.dart" ;
7+ import "package:miutem/screens/notas/widgets/notas/fila_nota.dart" ;
78import "package:miutem/styles/styles.dart" ;
89
910class Notas extends StatelessWidget {
10-
1111 final bool canAddNotas;
1212 final NotasController notasController;
1313
@@ -20,89 +20,70 @@ class Notas extends StatelessWidget {
2020 @override
2121 Widget build (BuildContext context) => Column (
2222 crossAxisAlignment: CrossAxisAlignment .start,
23- mainAxisSize: MainAxisSize .max,
2423 children: [
2524 Text ("Notas" , style: Theme .of (context).textTheme.bodyMedium),
26- const SizedBox (height: 12 ),
27- SizedBox (
28- width: double .infinity,
29- child: Card (
30- color: Theme .of (context).scaffoldBackgroundColor,
31- margin: EdgeInsets .zero,
32- shape: RoundedRectangleBorder (borderRadius: BorderRadius .circular (10 ), side: BorderSide (color: AppTheme .lightGrey)),
33- child: Padding (
34- padding: const EdgeInsets .all (20 ),
35- child: Column (
36- mainAxisSize: MainAxisSize .min,
37- mainAxisAlignment: MainAxisAlignment .center,
38- crossAxisAlignment: CrossAxisAlignment .center,
39- children: [
40- Obx (() => GridView (
41- shrinkWrap: true ,
42- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount (
43- crossAxisCount: 3 ,
44- childAspectRatio: 3 ,
45- mainAxisSpacing: 12 ,
46- crossAxisSpacing: 12 ,
47- ),
25+ Space .small,
26+ Card (
27+ margin: EdgeInsets .zero,
28+ color: Theme .of (context).scaffoldBackgroundColor,
29+ shape: RoundedRectangleBorder (
30+ borderRadius: BorderRadius .circular (10 ),
31+ side: BorderSide (color: AppTheme .lightGrey),
32+ ),
33+ child: Padding (
34+ padding: const EdgeInsets .all (20 ),
35+ child: Column (
36+ mainAxisSize: MainAxisSize .min,
37+ children: [
38+ // Usamos Obx solo para la parte que cambia
39+ Obx (
40+ () => Column (
4841 children: [
49- const Center (child : Text ( "Notas" )),
50- const Center (child : Text ( "Porcentaje" )),
51- const SizedBox . shrink () ,
52- for ( int i = 0 ; i < notasController.percentageTextFieldControllers.length; i ++ ) ... [
53- _buildTextField (context : context, enabled : true , controller : notasController.gradeTextFieldControllers[i], textInputAction : TextInputAction .next, hintText : formatoNota (notasController.suggestedGrade), formatters : [notaInputFormatter], onChanged : (value) {
54- final grade = notasController.partialGrades[i];
55- grade.nota = double . tryParse (value. replaceAll ( "," , "." ));
56- notasController. updateGradeAt (i, grade);
57- }) ,
58- _buildTextField (context : context,enabled : true , controller : notasController.percentageTextFieldControllers[i], textInputAction : TextInputAction .done, hintText : notasController.suggestedPercentage ? . toStringAsFixed ( 0 ) ?? "--" , onChanged : (value) {
59- final grade = notasController.partialGrades[i];
60- grade.porcentaje = double . tryParse (value. replaceAll ( "," , "." )) ?? 0 ;
61- notasController. updateGradeAt (i, grade);
62- }),
63- IconButton (onPressed : () => notasController. removeGradeAt (i), icon : const Icon ( AppIcons .delete, size : 20 )),
64- ],
65- const SizedBox . shrink () ,
66- SizedBox . expand (child : Center (child : FilledButton . tonalIcon (icon : const Icon ( AppIcons .add), label : const Text ( "Nota" ), onPressed : () {
67- if ( ! canAddNotas) {
68- showErrorSnackbar (context, "Las notas están cargando... Intenta más tarde." );
69- return ;
70- }
42+ // Encabezados manuales para evitar el GridView rígido
43+ const Row (
44+ mainAxisAlignment : MainAxisAlignment .center ,
45+ children : [
46+ Expanded (child : Center (child : Text ( "Notas" ))),
47+ HorizontalSpace .small,
48+ Expanded (child : Center (child : Text ( "Porcentaje" ))),
49+ HorizontalSpace .extraExtraLarge,
50+ ] ,
51+ ),
52+ HorizontalSpace .small,
53+
54+ // Filas de Notas
55+ ...notasController.percentageTextFieldControllers
56+ . mapIndexed < Widget >(
57+ (i, controller) => FilaNota (
58+ notasController : notasController ,
59+ index : i,
60+ ),
61+ )
62+ . toList ()
63+ . intersperse ( Space .small),
7164
72- notasController.addGrade (IEvaluacion ());
73- }))),
74- const SizedBox .shrink (),
65+ Space .extraSmall,
66+ FilledButton .tonalIcon (
67+ onPressed: () {
68+ if (! canAddNotas) {
69+ showErrorSnackbar (
70+ context,
71+ "Las notas están cargando... Intenta más tarde." ,
72+ );
73+ return ;
74+ }
75+ notasController.addGrade (IEvaluacion ());
76+ },
77+ icon: const Icon (AppIcons .add),
78+ label: const Text ("Agregar Nota" ),
79+ ),
7580 ],
76- )) ,
77- ] ,
78- ) ,
81+ ),
82+ ) ,
83+ ] ,
7984 ),
8085 ),
8186 ),
8287 ],
8388 );
84-
85- Widget _buildTextField ({
86- required BuildContext context,
87- required bool enabled,
88- required TextEditingController controller,
89- required TextInputAction textInputAction,
90- required String ? hintText,
91- Function (String )? onChanged,
92- List <TextInputFormatter >? formatters,
93- }) => TextField (
94- enabled: enabled,
95- controller: controller,
96- style: Theme .of (context).textTheme.bodyMedium,
97- decoration: InputDecoration (
98- hintText: hintText ?? "--" ,
99- filled: true ,
100- ),
101- textAlign: TextAlign .center,
102- textAlignVertical: TextAlignVertical .center,
103- onChanged: onChanged,
104- textInputAction: textInputAction,
105- inputFormatters: formatters,
106-
107- );
108- }
89+ }
0 commit comments