Se limitaron el número de caracteres y de digitos en los inputs de los wizards

This commit was merged in pull request #84.
This commit is contained in:
2026-02-06 12:23:17 -06:00
parent 1f78284fb6
commit 6fc1677654
6 changed files with 64 additions and 39 deletions

View File

@@ -27,14 +27,25 @@ export function PasoBasicosForm({
const [creditosInput, setCreditosInput] = useState<string>(() => {
const c = Number(wizard.datosBasicos.creditos ?? 0)
return c > 0 ? c.toFixed(2) : ''
let newC = c
console.log('antes', newC)
if (Number.isFinite(c) && c > 999) {
newC = 999
}
console.log('desp', newC)
return newC > 0 ? newC.toFixed(2) : ''
})
const [creditosFocused, setCreditosFocused] = useState(false)
useEffect(() => {
if (creditosFocused) return
const c = Number(wizard.datosBasicos.creditos ?? 0)
setCreditosInput(c > 0 ? c.toFixed(2) : '')
let newC = c
if (Number.isFinite(c) && c > 999) {
newC = 999
}
setCreditosInput(newC > 0 ? newC.toFixed(2) : '')
}, [wizard.datosBasicos.creditos, creditosFocused])
return (
@@ -44,6 +55,7 @@ export function PasoBasicosForm({
<Input
id="nombre"
placeholder="Ej. Matemáticas Discretas"
maxLength={200}
value={wizard.datosBasicos.nombre}
onChange={(e) =>
onChange(
@@ -67,6 +79,7 @@ export function PasoBasicosForm({
<Input
id="codigo"
placeholder="Ej. MAT-101"
maxLength={200}
value={wizard.datosBasicos.codigo || ''}
onChange={(e) =>
onChange(
@@ -123,6 +136,7 @@ export function PasoBasicosForm({
id="creditos"
type="text"
inputMode="decimal"
maxLength={6}
pattern="^\\d*(?:[.,]\\d{0,2})?$"
value={creditosInput}
onKeyDown={(e) => {
@@ -191,6 +205,42 @@ export function PasoBasicosForm({
/>
</div>
<div className="grid gap-1">
<Label htmlFor="estructura">Estructura de la asignatura</Label>
<Select
value={wizard.datosBasicos.estructuraId as string}
onValueChange={(val) =>
onChange(
(w): NewSubjectWizardState => ({
...w,
datosBasicos: { ...w.datosBasicos, estructuraId: val },
}),
)
}
>
<SelectTrigger
id="estructura"
className="w-full min-w-0 [&>span]:block! [&>span]:truncate!"
>
<SelectValue placeholder="Selecciona plantilla..." />
</SelectTrigger>
<SelectContent>
{estructuras?.map(
(
e: Database['public']['Tables']['estructuras_asignatura']['Row'],
) => (
<SelectItem key={e.id} value={e.id}>
{e.nombre}
</SelectItem>
),
)}
</SelectContent>
</Select>
<p className="text-muted-foreground text-xs">
Define los campos requeridos (ej. Objetivos, Temario, Evaluación).
</p>
</div>
<div className="grid gap-1">
<Label htmlFor="horasAcademicas">
Horas Académicas
@@ -202,6 +252,7 @@ export function PasoBasicosForm({
id="horasAcademicas"
type="number"
min={1}
max={999}
step={1}
inputMode="numeric"
pattern="[0-9]*"
@@ -246,6 +297,7 @@ export function PasoBasicosForm({
id="horasIndependientes"
type="number"
min={1}
max={999}
step={1}
inputMode="numeric"
pattern="[0-9]*"
@@ -278,42 +330,6 @@ export function PasoBasicosForm({
placeholder="Ej. 24"
/>
</div>
<div className="grid gap-1">
<Label htmlFor="estructura">Estructura de la asignatura</Label>
<Select
value={wizard.datosBasicos.estructuraId as string}
onValueChange={(val) =>
onChange(
(w): NewSubjectWizardState => ({
...w,
datosBasicos: { ...w.datosBasicos, estructuraId: val },
}),
)
}
>
<SelectTrigger
id="estructura"
className="w-full min-w-0 [&>span]:block! [&>span]:truncate!"
>
<SelectValue placeholder="Selecciona plantilla..." />
</SelectTrigger>
<SelectContent>
{estructuras?.map(
(
e: Database['public']['Tables']['estructuras_asignatura']['Row'],
) => (
<SelectItem key={e.id} value={e.id}>
{e.nombre}
</SelectItem>
),
)}
</SelectContent>
</Select>
<p className="text-muted-foreground text-xs">
Define los campos requeridos (ej. Objetivos, Temario, Evaluación).
</p>
</div>
</div>
)
}

View File

@@ -56,6 +56,7 @@ export function PasoDetallesPanel({
<Label>Descripción del enfoque académico</Label>
<Textarea
placeholder="Describe el enfoque, alcance y público objetivo. Ej.: Teórica-práctica enfocada en patrones de diseño, con proyectos semanales."
maxLength={7000}
value={wizard.iaConfig?.descripcionEnfoqueAcademico}
onChange={(e) =>
onChange(
@@ -80,6 +81,7 @@ export function PasoDetallesPanel({
</Label>
<Textarea
placeholder="Opcional: restricciones y preferencias. Ej.: incluye bibliografía en español, evita contenido avanzado, prioriza evaluación por proyectos."
maxLength={7000}
value={wizard.iaConfig?.instruccionesAdicionalesIA}
onChange={(e) =>
onChange(

View File

@@ -50,6 +50,7 @@ export function PasoBasicosForm({
id="nombrePlan"
placeholder="Ej. Ingeniería en Sistemas (2026)"
value={wizard.datosBasicos.nombrePlan}
maxLength={200}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
onChange(
(w): NewPlanWizardState => ({
@@ -228,6 +229,7 @@ export function PasoBasicosForm({
id="numCiclos"
type="number"
min={1}
max={99}
step={1}
inputMode="numeric"
pattern="[0-9]*"

View File

@@ -49,6 +49,7 @@ export function PasoDetallesPanel({
id="desc"
className="bg-background text-foreground ring-offset-background focus-visible:ring-ring min-h-24 w-full rounded-md border px-3 py-2 text-sm shadow-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
placeholder="Describe el enfoque del programa…"
maxLength={7000}
value={wizard.iaConfig?.descripcionEnfoqueAcademico || ''}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
onChange((w) => ({
@@ -73,6 +74,7 @@ export function PasoDetallesPanel({
id="notas"
className="bg-background text-foreground ring-offset-background focus-visible:ring-ring min-h-24 w-full rounded-md border px-3 py-2 text-sm shadow-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
placeholder="Lineamientos institucionales, restricciones, etc."
maxLength={7000}
value={wizard.iaConfig?.instruccionesAdicionalesIA || ''}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
onChange((w) => ({

View File

@@ -93,6 +93,7 @@ export type Database = {
asignatura_hash: string | null
codigo: string | null
contenido_tematico: Json
conversation_id: string | null
creado_en: string
creado_por: string | null
creditos: number
@@ -116,6 +117,7 @@ export type Database = {
asignatura_hash?: string | null
codigo?: string | null
contenido_tematico?: Json
conversation_id?: string | null
creado_en?: string
creado_por?: string | null
creditos: number
@@ -139,6 +141,7 @@ export type Database = {
asignatura_hash?: string | null
codigo?: string | null
contenido_tematico?: Json
conversation_id?: string | null
creado_en?: string
creado_por?: string | null
creditos?: number