frontend: improve onboarding empty states

This commit is contained in:
Marco Allegretti 2026-02-12 17:59:35 +01:00
parent 8c794432a3
commit 070257597e
3 changed files with 37 additions and 9 deletions

View file

@ -56,6 +56,7 @@ import { API_BASE as apiBase } from '../lib/api';
var allCommunities = []; var allCommunities = [];
var currentQuery = ''; var currentQuery = '';
var currentSort = 'name_asc'; var currentSort = 'name_asc';
var token = localStorage.getItem('token');
function escapeHtml(value) { function escapeHtml(value) {
return String(value || '').replace(/[&<>\"']/g, function(ch) { return String(value || '').replace(/[&<>\"']/g, function(ch) {
@ -122,8 +123,18 @@ import { API_BASE as apiBase } from '../lib/api';
var container = document.getElementById('communities-list'); var container = document.getElementById('communities-list');
if (!container) return; if (!container) return;
var label = isFiltered ? 'No communities match your search.' : 'No communities found.'; var isLoggedIn = !!token;
var hint = isFiltered ? 'Try a different keyword or clear the search.' : 'Please try again later.'; var label;
var hint;
if (isFiltered) {
label = 'No communities match your search.';
hint = 'Try a different keyword or clear the search.';
} else {
label = isLoggedIn ? 'No communities yet.' : 'No communities found.';
hint = isLoggedIn
? 'Create the first community to start organizing proposals.'
: 'Sign in to create a community, or refresh to try again.';
}
container.innerHTML = container.innerHTML =
'<div class="state-card ui-card">' + '<div class="state-card ui-card">' +
@ -131,6 +142,8 @@ import { API_BASE as apiBase } from '../lib/api';
'<p class="hint">' + hint + '</p>' + '<p class="hint">' + hint + '</p>' +
'<div class="state-actions">' + '<div class="state-actions">' +
(isFiltered ? '<button type="button" class="ui-btn ui-btn-secondary" id="reset-community-search">Reset search</button>' : '') + (isFiltered ? '<button type="button" class="ui-btn ui-btn-secondary" id="reset-community-search">Reset search</button>' : '') +
(!isFiltered && isLoggedIn ? '<a class="ui-btn ui-btn-primary" href="/communities/new">Create Community</a>' : '') +
(!isFiltered && !isLoggedIn ? '<a class="ui-btn ui-btn-secondary" href="/login">Sign In</a>' : '') +
'<a class="ui-btn ui-btn-primary" href="/communities">Refresh</a>' + '<a class="ui-btn ui-btn-primary" href="/communities">Refresh</a>' +
'</div>' + '</div>' +
'</div>'; '</div>';
@ -265,7 +278,6 @@ import { API_BASE as apiBase } from '../lib/api';
} }
// Show create button if logged in // Show create button if logged in
var token = localStorage.getItem('token');
var createBtn = document.getElementById('create-btn'); var createBtn = document.getElementById('create-btn');
if (token && createBtn) { if (token && createBtn) {
createBtn.style.display = 'block'; createBtn.style.display = 'block';

View file

@ -72,7 +72,7 @@ const { slug } = Astro.params;
</div> </div>
</div> </div>
<div id="proposals-list" class="list"> <div id="proposals-list" class="list" aria-live="polite">
<div class="list-skeleton"> <div class="list-skeleton">
<div class="skeleton-card"></div> <div class="skeleton-card"></div>
<div class="skeleton-card"></div> <div class="skeleton-card"></div>
@ -154,7 +154,18 @@ const { slug } = Astro.params;
if (!container) return; if (!container) return;
if (proposals.length === 0) { if (proposals.length === 0) {
container.innerHTML = '<div class="ui-card"><p class="empty">No proposals found.</p></div>'; const token = localStorage.getItem('token');
const isLoggedIn = !!token;
container.innerHTML = `
<div class="state-card ui-card">
<p class="empty">No proposals yet.</p>
<p class="hint">Create the first proposal for this community to start collecting feedback and votes.</p>
<div class="state-actions">
${isLoggedIn ? `<a class="ui-btn ui-btn-primary" href="/communities/${encodeURIComponent(String(slug))}/proposals/new">+ New Proposal</a>` : '<a class="ui-btn ui-btn-secondary" href="/login">Sign In</a>'}
<a class="ui-btn ui-btn-secondary" href="/communities/${encodeURIComponent(String(slug))}">Back to community</a>
</div>
</div>
`;
return; return;
} }

View file

@ -100,13 +100,18 @@ import { API_BASE as apiBase } from '../lib/api';
const container = document.getElementById('proposals-list'); const container = document.getElementById('proposals-list');
if (!container) return; if (!container) return;
const label = isFiltered ? 'No proposals match your filters.' : 'No proposals yet.';
const hint = isFiltered
? 'Try adjusting search, status, or sort.'
: 'To create one, open a community and click New Proposal.';
container.innerHTML = ` container.innerHTML = `
<div class="state-card ui-card"> <div class="state-card ui-card">
<p class="empty">${isFiltered ? 'No proposals match your filters.' : 'No proposals found.'}</p> <p class="empty">${label}</p>
<p class="hint">Try adjusting search, status, or sort.</p> <p class="hint">${hint}</p>
<div class="state-actions"> <div class="state-actions">
<button type="button" class="ui-btn ui-btn-secondary" id="reset-filters">Reset filters</button> ${isFiltered ? '<button type="button" class="ui-btn ui-btn-secondary" id="reset-filters">Reset filters</button>' : ''}
<a class="ui-btn ui-btn-primary" href="/communities">Go to communities</a> <a class="ui-btn ui-btn-primary" href="/communities">Browse communities</a>
</div> </div>
</div> </div>
`; `;