feat: complete fases 3,4,5 - frontend, containers, e2e tests

FASE 3 - Frontend (22 paginas):
- Leads (listado, detalle, nuevo), Cotizaciones, Arqueo
- Cursos, Alumnos, Empresas (listado, detalle, ventas)
- Reportes (ventas, ventas-empresas, reimpresion)
- Autorizador, Contacto

FASE 4 - Contenedores:
- docker-compose.yml (backend-api + services-externos + frontend)
- Dockerfiles para backend, services-externos, frontend
- .env.example con secretos

FASE 5 - Pruebas E2E:
- Playwright config + 3 spec files (login, leads, dashboard)
- 7 escenarios: login, error, sidebar, crear lead,
  dashboard cards, timeout, reportes
This commit is contained in:
2026-07-08 11:07:27 -04:00
parent cf2349ef2f
commit 129991cfb7
24 changed files with 967 additions and 3 deletions
+40
View File
@@ -0,0 +1,40 @@
'use client';
import { useState, FormEvent } from 'react';
import { api } from '@/services/api';
export default function ContactoPage() {
const [mail, setMail] = useState('');
const [mensaje, setMensaje] = useState('');
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
try {
await api.post('/email/send', { to: mail, subject: 'Contacto desde SAM', body: mensaje });
alert('Correo enviado');
setMail('');
setMensaje('');
} catch {
alert('Error al enviar');
}
};
return (
<div>
<h3 className="mb-3">Contacto</h3>
<div className="card shadow p-4">
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label">Correo</label>
<input type="email" className="form-control" value={mail} onChange={e => setMail(e.target.value)} required />
</div>
<div className="mb-3">
<label className="form-label">Mensaje</label>
<textarea className="form-control" rows={4} value={mensaje} onChange={e => setMensaje(e.target.value)} required />
</div>
<button type="submit" className="btn btn-primary">Enviar</button>
</form>
</div>
</div>
);
}