import { createFileRoute, Outlet, Link, useLocation, useParams, useRouterState, } from '@tanstack/react-router' import { ArrowLeft, GraduationCap } from 'lucide-react' import { useEffect, useState } from 'react' import { Badge } from '@/components/ui/badge' import { lateralConfetti } from '@/components/ui/lateral-confetti' import { useSubject, useUpdateAsignatura } from '@/data' export const Route = createFileRoute( '/planes/$planId/asignaturas/$asignaturaId', )({ component: AsignaturaLayout, }) function EditableHeaderField({ value, onSave, className, }: { value: string | number onSave: (val: string) => void className?: string }) { const textValue = String(value) // Manejador para cuando el usuario termina de editar (pierde el foco) const handleBlur = (e: React.FocusEvent) => { const newValue = e.currentTarget.innerText if (newValue !== textValue) { onSave(newValue) } } const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault() e.currentTarget.blur() // Forzamos el guardado al presionar Enter } } return ( // eslint-disable-next-line jsx-a11y/no-static-element-interactions {textValue} ) } interface DatosPlan { nombre?: string } function AsignaturaLayout() { const location = useLocation() const { asignaturaId } = useParams({ from: '/planes/$planId/asignaturas/$asignaturaId', }) const { planId } = useParams({ from: '/planes/$planId/asignaturas/$asignaturaId', }) const { data: asignaturaApi, isLoading: loadingAsig } = useSubject(asignaturaId) // 1. Asegúrate de tener estos estados en tu componente principal const updateAsignatura = useUpdateAsignatura() // Dentro de AsignaturaDetailPage const [headerData, setHeaderData] = useState({ codigo: '', nombre: '', creditos: 0, ciclo: 0, }) // Sincronizar cuando llegue la API useEffect(() => { if (asignaturaApi) { setHeaderData({ codigo: asignaturaApi.codigo ?? '', nombre: asignaturaApi.nombre, creditos: asignaturaApi.creditos, ciclo: asignaturaApi.numero_ciclo ?? 0, }) } }, [asignaturaApi]) const handleUpdateHeader = (key: string, value: string | number) => { const newData = { ...headerData, [key]: value } setHeaderData(newData) const patch: Record = key === 'ciclo' ? { numero_ciclo: value } : { [key]: value, } updateAsignatura.mutate({ asignaturaId, patch, }) } const pathname = useRouterState({ select: (state) => state.location.pathname, }) // Confetti al llegar desde creación IA useEffect(() => { if ((location.state as any)?.showConfetti) { lateralConfetti() window.history.replaceState({}, document.title) } }, [location.state]) if (loadingAsig) { return (
Cargando asignatura...
) } // Si no hay datos y no está cargando, algo falló if (!asignaturaApi) return null return (
Volver al plan
{/* CÓDIGO EDITABLE */} handleUpdateHeader('codigo', val)} /> {/* NOMBRE EDITABLE */}

handleUpdateHeader('nombre', val)} />

{ // console.log(headerData), console.log(asignaturaApi.planes_estudio?.nombre) }
Pertenece al plan:{' '} {(asignaturaApi.planes_estudio as DatosPlan).nombre || ''}
{/* CRÉDITOS EDITABLES */} handleUpdateHeader('creditos', parseInt(val) || 0) } /> créditos {/* SEMESTRE EDITABLE */} handleUpdateHeader('ciclo', parseInt(val) || 0) } /> ° ciclo {asignaturaApi.tipo}
{/* TABS */}
) }