diff --git a/app/(private)/AgregarTiempo/Addtime.tsx b/app/(private)/AgregarTiempo/Addtime.tsx new file mode 100644 index 0000000..d107cf4 --- /dev/null +++ b/app/(private)/AgregarTiempo/Addtime.tsx @@ -0,0 +1,173 @@ +"use client"; + +import { useState } from "react"; +import toast from "react-hot-toast"; +import { useRouter } from "next/navigation"; + +import Selection from "@/app/Components/Selection/Selection"; +import { PostReceipt } from "@/app/lib/postReceipt"; + +import "./addTime.css"; +import SelectionCo from "@/app/Components/Selection/SelectionCo"; + +const PLATAFORMA_MAP: Record = { + WINDOWS: 1, + MACINTOSH: 2, + PROFESORES: 5, +}; + +interface AddTimeProps { + numAcount: number; + plataformasInscritas: string[]; +} + +export default function AddTime({ + numAcount, + plataformasInscritas, +}: AddTimeProps) { + const router = useRouter(); + + // 🔹 selección plataforma + const [plataformaSeleccionada, setPlataformaSeleccionada] = + useState(null); + + // 🔹 datos del recibo + const [folio, setFolio] = useState(""); + const [amount, setAmount] = useState(""); + const [date, setDate] = useState(""); + + // 🔹 restricción de fechas + const day = new Date(); + const year = day.getFullYear(); + const month = day.getMonth(); + const today = day.getDate(); + + const minFecha = new Date(year, month, 1).toISOString().split("T")[0]; + const maxFecha = new Date(year, month, today).toISOString().split("T")[0]; + + // 🔹 lógica central (AQUÍ crecerá después) + const handleSaveReceipt = async () => { + if (!numAcount) { + toast.error("Busca de nuevo al estudiante"); + return; + } + + if (!plataformaSeleccionada) { + toast.error("Selecciona una plataforma"); + return; + } + + if (!folio) { + toast.error("Ingresa el folio del ticket"); + return; + } + + if (!amount) { + toast.error("Coloca el monto a depositar"); + return; + } + + if (!date) { + toast.error("Coloca la fecha"); + return; + } + + const id_plataforma = PLATAFORMA_MAP[plataformaSeleccionada]; + + try { + // 1️⃣ Guardar recibo + await PostReceipt({ + id_cuenta: numAcount, + folio_recibo: folio, + monto: Number(amount), + fecha_recibo: date, + }); + + // 🔜 2️⃣ AQUÍ luego: + // await inscribirAlumno(...) + // await agregarTiempo(...) + // await marcarPago(...) + + setFolio(""); + setAmount(""); + setDate(""); + + toast.success("Recibo guardado correctamente"); + router.refresh(); + } catch (err: any) { + toast.error(err.message || "Error al guardar"); + } + }; + + return ( +
+ + +
{ + e.preventDefault(); + handleSaveReceipt(); + }} + > +
+
+ + { + const value = e.target.value; + if (/^\d*$/.test(value) && value.length <= 7) { + setFolio(value); + } + }} + placeholder="Numero de ticket..." + inputMode="numeric" + /> +
+ +
+ + { + const value = e.target.value; + if (/^\d*\.?\d*$/.test(value)) { + const numericValue = parseFloat(value); + if (value === "" || numericValue <= 1000) { + setAmount(value); + } else { + toast.error("El monto no puede superar $1000.00"); + } + } + }} + placeholder="Monto recibido..." + inputMode="numeric" + /> +
+ +
+ + setDate(e.target.value)} + min={minFecha} + max={maxFecha} + /> +
+ +
+ +
+
+
+
+ ); +} diff --git a/app/(private)/AgregarTiempo/page.tsx b/app/(private)/AgregarTiempo/page.tsx index 2eef6c1..f8cc99c 100644 --- a/app/(private)/AgregarTiempo/page.tsx +++ b/app/(private)/AgregarTiempo/page.tsx @@ -1,52 +1,76 @@ import SearchUser from "@/app/Components/Global/SearchUser/searchUser"; import Information from "@/app/Components/Global/Information/information"; -import Receipt from "@/app/Components/Receipt/Receipt"; +import ShowError from "@/app/Components/Global/ShowError"; + +import { GetRegisterStudent } from "@/app/lib/getRegisterStudent"; +import { envConfig } from "@/app/lib/config"; import "./addTime.css"; -import Selection from "@/app/Components/Selection/Selection"; -import ShowError from "@/app/Components/Global/ShowError"; -import { GetRegisterStudent } from "@/app/lib/getRegisterStudent"; +import AddTime from "./Addtime"; + +async function getInscripcion(idCuenta: number) { + try { + const res = await fetch(`${envConfig.apiUrl}/alumno-inscrito/${idCuenta}`, { + headers: { "Content-Type": "application/json" }, + cache: "no-store", + }); + + if (!res.ok) throw new Error("No se pudo cargar inscripción"); + + return await res.json(); + } catch { + return []; + } +} export default async function Page(props: { - searchParams?: Promise<{ - numAcount: string; - }>; + searchParams?: Promise<{ numAcount: string }>; }) { const params = await props.searchParams; - const numAcount = params?.numAcount ? params.numAcount : null; + const numAcount = params?.numAcount ?? null; + + let student = null; + let inscripcion: any[] = []; let errorMessage = ""; - let student: any = null; if (numAcount) { - const result = await GetRegisterStudent(parseInt(numAcount)); + const idCuenta = parseInt(numAcount); - if (result.error) { - errorMessage = `${result.error}`; - return; + const result = await GetRegisterStudent(idCuenta); + if (result?.error) { + errorMessage = result.error; } else { student = result[0]?.alumno; + inscripcion = await getInscripcion(idCuenta); } } + const plataformasInscritas = inscripcion.map( + (ins) => ins.plataforma?.nombre + ); + return (
- {errorMessage && } + {errorMessage && } -

AGREGAR TIEMPO

+

AGREGAR TIEMPO

{student && ( <> - + -
- - -
+ )}
); } -//IO +//IO \ No newline at end of file diff --git a/app/Components/Selection/SelectionCo.tsx b/app/Components/Selection/SelectionCo.tsx new file mode 100644 index 0000000..ba51d12 --- /dev/null +++ b/app/Components/Selection/SelectionCo.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { useState } from "react"; +import "./Selection.css"; + +function SelectionCo({ + plataformasInscritas = [], + onSelect, +}: { + plataformasInscritas: string[]; + onSelect: (plataforma: string | null) => void; +}) { + const [selected, setSelected] = useState(null); + + const options = [ + { + name: "WINDOWS", + img: "https://images.icon-icons.com/2235/PNG/512/windows_os_logo_icon_134678.png", + }, + { + name: "MACINTOSH", + img: "https://upload.wikimedia.org/wikipedia/commons/f/fa/Apple_logo_black.svg", + }, + { + name: "PROFESORES", + img: "https://cdn-icons-png.flaticon.com/512/3135/3135715.png", + }, + ]; + + // ✅ SOLO las inscritas + const opcionesInscritas = options.filter((option) => + plataformasInscritas.includes(option.name), + ); + + const handleSelect = (optionName: string) => { + const value = selected === optionName ? null : optionName; + setSelected(value); + onSelect(value); + }; + + return ( +
+ {opcionesInscritas.map((option, index) => ( +
handleSelect(option.name)} + > + + {option.name} +
+ ))} + + {opcionesInscritas.length === 0 && ( +

+ El alumno no está inscrito en ninguna plataforma +

+ )} +
+ ); +} + +export default SelectionCo;