This commit is contained in:
2026-01-30 12:43:54 -06:00
20 changed files with 693 additions and 693 deletions

View File

@@ -12,9 +12,13 @@ import { BibliographyItem } from './BibliographyItem'
import { ContenidoTematico } from './ContenidoTematico'
import { DocumentoSEPTab } from './DocumentoSEPTab'
import { HistorialTab } from './HistorialTab'
import { IAMateriaTab } from './IAMateriaTab'
import { IAAsignaturaTab } from './IAAsignaturaTab'
import type { CampoEstructura, IAMessage, IASugerencia } from '@/types/materia'
import type {
CampoEstructura,
IAMessage,
IASugerencia,
} from '@/types/asignatura'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
@@ -30,10 +34,10 @@ import {
} from '@/components/ui/tooltip'
import { useSubject } from '@/data/hooks/useSubjects'
import {
mockMateria,
mockAsignatura,
mockEstructura,
mockDocumentoSep,
} from '@/data/mockMateriaData'
} from '@/data/mockAsignaturaData'
export interface BibliografiaEntry {
id: string
@@ -101,10 +105,10 @@ function EditableHeaderField({
export const Route = createFileRoute(
'/planes/$planId/asignaturas/$asignaturaId',
)({
component: MateriaDetailPage,
component: AsignaturaDetailPage,
})
export default function MateriaDetailPage() {
export default function AsignaturaDetailPage() {
const routerState = useRouterState()
const state = routerState.location.state as any
const { asignaturaId } = useParams({
@@ -121,7 +125,7 @@ export default function MateriaDetailPage() {
const [campos, setCampos] = useState<Array<CampoEstructura>>([])
const [activeTab, setActiveTab] = useState('datos')
// Dentro de MateriaDetailPage
// Dentro de AsignaturaDetailPage
const [headerData, setHeaderData] = useState({
codigo: '',
nombre: '',
@@ -315,7 +319,7 @@ export default function MateriaDetailPage() {
<TabsTrigger value="datos">Datos generales</TabsTrigger>
<TabsTrigger value="contenido">Contenido temático</TabsTrigger>
<TabsTrigger value="bibliografia">Bibliografía</TabsTrigger>
<TabsTrigger value="ia">IA de la materia</TabsTrigger>
<TabsTrigger value="ia">IA de la asignatura</TabsTrigger>
<TabsTrigger value="sep">Documento SEP</TabsTrigger>
<TabsTrigger value="historial">Historial</TabsTrigger>
</TabsList>
@@ -348,7 +352,7 @@ export default function MateriaDetailPage() {
</TabsContent>
<TabsContent value="ia">
<IAMateriaTab
<IAAsignaturaTab
campos={campos}
datosGenerales={datosGenerales}
messages={messages}
@@ -366,7 +370,7 @@ export default function MateriaDetailPage() {
<TabsContent value="sep">
<DocumentoSEPTab
documento={mockDocumentoSep}
materia={mockMateria}
asignatura={mockAsignatura}
estructura={mockEstructura}
datosGenerales={datosGenerales}
onRegenerate={handleRegenerateDocument}

View File

@@ -41,7 +41,7 @@ import { Textarea } from '@/components/ui/textarea'
import { useSubjectBibliografia } from '@/data/hooks/useSubjects'
import { cn } from '@/lib/utils'
// import { toast } from 'sonner';
// import { mockLibraryResources } from '@/data/mockMateriaData';
// import { mockLibraryResources } from '@/data/mockAsignaturaData';
export const mockLibraryResources = [
{
@@ -99,7 +99,7 @@ export function BibliographyItem({
}: BibliografiaTabProps) {
console.log(id)
const { data: bibliografia2, isLoading: loadinmateria } =
const { data: bibliografia2, isLoading: loadinasignatura } =
useSubjectBibliografia(id)
const [entries, setEntries] = useState<Array<BibliografiaEntry>>(bibliografia)
const [isAddDialogOpen, setIsAddDialogOpen] = useState(false)

View File

@@ -23,10 +23,10 @@ import {
AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import type {
DocumentoMateria,
Materia,
MateriaStructure,
} from '@/types/materia'
DocumentoAsignatura,
Asignatura,
AsignaturaStructure,
} from '@/types/asignatura'
import { cn } from '@/lib/utils'
import { useSubjectBibliografia } from '@/data/hooks/useSubjects'
//import { toast } from 'sonner';
@@ -34,9 +34,9 @@ import { useSubjectBibliografia } from '@/data/hooks/useSubjects'
//import { es } from 'date-fns/locale';
interface DocumentoSEPTabProps {
documento: DocumentoMateria | null
materia: Materia
estructura: MateriaStructure
documento: DocumentoAsignatura | null
asignatura: Asignatura
estructura: AsignaturaStructure
datosGenerales: Record<string, any>
onRegenerate: () => void
isRegenerating: boolean
@@ -44,7 +44,7 @@ interface DocumentoSEPTabProps {
export function DocumentoSEPTab({
documento,
materia,
asignatura,
estructura,
datosGenerales,
onRegenerate,
@@ -112,7 +112,7 @@ export function DocumentoSEPTab({
<AlertDialogTitle>¿Regenerar documento SEP?</AlertDialogTitle>
<AlertDialogDescription>
Se creará una nueva versión del documento con los datos
actuales de la materia. La versión anterior quedará en el
actuales de la asignatura. La versión anterior quedará en el
historial.
</AlertDialogDescription>
</AlertDialogHeader>
@@ -139,7 +139,7 @@ export function DocumentoSEPTab({
<div className="flex items-center gap-2">
<FileText className="text-primary h-5 w-5" />
<span className="text-foreground font-medium">
Programa de Estudios - {materia.clave}
Programa de Estudios - {asignatura.clave}
</span>
</div>
<Badge variant="outline">Versión {documento.version}</Badge>
@@ -155,28 +155,29 @@ export function DocumentoSEPTab({
Secretaría de Educación Pública
</p>
<h1 className="font-display text-primary mb-1 text-2xl font-bold">
{materia.nombre}
{asignatura.nombre}
</h1>
<p className="text-muted-foreground text-sm">
Clave: {materia.clave} | Créditos:{' '}
{materia.creditos || 'N/A'}
Clave: {asignatura.clave} | Créditos:{' '}
{asignatura.creditos || 'N/A'}
</p>
</div>
{/* Datos de la institución */}
<div className="space-y-1 text-sm">
<p>
<strong>Carrera:</strong> {materia.carrera}
<strong>Carrera:</strong> {asignatura.carrera}
</p>
<p>
<strong>Facultad:</strong> {materia.facultad}
<strong>Facultad:</strong> {asignatura.facultad}
</p>
<p>
<strong>Plan de estudios:</strong> {materia.planNombre}
<strong>Plan de estudios:</strong>{' '}
{asignatura.planNombre}
</p>
{materia.ciclo && (
{asignatura.ciclo && (
<p>
<strong>Ciclo:</strong> {materia.ciclo}
<strong>Ciclo:</strong> {asignatura.ciclo}
</p>
)}
</div>

View File

@@ -13,7 +13,11 @@ import {
} from 'lucide-react'
import { useState, useEffect, useRef, useMemo } from 'react'
import type { IAMessage, IASugerencia, CampoEstructura } from '@/types/materia'
import type {
IAMessage,
IASugerencia,
CampoEstructura,
} from '@/types/asignatura'
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
import { Badge } from '@/components/ui/badge'
@@ -22,7 +26,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import { Textarea } from '@/components/ui/textarea'
import { cn } from '@/lib/utils'
// Tipos importados de tu archivo de materia
// Tipos importados de tu archivo de asignatura
const PRESETS = [
{
@@ -35,7 +39,7 @@ const PRESETS = [
id: 'contenido-tematico',
label: 'Sugerir contenido',
icon: BookOpen,
prompt: 'Genera un desglose de temas para esta materia...',
prompt: 'Genera un desglose de temas para esta asignatura...',
},
{
id: 'actividades',
@@ -57,7 +61,7 @@ interface SelectedField {
value: string
}
interface IAMateriaTabProps {
interface IAAsignaturaTabProps {
campos: Array<CampoEstructura>
datosGenerales: Record<string, any>
messages: Array<IAMessage>
@@ -66,14 +70,14 @@ interface IAMateriaTabProps {
onRejectSuggestion: (messageId: string) => void
}
export function IAMateriaTab({
export function IAAsignaturaTab({
campos,
datosGenerales,
messages,
onSendMessage,
onAcceptSuggestion,
onRejectSuggestion,
}: IAMateriaTabProps) {
}: IAAsignaturaTabProps) {
const routerState = useRouterState()
// ESTADOS PRINCIPALES (Igual que en Planes)
@@ -83,7 +87,7 @@ export function IAMateriaTab({
const [isLoading, setIsLoading] = useState(false)
const scrollRef = useRef<HTMLDivElement>(null)
// 1. Transformar datos de la materia para el menú
// 1. Transformar datos de la asignatura para el menú
const availableFields = useMemo(() => {
// Extraemos las claves directamente del objeto datosGenerales
// ["nombre", "descripcion", "perfil_de_egreso", "fines_de_aprendizaje_o_formacion"]
@@ -105,7 +109,7 @@ export function IAMateriaTab({
})
}, [campos, datosGenerales])
// 2. Manejar el estado inicial si viene de "Datos de Materia" (Prefill)
// 2. Manejar el estado inicial si viene de "Datos de Asignatura" (Prefill)
useEffect(() => {
const state = routerState.location.state as any
@@ -244,7 +248,7 @@ export function IAMateriaTab({
{msg.content}
</div>
{/* Renderizado de Sugerencias (Homologado con lógica de Materia) */}
{/* Renderizado de Sugerencias (Homologado con lógica de Asignatura) */}
{msg.sugerencia && !msg.sugerencia.aceptada && (
<div className="animate-in fade-in slide-in-from-top-1 mt-3 w-full">
<div className="rounded-xl border border-teal-100 bg-white p-4 shadow-md">
@@ -302,7 +306,7 @@ export function IAMateriaTab({
{showSuggestions && (
<div className="animate-in slide-in-from-bottom-2 absolute bottom-full z-50 mb-2 w-72 overflow-hidden rounded-xl border bg-white shadow-2xl">
<div className="border-b bg-slate-50 px-3 py-2 text-[10px] font-bold tracking-wider text-slate-500 uppercase">
Seleccionar campo de materia
Seleccionar campo de asignatura
</div>
<div className="max-h-64 overflow-y-auto p-1">
{availableFields.map((field) => (