Capítulo 3: Integración del Frontend
🎯 Objetivos
- Comprender el frontend de prueba proporcionado
- Conectar el frontend con el backend Spring Boot
- Probar el formulario de contacto en un entorno real
- Configurar CORS para Codespaces
📚 Recursos Frontend
| Recurso | Enlace |
|---|---|
| Código Frontend | Carpeta frontend |
| Guía de integración | 27-guide-formulaire-frontend-codespaces.md |
🎨 Presentación del Frontend
El frontend proporcionado es una aplicación simple HTML/CSS/JavaScript que permite:
- ✅ Enviar formularios de contacto
- ✅ Visualizar las respuestas de la API
- ✅ Probar la autenticación de administrador
- ✅ Consultar la lista de leads
Estructura del Frontend
frontend/
├── index.html # Página formulario de contacto
├── admin.html # Página admin (lista de leads)
├── login.html # Página de inicio de sesión
├── css/
│ └── styles.css # Estilos
└── js/
├── contact.js # Lógica formulario contacto
├── admin.js # Lógica admin
└── auth.js # Gestión autenticación
🚀 Inicio del Frontend
Opción 1: Con Live Server (VS Code / Codespaces)
-
Instalar la extensión Live Server en VS Code/Codespaces
-
Abrir la carpeta frontend:
cd frontend
-
Clic derecho en
index.html→ Open with Live Server -
El navegador se abre automáticamente en el frontend
Opción 2: Con Python (Simple HTTP Server)
# En la carpeta frontend
cd frontend
# Python 3
python -m http.server 3000
# Acceder a http://localhost:3000
Opción 3: Con Node.js
# Instalar serve globalmente
npm install -g serve
# Iniciar el servidor
cd frontend
serve -p 3000
⚙️ Configuración para Codespaces
Problema CORS en Codespaces
En GitHub Codespaces, las URLs son diferentes:
- Backend:
https://xxx-8080.app.github.dev - Frontend:
https://xxx-3000.app.github.dev
Solución: Configurar las URLs de Codespaces
-
Obtener la URL del backend en Codespaces:
- Cuando la aplicación Spring Boot inicia
- Anotar la URL pública (ej:
https://abc123-8080.app.github.dev)
-
Modificar el archivo JavaScript del frontend:
// js/config.js o en la parte superior de contact.js
// Configuración de la URL de la API
const API_BASE_URL = 'https://SU-CODESPACE-8080.app.github.dev';
// O para desarrollo local
// const API_BASE_URL = 'http://localhost:8080';
- Actualizar la configuración CORS del backend:
// SecurityConfig.java
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
📝 Uso del Formulario de Contacto
Página Principal (index.html)
┌─────────────────────────────────────────────────────────┐
│ CONTÁCTENOS │
├─────────────────────────────────────────────────────────┤
│ │
│ Nombre completo * Empresa │
│ ┌─────────────────────────┐ ┌─────────────────────┐│
│ │ Ingrese su nombre │ │ Su empresa ││
│ └─────────────────────────┘ └─────────────────────┘│
│ │
│ Email * Teléfono │
│ ┌─────────────────────────┐ ┌─────────────────────┐│
│ │ su@email.com │ │ 514-555-1234 ││
│ └─────────────────────────┘ └─────────────────────┘│
│ │
│ Tipo de solicitud * │
│ ┌─────────────────────────────────────────────────┬──┐│
│ │ Solicitud de información │ v││
│ └─────────────────────────────────────────────────┴──┘│
│ │
│ Mensaje * │
│ ┌────────────────────────────────────────────────────┐│
│ │ Describa su solicitud... ││
│ │ ││
│ └────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────┐ │
│ │ ENVIAR │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Prueba de Envío
- Llenar todos los campos obligatorios (*)
- Hacer clic en Enviar
- Observar la respuesta:
Éxito:
✅ ¡Mensaje enviado con éxito!
Su solicitud ha sido registrada. Nos pondremos en contacto pronto.
Error:
❌ Error al enviar
Por favor, verifique los campos e intente nuevamente.
🔐 Interfaz Admin
Inicio de Sesión (login.html)
- Acceder a
login.html - Ingresar las credenciales:
- Email:
admin@test.com - Password:
password123(o según configuración)
- Email:
- Hacer clic en Iniciar sesión
Dashboard Admin (admin.html)
Una vez autenticado, usted puede:
- 📋 Ver la lista de todos los contactos/leads
- 🔍 Filtrar por estado (NEW, CONTACTED, CONVERTED, LOST)
- ✏️ Cambiar el estado de un lead
- 🗑️ Eliminar un lead
┌─────────────────────────────────────────────────────────────────┐
│ Dashboard Admin - Gestión de Leads [Cerrar sesión]│
├─────────────────────────────────────────────────────────────────┤
│ │
│ Filtrar: [Todos ▼] [NEW] [CONTACTED] [CONVERTED] [LOST] │
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ID │ Nombre │ Email │ Tipo │ Estado │ ⚙ ││
│ ├────┼──────────────┼─────────────────┼─────────┼────────┼───┤│
│ │ 1 │ Jean Dupont │ jean@test.com │ INFO │ NEW │ ✏🗑││
│ │ 2 │ Marie Martin │ marie@test.com │ QUOTE │ CONTACT│ ✏🗑││
│ │ 3 │ Pierre Duval │ pierre@test.com │ SUPPORT │ NEW │ ✏🗑││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ Total: 3 leads | Nuevos: 2 | En curso: 1 │
└─────────────────────────────────────────────────────────────────┘
🔄 Flujo de Comunicación Frontend-Backend
📡 Llamadas API desde el Frontend
JavaScript para enviar el formulario
// contact.js
async function submitContact(formData) {
try {
const response = await fetch(`${API_BASE_URL}/api/contact`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
fullName: formData.fullName,
email: formData.email,
company: formData.company,
phone: formData.phone,
requestType: formData.requestType,
message: formData.message
})
});
if (!response.ok) {
throw new Error('Erreur lors de la soumission');
}
const data = await response.json();
showSuccess('Message envoyé avec succès!');
return data;
} catch (error) {
showError('Erreur: ' + error.message);
}
}
JavaScript para la autenticación admin
// auth.js
async function login(email, password) {
const response = await fetch(`${API_BASE_URL}/api/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
const data = await response.json();
if (response.ok) {
// Guardar el token JWT
localStorage.setItem('token', data.token);
window.location.href = 'admin.html';
} else {
showError('Identificadores incorrectos');
}
}
JavaScript para obtener los leads (con token)
// admin.js
async function getLeads() {
const token = localStorage.getItem('token');
const response = await fetch(`${API_BASE_URL}/api/admin/leads`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
if (response.status === 401) {
// Token expirado, redirigir a login
window.location.href = 'login.html';
}
throw new Error('Erreur lors du chargement');
}
return await response.json();
}
⚠️ Troubleshooting Frontend
Error CORS
Access to fetch at 'http://localhost:8080/api/contact' has been blocked by CORS policy
Solución: Verifique la configuración CORS del backend.
Token no enviado
Síntoma: 401 en los endpoints admin incluso después de iniciar sesión.
Solución: Verifique que el token esté correctamente almacenado y enviado:
console.log('Token:', localStorage.getItem('token'));
URL incorrecta
Síntoma: fetch failed o network error
Solución: Verifique que:
- El backend esté iniciado
- La URL en
API_BASE_URLsea correcta - Para Codespaces, utilice la URL pública
.app.github.dev
✅ Checklist de Validación
- Frontend accesible en el navegador
- Formulario de contacto visible
- Envío de contacto exitoso
- Respuesta de éxito mostrada
- Autenticación admin funcional
- Lista de leads visible tras autenticación
📖 Guía Completa
Para todas las instrucciones detalladas de integración frontend con Codespaces:
⏭️ Siguiente Paso
Capítulo 4: Curso Complementario →