fixed style and added new select whit div and fixed date to mx
This commit is contained in:
@@ -160,7 +160,6 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
|
||||
>
|
||||
{equipoSeleccionado ? (
|
||||
<span
|
||||
className={equipoSeleccionado?.plataforma?.nombre?.toUpperCase()}
|
||||
>
|
||||
{equipoSeleccionado.ubicacion}{" "}
|
||||
{equipoSeleccionado.nombre_equipo}
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.customSelect.disabled {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
'use client';
|
||||
|
||||
type EstadoPC = 'libre' | 'ocupada' | 'fallo';
|
||||
|
||||
const colores: Record<EstadoPC, string> = {
|
||||
libre: '#22c55e', // verde
|
||||
ocupada: '#ef4444', // rojo
|
||||
fallo: '#facc15', // amarillo
|
||||
};
|
||||
|
||||
const pcs = [
|
||||
{
|
||||
id: 'PC-01',
|
||||
x: 120,
|
||||
y: 180,
|
||||
width: 40,
|
||||
height: 40,
|
||||
estado: 'libre' as EstadoPC,
|
||||
},
|
||||
{
|
||||
id: 'PC-02',
|
||||
x: 170,
|
||||
y: 180,
|
||||
width: 40,
|
||||
height: 40,
|
||||
estado: 'ocupada' as EstadoPC,
|
||||
},
|
||||
{
|
||||
id: 'PC-03',
|
||||
x: 220,
|
||||
y: 180,
|
||||
width: 40,
|
||||
height: 40,
|
||||
estado: 'fallo' as EstadoPC,
|
||||
},
|
||||
];
|
||||
|
||||
export default function DSC() {
|
||||
return (
|
||||
<svg viewBox="0 0 1500 900" width="100%" height="auto">
|
||||
|
||||
{/* FONDO */}
|
||||
<image
|
||||
href="/plano.svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
pointerEvents="none"
|
||||
/>
|
||||
|
||||
{/* CAPA INTERACTIVA */}
|
||||
<g>
|
||||
{pcs.map(pc => (
|
||||
<g key={pc.id}>
|
||||
{/* CUADRO */}
|
||||
<rect
|
||||
x={pc.x}
|
||||
y={pc.y}
|
||||
width={pc.width}
|
||||
height={pc.height}
|
||||
fill={colores[pc.estado]}
|
||||
stroke="#bb4242"
|
||||
strokeWidth={1}
|
||||
rx={4}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => console.log(pc.id)}
|
||||
/>
|
||||
|
||||
{/* NÚMERO */}
|
||||
<text
|
||||
x={pc.x + pc.width / 2}
|
||||
y={pc.y + pc.height / 2 + 5}
|
||||
textAnchor="middle"
|
||||
fontSize={12}
|
||||
fill="#000"
|
||||
pointerEvents="none"
|
||||
>
|
||||
{pc.id.replace('PC-', '')}
|
||||
</text>
|
||||
</g>
|
||||
))}
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import Toggle from "@/app/Components/Global/Toggle/Toggle";
|
||||
import MachineTable from "./MachineTable";
|
||||
import styles from "./Page.module.css";
|
||||
import ToggleTable from "@/app/Components/Global/Toggle/ToggleTable";
|
||||
import MachineTableActive from "./MachineTableActive";
|
||||
import DSC from "./DSC";
|
||||
|
||||
export default async function Page(props: {
|
||||
searchParams?: Promise<{ numAcount: string; key: string }>;
|
||||
|
||||
@@ -29,7 +29,6 @@ function Mesas() {
|
||||
<form className="containerForm" onSubmit={handleConfirmar}>
|
||||
<label className="label">Mesas disponibles:</label>
|
||||
<div className="groupInput" style={{display:"flex", flexDirection:"column"}}>
|
||||
{/* Select de mesas */}
|
||||
<select value={mesa} onChange={(e) => setMesa(e.target.value)}>
|
||||
<option value="">-- Mesas disponibles --</option>
|
||||
<option value="1">1</option>
|
||||
|
||||
@@ -28,13 +28,36 @@ export default function MesasDisponibles() {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleEquipo = async (id_mesa: number) => {
|
||||
try {
|
||||
await fetch(`${envConfig.apiUrl}/mesa/${id_mesa}/activo`, {
|
||||
method: "PATCH",
|
||||
});
|
||||
|
||||
setMesas((prev) =>
|
||||
prev
|
||||
? prev.map((e) =>
|
||||
e.id_mesa === id_mesa
|
||||
? {
|
||||
...e,
|
||||
activo: e.activo === 1 ? 0 : 1,
|
||||
}
|
||||
: e,
|
||||
)
|
||||
: prev,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error al cambiar estado del equipo", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="containerSection">
|
||||
<div
|
||||
style={{
|
||||
overflow: "auto",
|
||||
height: "430px",
|
||||
width:"100%",
|
||||
width: "100%",
|
||||
scrollbarColor: "#2563eb white",
|
||||
}}
|
||||
>
|
||||
@@ -58,7 +81,6 @@ export default function MesasDisponibles() {
|
||||
<td>Mesa {mesa.id_mesa}</td>
|
||||
|
||||
<td
|
||||
className={isActivo ? "activo" : "inactivo"}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
@@ -67,12 +89,11 @@ export default function MesasDisponibles() {
|
||||
}}
|
||||
>
|
||||
<span>{isActivo ? "Sí" : "No"}</span>
|
||||
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isActivo}
|
||||
readOnly
|
||||
style={{ height: "2.5rem", maxWidth:"50px"}}
|
||||
style={{ height: "2.5rem", maxWidth: "50px" }}
|
||||
onChange={() => toggleEquipo(mesa.id_mesa)}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function TableEquipos() {
|
||||
|
||||
const toggleEquipo = async (id_equipo: number) => {
|
||||
try {
|
||||
await fetch(`${envConfig.apiUrl}/equipo/${id_equipo}/activo`, {
|
||||
await fetch(`${envConfig.apiUrl}/mesa/${id_equipo}/activo`, {
|
||||
method: "PATCH",
|
||||
});
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { envConfig } from "@/app/lib/config";
|
||||
|
||||
import "../../(private)/AsignacionEquipo/asignacion.css";
|
||||
|
||||
interface Equipo {
|
||||
id_equipo: number;
|
||||
id_plataforma: number;
|
||||
@@ -22,15 +24,16 @@ interface EnviarMensajeProps {
|
||||
|
||||
const EnviarMensaje = ({ titulo }: EnviarMensajeProps) => {
|
||||
const [equipos, setEquipos] = useState<Equipo[]>([]);
|
||||
const [equipoSeleccionado, setEquipoSeleccionado] = useState("");
|
||||
const [equipoSeleccionado, setEquipoSeleccionado] = useState<any>(null);
|
||||
const [loadingEquipos, setLoadingEquipos] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [mensaje, setMensaje] = useState("");
|
||||
const [customMsg, setCustomMsg] = useState("");
|
||||
|
||||
// 🔹 Traer equipos desde API
|
||||
useEffect(() => {
|
||||
const fetchEquipos = async () => {
|
||||
try {
|
||||
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
|
||||
const response = await axios.get(`${envConfig.apiUrl}/equipo/busy`);
|
||||
setEquipos(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error cargando equipos:", error);
|
||||
@@ -50,28 +53,59 @@ const EnviarMensaje = ({ titulo }: EnviarMensajeProps) => {
|
||||
|
||||
console.log(payload);
|
||||
|
||||
// aquí puedes enviar al backend
|
||||
// axios.post(...)
|
||||
};
|
||||
|
||||
return (
|
||||
<form className="containerForm" onSubmit={handleSubmit}>
|
||||
<label className="label">{titulo}</label>
|
||||
|
||||
<div className="groupInput">
|
||||
<select
|
||||
value={equipoSeleccionado}
|
||||
onChange={(e) => setEquipoSeleccionado(e.target.value)}
|
||||
<div
|
||||
className={`customSelect ${open ? "open" : ""} ${loadingEquipos ? "disabled" : ""}`}
|
||||
>
|
||||
<div
|
||||
className={`selectHeader ${equipoSeleccionado && equipoSeleccionado.plataforma?.nombre?.toUpperCase()}`}
|
||||
onClick={() => !loadingEquipos && setOpen(!open)}
|
||||
>
|
||||
<option value="">-- Selecciona un equipo --</option>
|
||||
{equipoSeleccionado ? (
|
||||
<span
|
||||
>
|
||||
{equipoSeleccionado.ubicacion}{" "}
|
||||
{equipoSeleccionado.nombre_equipo}{" "}
|
||||
{equipoSeleccionado.areaUbicacion.area}
|
||||
</span>
|
||||
) : (
|
||||
<span className="placeholder">
|
||||
{loadingEquipos
|
||||
? "Cargando equipos..."
|
||||
: "Seleccione un equipo"}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{equipos.map((eq) => (
|
||||
<option key={eq.id_equipo} value={eq.id_equipo}>
|
||||
{eq.ubicacion} {eq.nombre_equipo} {eq.plataforma.nombre}{" "}
|
||||
{eq.areaUbicacion.area}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="arrow">{open ? "▲" : "▼"}</span>
|
||||
</div>
|
||||
|
||||
{open && (
|
||||
<div className="options">
|
||||
{equipos.length === 0 && (
|
||||
<div className="option disabled">
|
||||
No hay equipos disponibles
|
||||
</div>
|
||||
)}
|
||||
|
||||
{equipos.map((eq) => (
|
||||
<div
|
||||
key={eq.id_equipo}
|
||||
className={`option ${eq.plataforma?.nombre?.toUpperCase()}`}
|
||||
onClick={() => {
|
||||
setEquipoSeleccionado(eq);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
{eq.ubicacion} {eq.nombre_equipo} {eq.areaUbicacion.area}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<label className="label">Seleccione el mensaje</label>
|
||||
@@ -86,7 +120,7 @@ const EnviarMensaje = ({ titulo }: EnviarMensajeProps) => {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<label className="label">Mensaje personalizado</label>
|
||||
|
||||
<div className="groupInput">
|
||||
@@ -98,7 +132,7 @@ const EnviarMensaje = ({ titulo }: EnviarMensajeProps) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<button
|
||||
className="button buttonSearch"
|
||||
type="submit"
|
||||
|
||||
@@ -4,6 +4,8 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
import "../../(private)/AsignacionEquipo/asignacion.css";
|
||||
|
||||
interface Equipos {
|
||||
id_equipo: number;
|
||||
id_plataforma: number;
|
||||
@@ -21,60 +23,99 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function SelectorEquipo({ onSearch }: Props) {
|
||||
const [sala, setSala] = useState<Equipos[]>();
|
||||
const [equipos, setEquipos] = useState<Equipos[]>([]);
|
||||
const searchParams = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
|
||||
const paramSala = Number(searchParams.get("equipo")) || 0;
|
||||
const [selected, setSelected] = useState<number>(paramSala);
|
||||
|
||||
const handleChangeEquipo = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const value = e.target.value;
|
||||
const numberValue = Number(e.target.value);
|
||||
|
||||
setSelected(numberValue);
|
||||
|
||||
if (numberValue === 0) {
|
||||
onSearch('');
|
||||
} else {
|
||||
onSearch(value);
|
||||
}
|
||||
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
|
||||
if (numberValue === 0) {
|
||||
params.delete("equipo");
|
||||
} else {
|
||||
params.set("equipo", value);
|
||||
}
|
||||
|
||||
router.push(`${pathname}?${params.toString()}`);
|
||||
};
|
||||
const paramEquipo = Number(searchParams.get("equipo")) || 0;
|
||||
const [selected, setSelected] = useState<Equipos | null>(null);
|
||||
const [loadingEquipos, setLoadingEquipos] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setLoadingEquipos(true);
|
||||
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
|
||||
|
||||
setSala(response.data);
|
||||
setEquipos(response.data);
|
||||
setLoadingEquipos(false);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (paramEquipo && equipos.length > 0) {
|
||||
const eq = equipos.find(e => e.id_equipo === paramEquipo);
|
||||
if (eq) {
|
||||
setSelected(eq);
|
||||
onSearch(eq.ubicacion);
|
||||
}
|
||||
}
|
||||
}, [paramEquipo, equipos]);
|
||||
|
||||
|
||||
return (
|
||||
<form className="form-container">
|
||||
<label>Ubicacion de equipo</label>
|
||||
<select value={selected} onChange={handleChangeEquipo}>
|
||||
<option value={0}>-- Selecciona una equipo --</option>
|
||||
{sala &&
|
||||
sala.map((eq) => (
|
||||
<option key={eq.id_equipo} value={eq.ubicacion}>
|
||||
{eq.ubicacion} {eq.nombre_equipo} {eq.plataforma.nombre}{" "}
|
||||
{eq.areaUbicacion.area}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<div
|
||||
className={`customSelect ${open ? "open" : ""} ${loadingEquipos ? "disabled" : ""}`}
|
||||
>
|
||||
<div
|
||||
className={`selectHeader ${selected && selected.plataforma?.nombre?.toUpperCase()}`}
|
||||
onClick={() => !loadingEquipos && setOpen(!open)}
|
||||
>
|
||||
{selected ? (
|
||||
<span
|
||||
>
|
||||
{selected.ubicacion}{" "}
|
||||
{selected.nombre_equipo}{" "}
|
||||
{selected.areaUbicacion.area}
|
||||
</span>
|
||||
) : (
|
||||
<span className="placeholder">
|
||||
{loadingEquipos
|
||||
? "Cargando equipos..."
|
||||
: "Seleccione un equipo"}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<span className="arrow">{open ? "▲" : "▼"}</span>
|
||||
</div>
|
||||
|
||||
{open && (
|
||||
<div className="options" style={{ bottom: "auto"}}>
|
||||
{equipos.length === 0 && (
|
||||
<div className="option disabled">
|
||||
No hay equipos disponibles
|
||||
</div>
|
||||
)}
|
||||
|
||||
{equipos.map((eq) => (
|
||||
<div
|
||||
key={eq.id_equipo}
|
||||
className={`option ${eq.plataforma?.nombre?.toUpperCase()}`}
|
||||
onClick={() => {
|
||||
setSelected(eq);
|
||||
setOpen(false);
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
|
||||
if (eq.id_equipo === 0) {
|
||||
params.delete("equipo");
|
||||
} else {
|
||||
params.set("equipo", String(eq.id_equipo));
|
||||
}
|
||||
|
||||
router.push(`${pathname}?${params.toString()}`);
|
||||
}}
|
||||
>
|
||||
{eq.ubicacion} {eq.nombre_equipo} {eq.areaUbicacion.area}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,19 @@ function PorRecibos({ desde, hasta }: Props) {
|
||||
fetchRecibos();
|
||||
}, [desde, hasta]);
|
||||
|
||||
const formatearFechaMX = (fechaISO: string) => {
|
||||
return new Date(fechaISO).toLocaleString("es-MX", {
|
||||
timeZone: "America/Mexico_City",
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
{recibos.length > 0 && <DownloadReporteXLSX />}
|
||||
@@ -81,7 +94,8 @@ function PorRecibos({ desde, hasta }: Props) {
|
||||
<td>{recibo.folio_recibo}</td>
|
||||
<td>${Number(recibo.monto).toFixed(2)}</td>
|
||||
<td>{recibo.fecha_recibo}</td>
|
||||
<td>{recibo.fecha_registro}</td>
|
||||
<td>{formatearFechaMX(recibo.fecha_registro)}</td>
|
||||
|
||||
<td>{recibo.user.usuario}</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
@@ -57,6 +57,13 @@
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
|
||||
.userName{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 50px;
|
||||
}
|
||||
}
|
||||
@media(max-width:450px){
|
||||
.userName{
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
|
||||
+2
-2
@@ -374,7 +374,6 @@ a {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
min-height: 45px;
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
text-align: start;
|
||||
@@ -692,6 +691,7 @@ table td:last-child {
|
||||
|
||||
.toggleSection {
|
||||
margin-top: 2rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -702,7 +702,7 @@ table td:last-child {
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 450px) {
|
||||
@media (max-width: 700px) {
|
||||
.title {
|
||||
max-width: 250px;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 1.2 MiB |
Reference in New Issue
Block a user