82 lines
3.5 KiB
JavaScript
82 lines
3.5 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 => `
|
|
<article class="post-card">
|
|
${journey.image ? `<img class="post-card-image" src="${journey.image}" alt="${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=${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);
|
|
});
|
|
});
|
|
});
|