// Variables globales para el modal de rechazo
let currentPetitionId = null;
let currentPetitionText = '';
let currentPetitionType = '';
// Variables globales para pestañas
const approvedContainer = document.getElementById('approvedContainer');
// Función para cambiar entre pestañas
window.switchTab = function(tabName) {
// Remover clase active de todos los botones y contenidos
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
// Activar pestaña seleccionada
if (tabName === 'pending') {
document.querySelector('.tab-btn[onclick="switchTab(\'pending\')"]').classList.add('active');
document.getElementById('petitionsContainer').classList.add('active');
} else if (tabName === 'approved') {
document.querySelector('.tab-btn[onclick="switchTab(\'approved\')"]').classList.add('active');
document.getElementById('approvedContainer').classList.add('active');
loadApprovedPetitions();
}
}
// Función para cargar peticiones aprobadas con comentarios y oraciones
function loadApprovedPetitions() {
approvedContainer.innerHTML = '
Cargando peticiones aprobadas...
';
try {
const q = query(collection(db, 'peticiones'), where('status', '==', 'aprobada'));
onSnapshot(q, async (snapshot) => {
approvedContainer.innerHTML = '';
if (snapshot.empty) {
approvedContainer.innerHTML = '
No hay peticiones aprobadas.
';
return;
}
for (const docSnap of snapshot.docs) {
const pet = docSnap.data();
const docId = docSnap.id;
const div = document.createElement('div');
div.className = 'petition-card';
div.setAttribute('data-petition-id', docId);
// Cargar comentarios y oraciones
const commentsSnapshot = await getDocs(query(collection(db, 'comentarios'), where('petitionId', '==', docId)));
const prayersSnapshot = await getDocs(query(collection(db, 'oraciones'), where('petitionId', '==', docId)));
let contentHtml = '';
// Mostrar comentarios generales de la petición
if (!commentsSnapshot.empty) {
contentHtml += '';
}
// Mostrar oraciones
if (!prayersSnapshot.empty) {
contentHtml += '
';
contentHtml += '
Oraciones:
';
prayersSnapshot.forEach(prayerDoc => {
const prayer = prayerDoc.data();
const prayerDate = prayer.timestamp ? new Date(prayer.timestamp.seconds * 1000).toLocaleString() : 'Fecha no
disponible';
contentHtml += `
Por: ${prayer.author || prayer.nombre || 'Anónimo'} - ${prayerDate}
${prayer.text || prayer.texto}
`;
});
contentHtml += '
';
}
div.innerHTML = `
${pet.requestText}
${contentHtml}
`;
div.onclick = function(event) {
if (!event.target.closest('button')) {
openPetitionModal(docId, pet);
}
};
approvedContainer.appendChild(div);
}
}, (error) => {
console.error('Error al cargar peticiones aprobadas:', error);
approvedContainer.innerHTML = '
Error al cargar peticiones aprobadas.
';
});
} catch (error) {
console.error('Error en loadApprovedPetitions:', error);
approvedContainer.innerHTML = '
Error al configurar la consulta de peticiones aprobadas.
';
}
}
// Funciones para manejar modales de rechazo
window.openRejectModal = function(petitionId, petitionText, petitionType) {
currentPetitionId = petitionId;
currentPetitionText = petitionText;
currentPetitionType = petitionType;
document.getElementById('previewText').textContent = petitionText;
document.getElementById('rejectionReason').value = '';
document.getElementById('rejectModal').style.display = 'block';
}
window.closeRejectModal = function() {
document.getElementById('rejectModal').style.display = 'none';
currentPetitionId = null;
currentPetitionText = '';
currentPetitionType = '';
}
window.showConfirmation = function() {
const reason = document.getElementById('rejectionReason').value.trim();
const displayReason = reason || 'Sin motivo especificado';
document.getElementById('confirmPetitionText').textContent = currentPetitionText;
document.getElementById('confirmReason').textContent = displayReason;
document.getElementById('rejectModal').style.display = 'none';
document.getElementById('confirmModal').style.display = 'block';
}
window.closeConfirmModal = function() {
document.getElementById('confirmModal').style.display = 'none';
document.getElementById('rejectModal').style.display = 'block';
}
window.editReason = function() {
document.getElementById('confirmModal').style.display = 'none';
document.getElementById('rejectModal').style.display = 'block';
document.getElementById('rejectionReason').focus();
}
window.confirmReject = async function() {
if (!currentPetitionId) return;
const reason = document.getElementById('rejectionReason').value.trim();
try {
// Obtener datos de la petición para la notificación
const petitionDoc = await getDoc(doc(db, 'peticiones', currentPetitionId));
const petitionData = petitionDoc.data();
await updateDoc(doc(db, 'peticiones', currentPetitionId), {
status: 'rechazada',
moderatedBy: auth.currentUser.uid,
moderatedAt: new Date(),
rejectionReason: reason || ''
});
await logModeratorAction('reject', currentPetitionId, `Petición de tipo: ${currentPetitionType}. Motivo: ${reason
|| 'Sin motivo especificado'}`);
// Crear notificación para el usuario
if (petitionData && petitionData.userId) {
await createStatusChangeNotification(petitionData.userId, currentPetitionId, 'rechazada',
currentPetitionText.substring(0, 50) + '...');
}
showNotification(`Petición ${currentPetitionId} rechazada correctamente.`);
// Cerrar modal
document.getElementById('confirmModal').style.display = 'none';
currentPetitionId = null;
currentPetitionText = '';
currentPetitionType = '';
} catch (error) {
console.error('Error al rechazar petición:', error);
alert('Error al rechazar la petición. Intenta de nuevo.');
}
}
// Función para mostrar/ocultar comentarios
window.toggleComments = function(prayerId) {
const commentsList = document.getElementById(`comments-${prayerId}`);
const toggleBtn = commentsList.previousElementSibling;
if (commentsList.style.display === 'none') {
commentsList.style.display = 'block';
toggleBtn.innerHTML = toggleBtn.innerHTML.replace('Ver comentarios', 'Ocultar comentarios');
} else {
commentsList.style.display = 'none';
toggleBtn.innerHTML = toggleBtn.innerHTML.replace('Ocultar comentarios', 'Ver comentarios');
}
}
// Función para mostrar/ocultar comentarios de peticiones
window.togglePetitionComments = async function(petitionId) {
const petitionCard = document.querySelector(`[data-petition-id="${petitionId}"]`);
if (!petitionCard) return;
let commentsSection = petitionCard.querySelector('.petition-comments-section');
const toggleBtn = petitionCard.querySelector('.approve-btn');
if (!commentsSection) {
// Crear la sección de comentarios si no existe
commentsSection = document.createElement('div');
commentsSection.className = 'petition-comments-section';
commentsSection.style.display = 'none';
try {
// Cargar comentarios y oraciones
const commentsSnapshot = await getDocs(query(collection(db, 'comentarios'), where('petitionId', '==',
petitionId)));
const prayersSnapshot = await getDocs(query(collection(db, 'oraciones'), where('petitionId', '==', petitionId)));
let commentsHtml = '';
commentsSection.innerHTML = commentsHtml;
// Insertar después del btn-group
const btnGroup = petitionCard.querySelector('.btn-group');
btnGroup.parentNode.insertBefore(commentsSection, btnGroup.nextSibling);
} catch (error) {
console.error('Error al cargar comentarios:', error);
commentsSection.innerHTML = '
Error al cargar comentarios.
';
}
}
// Toggle visibility
if (commentsSection.style.display === 'none') {
commentsSection.style.display = 'block';
toggleBtn.innerHTML = ' Ocultar Comentarios';
} else {
commentsSection.style.display = 'none';
toggleBtn.innerHTML = ' Ver Comentarios';
}
}
// Variables para el modal de eliminación
let currentDeleteType = '';
let currentDeleteId = '';
let currentDeletePetitionId = '';
let currentDeleteText = '';
// Funciones para el modal de eliminación
window.openDeleteModal = function(type, elementId, petitionId) {
currentDeleteType = type;
currentDeleteId = elementId;
currentDeletePetitionId = petitionId || elementId;
// Obtener el texto del elemento para mostrarlo en el modal
const elementText = getElementText(type, elementId);
currentDeleteText = elementText;
let elementTypeText = '';
if (type === 'comment') elementTypeText = 'Comentario a eliminar:';
else if (type === 'prayer') elementTypeText = 'Oración a eliminar:';
else if (type === 'petition') elementTypeText = 'Petición a eliminar:';
document.getElementById('deleteElementType').textContent = elementTypeText;
document.getElementById('deletePreviewText').textContent = elementText;
document.getElementById('deleteReason').value = '';
document.getElementById('deleteModal').style.display = 'block';
}
window.closeDeleteModal = function() {
document.getElementById('deleteModal').style.display = 'none';
currentDeleteType = '';
currentDeleteId = '';
currentDeletePetitionId = '';
currentDeleteText = '';
}
window.confirmDelete = async function() {
const reason = document.getElementById('deleteReason').value.trim();
if (!reason) {
alert('Por favor, proporciona un motivo para la eliminación.');
return;
}
try {
let collection_name;
if (currentDeleteType === 'comment') collection_name = 'comentarios';
else if (currentDeleteType === 'prayer') collection_name = 'oraciones';
else if (currentDeleteType === 'petition') collection_name = 'peticiones';
await deleteDoc(doc(db, collection_name, currentDeleteId));
// Registrar la acción con el motivo
let actionType;
if (currentDeleteType === 'comment') actionType = 'delete_comment';
else if (currentDeleteType === 'prayer') actionType = 'delete_prayer';
else if (currentDeleteType === 'petition') actionType = 'delete_petition';
await logModeratorAction(actionType, currentDeletePetitionId, `${currentDeleteType.charAt(0).toUpperCase() +
currentDeleteType.slice(1)} eliminado: ${currentDeleteId}. Motivo: ${reason}`);
// Crear notificación para el usuario afectado
await createUserNotification(currentDeleteType, currentDeleteId, reason);
let elementType = currentDeleteType === 'comment' ? 'Comentario' : currentDeleteType === 'prayer' ? 'Oración' :
'Petición';
showNotification(`${elementType} eliminado correctamente.`);
closeDeleteModal();
loadApprovedPetitions();
} catch (error) {
console.error(`Error al eliminar ${currentDeleteType}:`, error);
alert(`Error al eliminar el ${currentDeleteType === 'comment' ? 'comentario' : 'oración'}. Intenta de nuevo.`);
}
}
// Función auxiliar para obtener el texto del elemento
function getElementText(type, elementId) {
if (type === 'petition') {
const cards = document.querySelectorAll('.petition-card');
for (let card of cards) {
const button = card.querySelector(`[onclick*="'${elementId}'"]`);
if (button) {
const text = card.querySelector('.petition-text');
return text ? text.textContent.substring(0, 100) + '...' : 'Texto no disponible';
}
}
} else {
const elements = document.querySelectorAll(type === 'comment' ? '.comment-item' : '.prayer-item');
for (let element of elements) {
const button = element.querySelector(`[onclick*="'${elementId}'"]`);
if (button) {
const content = element.querySelector(type === 'comment' ? '.comment-content' : '.prayer-content');
if (content) {
const textDiv = content.querySelector('div:last-child');
return textDiv ? textDiv.textContent.substring(0, 100) + '...' : 'Texto no disponible';
}
}
}
}
return 'Texto no disponible';
}
// Función para crear notificación al usuario
async function createUserNotification(type, elementId, reason) {
try {
// Obtener información del elemento eliminado para encontrar al autor
let collection_name;
if (type === 'comment') collection_name = 'comentarios';
else if (type === 'prayer') collection_name = 'oraciones';
else if (type === 'petition') collection_name = 'peticiones';
const elementDoc = await getDoc(doc(db, collection_name, elementId));
if (elementDoc.exists()) {
const elementData = elementDoc.data();
const authorUID = elementData.authorUID || elementData.uid;
if (authorUID) {
await addDoc(collection(db, 'user_notifications'), {
userUID: authorUID,
type: 'deletion',
elementType: type,
reason: reason,
deletedAt: new Date(),
read: false,
createdAt: serverTimestamp()
});
}
}
} catch (error) {
console.error('Error al crear notificación de usuario:', error);
}
}
// Función para verificar notificaciones del usuario
async function checkUserNotifications() {
try {
const user = auth.currentUser;
if (!user) return;
const notificationsQuery = query(
collection(db, 'user_notifications'),
where('userUID', '==', user.uid),
where('read', '==', false)
);
const snapshot = await getDocs(notificationsQuery);
const unreadCount = snapshot.size;
const badge = document.getElementById('notification-badge');
if (unreadCount > 0) {
badge.textContent = unreadCount;
badge.style.display = 'flex';
} else {
badge.style.display = 'none';
}
} catch (error) {
console.error('Error al verificar notificaciones:', error);
}
}
// Verificar notificaciones al cargar la página y cada 30 segundos
onAuthStateChanged(auth, (user) => {
if (user) {
checkUserNotifications();
setInterval(checkUserNotifications, 30000); // Verificar cada 30 segundos
}
});
// Funciones para el modal de detalles de petición
window.openPetitionModal = async function(petitionId, petitionData) {
try {
const modal = document.getElementById('petitionModal');
const detailsContainer = document.getElementById('petitionDetails');
// Cargar comentarios y oraciones
const commentsSnapshot = await getDocs(query(collection(db, 'comentarios'), where('petitionId', '==',
petitionId)));
const prayersSnapshot = await getDocs(query(collection(db, 'oraciones'), where('petitionId', '==', petitionId)));
const reactionsSnapshot = await getDocs(query(collection(db, 'reacciones'), where('petitionId', '==',
petitionId)));
let detailsHtml = `
${petitionData.requestType}
${petitionData.requestText}
${petitionData.createdAt ? new Date(petitionData.createdAt.seconds *
1000).toLocaleString() : 'Fecha no disponible'}
${petitionData.nombre || 'Anónimo'}
`;
// Mostrar reacciones
if (!reactionsSnapshot.empty) {
const reactionCounts = {};
reactionsSnapshot.forEach(doc => {
const reaction = doc.data();
reactionCounts[reaction.type] = (reactionCounts[reaction.type] || 0) + 1;
});
detailsHtml += '
';
detailsHtml += '
Reacciones:
';
for (const [type, count] of Object.entries(reactionCounts)) {
const emoji = type === 'like' ? '👍' : type === 'love' ? '❤️' : type === 'pray' ? '🙏' : '😢';
detailsHtml += `${emoji} ${count}`;
}
detailsHtml += '';
}
// Mostrar comentarios
if (!commentsSnapshot.empty) {
detailsHtml += '';
}
// Mostrar oraciones
if (!prayersSnapshot.empty) {
detailsHtml += '
';
detailsHtml += `
Oraciones (${prayersSnapshot.size}):
`;
prayersSnapshot.forEach(prayerDoc => {
const prayer = prayerDoc.data();
const prayerDate = prayer.timestamp ? new Date(prayer.timestamp.seconds * 1000).toLocaleString() : 'Fecha no
disponible';
detailsHtml += `
${prayer.text || prayer.texto}
`;
});
detailsHtml += '
';
}
// Botón para eliminar la petición completa
detailsHtml += `
`;
detailsContainer.innerHTML = detailsHtml;
modal.style.display = 'block';
} catch (error) {
console.error('Error al cargar detalles de la petición:', error);
alert('Error al cargar los detalles de la petición.');
}
}
window.closePetitionModal = function() {
document.getElementById('petitionModal').style.display = 'none';
}
// Funciones para eliminar peticiones aprobadas
window.openDeletePetitionModal = function(petitionId, petitionText, petitionType) {
currentDeleteId = petitionId;
currentDeleteType = 'petition';
const modal = document.getElementById('deleteModal');
const preview = document.getElementById('deletePreview');
preview.innerHTML = `
`;
modal.style.display = 'block';
}
window.confirmDeletePetition = async function() {
const reason = document.getElementById('deleteReason').value.trim();
if (!reason) {
alert('Por favor, proporciona una razón para la eliminación.');
return;
}
try {
// Eliminar la petición
await deleteDoc(doc(db, 'peticiones', currentDeleteId));
// Eliminar comentarios relacionados
const commentsQuery = query(collection(db, 'comentarios'), where('petitionId', '==', currentDeleteId));
const commentsSnapshot = await getDocs(commentsQuery);
const commentDeletePromises = commentsSnapshot.docs.map(commentDoc => deleteDoc(commentDoc.ref));
await Promise.all(commentDeletePromises);
// Eliminar oraciones relacionadas
const prayersQuery = query(collection(db, 'oraciones'), where('petitionId', '==', currentDeleteId));
const prayersSnapshot = await getDocs(prayersQuery);
const prayerDeletePromises = prayersSnapshot.docs.map(prayerDoc => deleteDoc(prayerDoc.ref));
await Promise.all(prayerDeletePromises);
// Eliminar reacciones relacionadas
const reactionsQuery = query(collection(db, 'reacciones'), where('petitionId', '==', currentDeleteId));
const reactionsSnapshot = await getDocs(reactionsQuery);
const reactionDeletePromises = reactionsSnapshot.docs.map(reactionDoc => deleteDoc(reactionDoc.ref));
await Promise.all(reactionDeletePromises);
// Crear notificación para el usuario
await createUserNotification(currentDeleteId, 'petition', reason);
// Registrar en el log de moderación
await addDoc(collection(db, 'moderation_log'), {
action: 'delete_petition',
petitionId: currentDeleteId,
moderatorUID: auth.currentUser.uid,
reason: reason,
timestamp: serverTimestamp()
});
});
Comentarios de la petición