fix: docker build fallaba por public/ ausente y login alineado con sam-portal

This commit is contained in:
Nurfog committed 2026-10-13 18:00:45 -03:00
1 parent 2dc41ed4fa
commit 2b60a17645
6 files changed
+111 -81

No files matched your search

+2 -2
View File
@@ -18,8 +18,8 @@ FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 -G nodejs nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

+33
View File
@@ -800,6 +800,23 @@ a:hover {
object-fit: contain;
}
.login-page .login-main-text h1 {
font-size: 2rem;
font-weight: 700;
}
.login-page .login-main-text h3 {
font-size: 1.05rem;
font-weight: 400;
opacity: 0.85;
}
/* Columna derecha: sin esta regla base la tarjeta queda bajo el sidenav
fijo, porque .main solo aporta el margen en pantallas >= 768px. */
.main {
padding: 0 24px;
}
/* ---------------------------------------------------------------
Responsive
--------------------------------------------------------------- */
@@ -819,6 +836,22 @@ a:hover {
margin-left: 0;
}
.login-page .sidenav {
padding: 20px 0 10px;
}
.login-page .login-main-text {
padding: 20px;
}
.login-page .login-main-text h1 {
font-size: 1.5rem;
}
.main {
padding: 0 12px;
}
.detail-grid {
grid-template-columns: 1fr;
gap: 24px;
+3
View File
@@ -11,6 +11,9 @@ export const metadata: Metadata = {
template: "%s · Proyectos · SAM",
},
description: "Gestor de proyectos estilo Linear para la plataforma SAM.",
icons: {
icon: "/favicon.png",
},
};
/**
+73 -79
View File
@@ -8,8 +8,9 @@ import { useAuth } from "@/lib/auth";
* Acceso al módulo. Valida contra sige_sam_v3.usuario en el backend
* (POST /api/proyectos/auth/login), igual que el resto de módulos SAM.
*
* Patrón visual de sam-portal / SistemaCalidad: sidenav azul con la marca
* a la izquierda y la tarjeta de acceso a la derecha.
* Estructura idéntica a la de sam-portal (ventas/login.aspx): sidenav azul
* sólido #00285d con la marca a la izquierda, y el formulario en .main,
* que a partir de 768px se desplaza el 40% del sidenav.
*/
export default function LoginPage() {
const router = useRouter();
@@ -43,87 +44,80 @@ export default function LoginPage() {
return (
<div className="login-page">
<div className="container-fluid">
<div className="row min-vh-100">
{/* Marca */}
<div className="col-md-5 sidenav d-flex flex-column justify-content-center">
<div className="login-main-text text-center">
<i className="bx bx-briefcase" style={{ fontSize: "5rem" }} />
<h1 className="fw-bold mt-3">Proyectos</h1>
<p className="mb-0" style={{ opacity: 0.8 }}>
Gestión de proyectos · SAM
</p>
<p style={{ opacity: 0.5, fontSize: "0.85rem" }}>
Organismo Técnico de Capacitación
</p>
</div>
</div>
<div className="sidenav">
<div className="login-main-text text-center">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src="/logo-sam.png" alt="SAM" />
<h1 className="fw-bold">Proyectos</h1>
<h3>Welcome | Bienvenido/a</h3>
<h3>Gestión de Proyectos</h3>
</div>
</div>
{/* Formulario */}
<div className="col-md-7 d-flex align-items-center justify-content-center">
<div className="lp-card p-4 p-md-5" style={{ maxWidth: 420, width: "100%" }}>
<h2 className="h5 fw-bold mb-1">Acceso al sistema</h2>
<p className="small mb-4" style={{ color: "var(--inv-muted)" }}>
Use su RUT y clave del sistema central (SIGE).
</p>
<div className="main">
<div
className="row justify-content-center align-items-center"
style={{ minHeight: "85vh" }}
>
<div className="col-md-12">
<div className="col-md-12 text-center">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8">
<div className="card alert alert-secondary">
<div className="card-body">
<div className="mb-3">
<strong>USUARIO | CLAVE</strong>
</div>
<form onSubmit={handleSubmit}>
{error && (
<div className="alert alert-danger d-flex align-items-center gap-2 py-2" role="alert">
<i className="bx bx-error" />
<span className="small">{error}</span>
<form onSubmit={handleSubmit}>
{error && (
<div className="alert alert-danger py-2 mb-2">
<i className="bx bx-error me-1" />
{error}
</div>
)}
<input
name="TextBoxRut"
type="text"
value={idUsuario}
onChange={(event) => setIdUsuario(event.target.value)}
className="form-control shadow mb-2"
required
placeholder="Usuario"
autoComplete="username"
autoFocus
/>
<input
name="TextBoxClave"
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
className="form-control shadow mb-2"
required
placeholder="Clave"
autoComplete="current-password"
/>
<div className="d-grid">
<button
type="submit"
disabled={submitting}
className="btn btn-success btn-sm"
>
{submitting ? (
<span className="spinner-border spinner-border-sm" />
) : (
"Ingresar"
)}
</button>
</div>
</form>
</div>
</div>
)}
<div className="mb-3">
<label htmlFor="idUsuario" className="form-label">
Usuario (RUT o legajo)
</label>
<input
type="text"
id="idUsuario"
className="form-control"
autoComplete="username"
value={idUsuario}
onChange={(event) => setIdUsuario(event.target.value)}
required
autoFocus
/>
</div>
<div className="mb-4">
<label htmlFor="password" className="form-label">
Clave
</label>
<input
type="password"
id="password"
className="form-control"
autoComplete="current-password"
value={password}
onChange={(event) => setPassword(event.target.value)}
required
/>
</div>
<button
type="submit"
className="btn btn-accent w-100 py-2 d-flex align-items-center justify-content-center gap-2"
disabled={submitting}
>
{submitting ? (
<>
<span className="spinner-border spinner-border-sm" role="status" />
Verificando…
</>
) : (
<>
<i className="bx bx-log-in" />
Ingresar
</>
)}
</button>
</form>
<div className="col-md-2" />
</div>
</div>
</div>
</div>