spinners, creación manual de asignatura, actualización de asignaturas generadas por sugerencias
fix #29: - Se agregaron spinners en la creación con IA de un plan o una asignatura - Se añadió la creación manual de asignaturas - Al generar asignaturas a partir de sugerencias, el badge de estado de la asignatura dice 'Generando' y muestra una animación tipo respiro para indicar que está siendo generada. Adicionalmente, se actualiza automáticamente la UI una vez que acabó de ser generada
This commit is contained in:
@@ -16,7 +16,7 @@ import type {
|
||||
AsignaturaSugerida,
|
||||
DataAsignaturaSugerida,
|
||||
} from '@/features/asignaturas/nueva/types'
|
||||
import type { Database } from '@/types/supabase'
|
||||
import type { Database, TablesInsert } from '@/types/supabase'
|
||||
|
||||
const EDGE = {
|
||||
generate_subject_suggestions: 'generate-subject-suggestions',
|
||||
@@ -89,23 +89,18 @@ export async function subjects_bibliografia_list(
|
||||
return data ?? []
|
||||
}
|
||||
|
||||
/** Wizard: crear asignatura manual (Edge Function) */
|
||||
export type SubjectsCreateManualInput = {
|
||||
planId: UUID
|
||||
datosBasicos: {
|
||||
nombre: string
|
||||
clave?: string
|
||||
tipo: TipoAsignatura
|
||||
creditos: number
|
||||
horasSemana?: number
|
||||
estructuraId: UUID
|
||||
}
|
||||
}
|
||||
|
||||
export async function subjects_create_manual(
|
||||
payload: SubjectsCreateManualInput,
|
||||
payload: TablesInsert<'asignaturas'>,
|
||||
): Promise<Asignatura> {
|
||||
return invokeEdge<Asignatura>(EDGE.subjects_create_manual, payload)
|
||||
const supabase = supabaseBrowser()
|
||||
const { data, error } = await supabase
|
||||
.from('asignaturas')
|
||||
.insert(payload)
|
||||
.select()
|
||||
.single()
|
||||
|
||||
throwIfError(error)
|
||||
return requireData(data, 'No se pudo crear la asignatura.')
|
||||
}
|
||||
|
||||
export type AIGenerateSubjectInput = {
|
||||
|
||||
@@ -77,6 +77,16 @@ export function usePlanAsignaturas(planId: UUID | null | undefined) {
|
||||
: ['planes', 'asignaturas', null],
|
||||
queryFn: () => plan_asignaturas_list(planId as UUID),
|
||||
enabled: Boolean(planId),
|
||||
|
||||
refetchInterval: (query) => {
|
||||
const data = query.state.data
|
||||
if (!Array.isArray(data)) return false
|
||||
const hayGenerando = data.some(
|
||||
(a: any) => (a as { estado?: unknown }).estado === 'generando',
|
||||
)
|
||||
return hayGenerando ? 500 : false
|
||||
},
|
||||
refetchIntervalInBackground: true,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -269,7 +279,7 @@ export function useDeleteLinea() {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: lineas_delete,
|
||||
onSuccess: (idEliminado) => {
|
||||
onSuccess: (_idEliminado) => {
|
||||
// Invalidamos para que las materias y líneas se refresquen
|
||||
qc.invalidateQueries({ queryKey: ['plan_lineas'] })
|
||||
qc.invalidateQueries({ queryKey: ['plan_asignaturas'] })
|
||||
|
||||
@@ -23,10 +23,10 @@ import { qk } from '../query/keys'
|
||||
|
||||
import type {
|
||||
BibliografiaUpsertInput,
|
||||
SubjectsCreateManualInput,
|
||||
SubjectsUpdateFieldsPatch,
|
||||
} from '../api/subjects.api'
|
||||
import type { UUID } from '../types/domain'
|
||||
import type { TablesInsert } from '@/types/supabase'
|
||||
|
||||
export function useSubject(subjectId: UUID | null | undefined) {
|
||||
return useQuery({
|
||||
@@ -82,7 +82,7 @@ export function useCreateSubjectManual() {
|
||||
const qc = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (payload: SubjectsCreateManualInput) =>
|
||||
mutationFn: (payload: TablesInsert<'asignaturas'>) =>
|
||||
subjects_create_manual(payload),
|
||||
onSuccess: (subject) => {
|
||||
qc.setQueryData(qk.asignatura(subject.id), subject)
|
||||
|
||||
Reference in New Issue
Block a user