85 lines
3.6 KiB
JavaScript

let allJourneys = [];
// ==================== LOAD JOURNEYS ====================
async function loadJourneys() {
try {
const res = await fetch(`${API_BASE}/journeys`, { credentials: 'include' });
if (!res.ok) throw new Error('Failed to fetch journeys');
const journeys = await res.json();
allJourneys = journeys;
renderJourneys(journeys);
} catch (err) {
console.error(err);
document.getElementById('posts-grid').innerHTML = '<p class="empty-state">Failed to load journeys. Make sure the backend is running.</p>';
}
}
function renderJourneys(journeys) {
const container = document.getElementById('posts-grid');
if (!journeys.length) {
container.innerHTML = `
<div class="empty-state">
<p>No journeys yet. Create one on the map!</p>
</div>
`;
return;
}
container.innerHTML = journeys.map(journey => {
const imageUrl = sanitizeDisplayUrl(journey.image || '');
return `
<article class="post-card">
${imageUrl ? `<img class="post-card-image" src="${escapeAttribute(imageUrl)}" alt="${escapeAttribute(journey.title)}">` : '<div class="post-card-image" style="background: var(--surface-3); display: flex; align-items: center; justify-content: center;"><i class="fas fa-image" style="font-size: 3rem; color: var(--gray-5);"></i></div>'}
<div class="post-card-content">
<h2 class="post-card-title"><a href="blog-post.html?id=${encodeURIComponent(journey.id)}">${escapeHtml(journey.title)}</a></h2>
<div class="post-card-meta">
<i class="fas fa-calendar-alt"></i> ${new Date(journey.created_at).toLocaleDateString()}
${journey.markers ? `<span style="margin-left: 12px;"><i class="fas fa-map-marker-alt"></i> ${journey.markers.length} chapters</span>` : ''}
${getJourneyBadges(journey)}
</div>
<div class="post-card-excerpt">${escapeHtml(journey.description || journey.markers?.[0]?.text?.substring(0, 150) + '…')}</div>
</div>
</article>
`;
}).join('');
}
function getJourneyBadges(journey) {
const badges = [];
const isOwner = journey.owner_id === currentUser?.id;
const isShared = journey.visibility === 'shared' && !isOwner;
if (journey.visibility === 'public') badges.push('Public');
if (isShared) badges.push(journey.can_edit ? 'Shared edit' : 'Shared');
return badges.map((badge) => `<span class="badge">${badge}</span>`).join('');
}
function filterJourneys(filter) {
if (filter === 'all') {
renderJourneys(allJourneys);
} else if (filter === 'own') {
renderJourneys(allJourneys.filter(j => j.owner_id === currentUser?.id));
} else if (filter === 'shared') {
renderJourneys(allJourneys.filter(j => j.owner_id !== currentUser?.id && j.visibility === 'shared'));
} else if (filter === 'public') {
renderJourneys(allJourneys.filter(j => j.visibility === 'public'));
}
}
// ==================== INITIALIZATION ====================
document.addEventListener('DOMContentLoaded', async () => {
const authenticated = await checkAuthAndRedirect();
if (!authenticated) return;
updateUserMenu();
loadJourneys();
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
filterJourneys(btn.dataset.filter);
});
});
});