diff --git a/src/components/asignaturas/detalle/MateriaDetailPage.tsx b/src/components/asignaturas/detalle/MateriaDetailPage.tsx
index a7c4883..1922bb5 100644
--- a/src/components/asignaturas/detalle/MateriaDetailPage.tsx
+++ b/src/components/asignaturas/detalle/MateriaDetailPage.tsx
@@ -73,15 +73,13 @@ function EditableHeaderField({
}
return (
-
- {value}
-
+ onSave(e.target.value)}
+ onBlur={(e) => onSave(e.target.value)}
+ className={`border-none bg-transparent outline-none focus:ring-2 focus:ring-blue-400 ${className}`}
+ />
)
}
@@ -97,6 +95,9 @@ export default function MateriaDetailPage() {
const { asignaturaId } = useParams({
from: '/planes/$planId/asignaturas/$asignaturaId',
})
+ const { planId } = useParams({
+ from: '/planes/$planId/asignaturas/$asignaturaId',
+ })
const { data: asignaturasApi, isLoading: loadingAsig } =
useSubject(asignaturaId)
// 1. Asegúrate de tener estos estados en tu componente principal
@@ -116,10 +117,10 @@ export default function MateriaDetailPage() {
useEffect(() => {
if (asignaturasApi) {
setHeaderData({
- codigo: asignaturasApi?.codigo ?? '',
- nombre: asignaturasApi?.nombre ?? '',
- creditos: asignaturasApi?.creditos ?? '',
- ciclo: asignaturasApi?.numero_ciclo ?? 0,
+ codigo: asignaturasApi.codigo ?? '',
+ nombre: asignaturasApi.nombre,
+ creditos: asignaturasApi.creditos,
+ ciclo: asignaturasApi.numero_ciclo ?? 0,
})
}
}, [asignaturasApi])
@@ -194,6 +195,7 @@ export default function MateriaDetailPage() {
Volver al plan
diff --git a/src/routes/planes/$planId/_detalle/mapa.tsx b/src/routes/planes/$planId/_detalle/mapa.tsx
index 985604e..218b4ec 100644
--- a/src/routes/planes/$planId/_detalle/mapa.tsx
+++ b/src/routes/planes/$planId/_detalle/mapa.tsx
@@ -177,7 +177,29 @@ function MapaCurricularPage() {
const manejarAgregarLinea = (nombre: string) => {
const nombreNormalizado = nombre.trim()
- // Validar si es Área Común (insensible a mayúsculas/minúsculas)
+ // 1. Validar que no esté vacío
+ if (!nombreNormalizado) return
+
+ // 2. Validar duplicados (Insensible a mayúsculas/minúsculas y acentos)
+ const nombreParaComparar = nombreNormalizado
+ .toLowerCase()
+ .normalize('NFD')
+ .replace(/[\u0300-\u036f]/g, '')
+
+ const yaExiste = lineas.some((l) => {
+ const lineaNombreBase = l.nombre
+ .toLowerCase()
+ .normalize('NFD')
+ .replace(/[\u0300-\u036f]/g, '')
+ return lineaNombreBase === nombreParaComparar
+ })
+
+ if (yaExiste) {
+ alert(`La línea "${nombreNormalizado}" ya existe.`)
+ return
+ }
+
+ // 3. Validar Área Común (usando tu lógica previa)
const esAreaComun =
nombreNormalizado.toLowerCase() === 'área común' ||
nombreNormalizado.toLowerCase() === 'area comun'
@@ -187,10 +209,12 @@ function MapaCurricularPage() {
return
}
+ // 4. Agregar la línea si todo está bien
const nueva = {
id: crypto.randomUUID(),
nombre: nombreNormalizado,
orden: lineas.length + 1,
+ color: '#1976d2',
}
setLineas([...lineas, nueva])
@@ -198,6 +222,7 @@ function MapaCurricularPage() {
if (esAreaComun) {
setHasAreaComun(true)
}
+
setNombreNuevaLinea('') // Limpiar input
}
@@ -599,19 +624,46 @@ function MapaCurricularPage() {
-
+
+ setEditingData({
+ ...editingData,
+ creditos: Number(e.target.value),
+ })
+ }
+ />
-
+
+ setEditingData({
+ ...editingData,
+ hd: Number(e.target.value),
+ })
+ }
+ />
-
+
+ setEditingData({
+ ...editingData,
+ hi: Number(e.target.value),
+ })
+ }
+ />
@@ -621,11 +673,22 @@ function MapaCurricularPage() {
-