* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: #f5f5f5;
color: #333;
line-height: 1.6;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
background-color: #d68910;
color: white;
padding: 20px;
text-align: center;
border-radius: 8px 8px 0 0;
margin-bottom: 20px;
}
h1 {
margin-bottom: 10px;
}
.descripcion {
font-style: italic;
margin-bottom: 20px;
}
.categorias {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 30px;
}
.categoria {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
flex: 1 1 250px;
transition: transform 0.3s ease;
cursor: pointer;
}
.categoria:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.categoria h3 {
color: #d68910;
margin-bottom: 10px;
border-bottom: 2px solid #e0e0e0;
padding-bottom: 5px;
}
.temas {
margin-top: 40px;
}
.tema {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
margin-bottom: 15px;
}
.tema-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 10px;
}
.tema-title {
color: #3f51b5;
font-weight: bold;
font-size: 1.2em;
}
.tema-info {
font-size: 0.9em;
color: #666;
}
.tema-content {
margin-bottom: 15px;
}
.respuestas {
margin-top: 20px;
padding-top: 10px;
border-top: 1px dashed #e0e0e0;
}
.respuesta {
background-color: #f9f9f9;
border-radius: 8px;
padding: 10px;
margin-bottom: 10px;
}
.respuesta-header {
display: flex;
justify-content: space-between;
font-size: 0.9em;
color: #666;
margin-bottom: 5px;
}
.nuevo-tema,
.nueva-respuesta {
margin-top: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input,
textarea,
select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1em;
}
textarea {
min-height: 100px;
}
button {
background-color: #3f51b5;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 1em;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #303f9f;
}
.btn-small {
font-size: 0.9em;
padding: 5px 10px;
}
.nav-buttons {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
footer {
text-align: center;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #ddd;
color: #666;
font-size: 0.9em;
}
.loading {
text-align: center;
padding: 20px;
font-style: italic;
color: #666;
}
/* Para dispositivos móviles */
@media (max-width: 768px) {
.container {
padding: 10px;
}
header {
padding: 15px;
}
.categoria {
flex: 1 1 100%;
}
}
Foro de Aplenguas
Espacio de discusión para estudiantes de Aplicaciones Lingüísticas
Categorías del Foro
Gramática
Discusiones sobre reglas gramaticales, sintaxis y estructura del lenguaje.
Cargando…
Vocabulario
Ampliación de léxico, términos técnicos y expresiones idiomáticas.
Cargando…
Escritura Creativa
Ejercicios de redacción, composición y estilo literario.
Cargando…
Expresión Oral
Técnicas de conversación, pronunciación y oratoria.
Cargando…
Dudas y Consultas
Preguntas generales sobre el curso y temas lingüísticos.
Cargando…
Recursos y Materiales
Compartir herramientas útiles para el aprendizaje de lenguas.
Cargando…
Temas de [Categoría]
Respuestas
Responder
Crear nuevo tema
Gramática
Vocabulario
Escritura Creativa
Expresión Oral
Dudas y Consultas
Recursos y Materiales
// Configuración de Firebase – Usando la versión 8 (no módulos)
const firebaseConfig = {
apiKey: “AIzaSyDk4Ht4vk9JVZ4OkhJmXJ-kgTDiI5Ms3Iw”,
authDomain: “foro-de-aplenguas.firebaseapp.com”,
databaseURL: “https://foro-de-aplenguas-default-rtdb.firebaseio.com”, // URL explícito a la base de datos
projectId: “foro-de-aplenguas”,
storageBucket: “foro-de-aplenguas.appspot.com”, // Corregido appspot.com en lugar de firebasestorage.app
messagingSenderId: “82293662876”,
appId: “1:82293662876:web:efa44b46ceab394c5d7959”
};
// Inicializar Firebase
firebase.initializeApp(firebaseConfig);
// Obtener una referencia a la base de datos
const database = firebase.database();
// Variables globales
let categoriaActual = “”;
let temaActualId = null;
let temaActual = null;
// Función para formatear la fecha
function obtenerFechaFormateada() {
const meses = [‘enero’, ‘febrero’, ‘marzo’, ‘abril’, ‘mayo’, ‘junio’, ‘julio’, ‘agosto’, ‘septiembre’, ‘octubre’, ‘noviembre’, ‘diciembre’];
const ahora = new Date();
return `${ahora.getDate()} de ${meses[ahora.getMonth()]} de ${ahora.getFullYear()}`;
}
// Función para depurar errores de Firebase – ayuda a identificar problemas
function handleFirebaseError(error) {
console.error(“Error de Firebase:”, error);
alert(“Error: ” + error.message);
}
// Inicialización: cargar estadísticas para cada categoría
function cargarEstadisticas() {
const categorias = [‘gramatica’, ‘vocabulario’, ‘escritura’, ‘oral’, ‘dudas’, ‘recursos’];
categorias.forEach(categoria => {
// Referencia a los temas de esta categoría
const temasRef = database.ref(‘temas’).orderByChild(‘categoria’).equalTo(categoria);
temasRef.once(‘value’)
.then(snapshot => {
const numTemas = snapshot.numChildren();
let ultimaFecha = “nunca”;
snapshot.forEach(childSnapshot => {
const tema = childSnapshot.val();
if (!ultimaFecha || ultimaFecha === “nunca” || new Date(tema.timestamp) > new Date(ultimaFecha)) {
ultimaFecha = tema.fecha;
}
});
document.getElementById(`stats-${categoria}`).innerHTML =
`${numTemas} ${numTemas === 1 ? ‘tema’ : ‘temas’} | Último: ${ultimaFecha !== “nunca” ? ultimaFecha : “sin temas”}`;
})
.catch(handleFirebaseError);
});
}
// Funciones para la navegación
function mostrarTemas(categoria) {
categoriaActual = categoria;
document.getElementById(“vista-principal”).style.display = “none”;
document.getElementById(“vista-temas”).style.display = “block”;
document.getElementById(“vista-tema”).style.display = “none”;
document.getElementById(“vista-nuevo-tema”).style.display = “none”;
// Actualizar el título de la categoría
const nombresCategorias = {
‘gramatica’: ‘Gramática’,
‘vocabulario’: ‘Vocabulario’,
‘escritura’: ‘Escritura Creativa’,
‘oral’: ‘Expresión Oral’,
‘dudas’: ‘Dudas y Consultas’,
‘recursos’: ‘Recursos y Materiales’
};
document.getElementById(“categoria-actual”).textContent = “Temas de ” + nombresCategorias[categoria];
// Obtener temas de Firebase
const temasContainer = document.querySelector(“.temas”);
temasContainer.innerHTML = ‘
‘;
const temasRef = database.ref(‘temas’).orderByChild(‘categoria’).equalTo(categoria);
temasRef.once(‘value’)
.then(snapshot => {
temasContainer.innerHTML = “”;
if (!snapshot.exists()) {
temasContainer.innerHTML = “
No hay temas en esta categoría. ¡Sé el primero en crear uno!
“;
return;
}
// Convertir los datos en un array para ordenarlos
const temas = [];
snapshot.forEach(childSnapshot => {
const tema = childSnapshot.val();
tema.id = childSnapshot.key;
temas.push(tema);
});
// Ordenar por fecha (más reciente primero)
temas.sort((a, b) => new Date(b.timestamp) – new Date(a.timestamp));
temas.forEach(tema => {
const temaEl = document.createElement(“div”);
temaEl.className = “tema”;
// Contar respuestas
let numRespuestas = 0;
if (tema.respuestas) {
numRespuestas = Object.keys(tema.respuestas).length;
}
temaEl.innerHTML = `
`;
temasContainer.appendChild(temaEl);
});
})
.catch(handleFirebaseError);
}
function verTema(id) {
temaActualId = id;
document.getElementById(“vista-principal”).style.display = “none”;
document.getElementById(“vista-temas”).style.display = “none”;
document.getElementById(“vista-tema”).style.display = “block”;
document.getElementById(“vista-nuevo-tema”).style.display = “none”;
// Obtener el tema de Firebase
const temaRef = database.ref(‘temas/’ + id);
temaRef.once(‘value’)
.then(snapshot => {
if (snapshot.exists()) {
temaActual = snapshot.val();
temaActual.id = snapshot.key;
document.getElementById(“tema-actual-titulo”).textContent = temaActual.titulo;
document.getElementById(“tema-actual-autor”).textContent = temaActual.autor;
document.getElementById(“tema-actual-fecha”).textContent = temaActual.fecha;
document.getElementById(“tema-actual-contenido”).textContent = temaActual.contenido;
// Cargar respuestas
cargarRespuestas(id);
} else {
alert(“El tema no existe o ha sido eliminado.”);
volverATemas();
}
})
.catch(handleFirebaseError);
}
function cargarRespuestas(temaId) {
const respuestasContainer = document.getElementById(“respuestas-lista”);
respuestasContainer.innerHTML = ‘
‘;
const respuestasRef = database.ref(‘temas/’ + temaId + ‘/respuestas’);
respuestasRef.once(‘value’)
.then(snapshot => {
respuestasContainer.innerHTML = “”;
if (!snapshot.exists()) {
respuestasContainer.innerHTML = “
No hay respuestas todavía. ¡Sé el primero en responder!
“;
return;
}
// Convertir los datos en un array para ordenarlos
const respuestas = [];
snapshot.forEach(childSnapshot => {
const respuesta = childSnapshot.val();
respuesta.id = childSnapshot.key;
respuestas.push(respuesta);
});
// Ordenar por fecha (más antigua primero)
respuestas.sort((a, b) => new Date(a.timestamp) – new Date(b.timestamp));
respuestas.forEach(respuesta => {
const respuestaEl = document.createElement(“div”);
respuestaEl.className = “respuesta”;
respuestaEl.innerHTML = `
`;
respuestasContainer.appendChild(respuestaEl);
});
})
.catch(handleFirebaseError);
}
function volverACategorias() {
document.getElementById(“vista-principal”).style.display = “block”;
document.getElementById(“vista-temas”).style.display = “none”;
document.getElementById(“vista-tema”).style.display = “none”;
document.getElementById(“vista-nuevo-tema”).style.display = “none”;
// Actualizar estadísticas
cargarEstadisticas();
categoriaActual = “”;
temaActualId = null;
temaActual = null;
}
function volverATemas() {
mostrarTemas(categoriaActual);
temaActualId = null;
temaActual = null;
}
function mostrarNuevoTema() {
document.getElementById(“vista-principal”).style.display = “none”;
document.getElementById(“vista-temas”).style.display = “none”;
document.getElementById(“vista-tema”).style.display = “none”;
document.getElementById(“vista-nuevo-tema”).style.display = “block”;
// Preseleccionar la categoría actual si estamos viendo temas
if (categoriaActual) {
document.getElementById(“tema-categoria”).value = categoriaActual;
}
}
// Funciones para crear contenido
function publicarTema() {
const nombre = document.getElementById(“tema-nombre”).value.trim();
const categoria = document.getElementById(“tema-categoria”).value;
const titulo = document.getElementById(“tema-titulo”).value.trim();
const contenido = document.getElementById(“tema-contenido”).value.trim();
if (!nombre || !titulo || !contenido) {
alert(“Por favor, completa todos los campos.”);
return;
}
// Mostrar mensaje de progreso
const btnPublicar = document.getElementById(“btn-publicar-tema”);
const textoOriginal = btnPublicar.textContent;
btnPublicar.textContent = “Publicando…”;
btnPublicar.disabled = true;
const fecha = obtenerFechaFormateada();
const timestamp = Date.now();
console.log(“Intentando publicar tema:”, {
titulo, autor: nombre, categoria, contenido, fecha, timestamp
});
// Crear una referencia para el nuevo tema
const nuevoTemaRef = database.ref(‘temas’).push();
// Guardar datos del tema
nuevoTemaRef.set({
titulo: titulo,
autor: nombre,
fecha: fecha,
timestamp: timestamp,
contenido: contenido,
categoria: categoria
})
.then(() => {
console.log(“Tema publicado exitosamente”);
// Limpiamos el formulario
document.getElementById(“tema-nombre”).value = “”;
document.getElementById(“tema-titulo”).value = “”;
document.getElementById(“tema-contenido”).value = “”;
// Restaurar botón
btnPublicar.textContent = textoOriginal;
btnPublicar.disabled = false;
// Mostramos la nueva lista de temas
mostrarTemas(categoria);
})
.catch(error => {
console.error(“Error al publicar tema:”, error);
alert(“Error al publicar el tema: ” + error.message);
// Restaurar botón
btnPublicar.textContent = textoOriginal;
btnPublicar.disabled = false;
});
}
function publicarRespuesta() {
if (!temaActualId) {
alert(“Error: No se ha seleccionado un tema.”);
return;
}
const nombre = document.getElementById(“respuesta-nombre”).value.trim();
const contenido = document.getElementById(“respuesta-contenido”).value.trim();
if (!nombre || !contenido) {
alert(“Por favor, completa todos los campos.”);
return;
}
const fecha = obtenerFechaFormateada();
const timestamp = Date.now();
console.log(“Intentando publicar respuesta en tema:”, temaActualId);
// Crear una referencia para la nueva respuesta
const nuevaRespuestaRef = database.ref(‘temas/’ + temaActualId + ‘/respuestas’).push();
// Guardar datos de la respuesta
nuevaRespuestaRef.set({
autor: nombre,
fecha: fecha,
timestamp: timestamp,
contenido: contenido
})
.then(() => {
console.log(“Respuesta publicada exitosamente”);
// Limpiamos el formulario
document.getElementById(“respuesta-nombre”).value = “”;
document.getElementById(“respuesta-contenido”).value = “”;
// Actualizamos la vista
cargarRespuestas(temaActualId);
})
.catch(handleFirebaseError);
}
// Inicialización y eventos
document.addEventListener(“DOMContentLoaded”, function() {
// Inicializar estadísticas
cargarEstadisticas();
// Conectar el botón de publicar tema (usando addEventListener en lugar de onclick)
document.getElementById(“btn-publicar-tema”).addEventListener(“click”, publicarTema);
// Hacer globales las funciones necesarias
window.mostrarTemas = mostrarTemas;
window.verTema = verTema;
window.volverACategorias = volverACategorias;
window.volverATemas = volverATemas;
window.mostrarNuevoTema = mostrarNuevoTema;
window.publicarRespuesta = publicarRespuesta;
// Registrar versión para depuración
console.log(“Foro de Aplenguas inicializado correctamente – v1.0.2”);
});