mirror of
https://codeberg.org/likwid/likwid.git
synced 2026-02-09 21:13:09 +00:00
ux: improve community plugins states
This commit is contained in:
parent
e084c0d235
commit
c8f7150fac
1 changed files with 99 additions and 8 deletions
|
|
@ -28,8 +28,68 @@ const { slug } = Astro.params;
|
||||||
<script define:vars={{ slug, apiBase }}>
|
<script define:vars={{ slug, apiBase }}>
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
if (!token) {
|
function renderLoginRequiredState() {
|
||||||
window.location.href = '/login';
|
const container = document.getElementById('plugins-content');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="state-card ui-card">
|
||||||
|
<p class="empty">Login required.</p>
|
||||||
|
<p class="hint">Sign in to manage community plugins.</p>
|
||||||
|
<div class="state-actions">
|
||||||
|
<a class="ui-btn ui-btn-primary" href="/login">Login</a>
|
||||||
|
<a class="ui-btn ui-btn-secondary" href="/communities/${encodeURIComponent(String(slug || ''))}">Back to community</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNotFoundState() {
|
||||||
|
const container = document.getElementById('plugins-content');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="state-card ui-card">
|
||||||
|
<p class="error">Community not found.</p>
|
||||||
|
<p class="hint">It may have been deleted, or the link is incorrect.</p>
|
||||||
|
<div class="state-actions">
|
||||||
|
<a class="ui-btn ui-btn-primary" href="/communities">Back to communities</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderForbiddenState(communityName) {
|
||||||
|
const container = document.getElementById('plugins-content');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="state-card ui-card">
|
||||||
|
<p class="error">Not allowed.</p>
|
||||||
|
<p class="hint">You must be an admin or moderator to manage plugins for ${escapeHtml(communityName)}.</p>
|
||||||
|
<div class="state-actions">
|
||||||
|
<a class="ui-btn ui-btn-primary" href="/communities/${encodeURIComponent(String(slug || ''))}">Back to community</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPluginsErrorState(message) {
|
||||||
|
const container = document.getElementById('plugins-content');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="state-card ui-card">
|
||||||
|
<p class="error">${escapeHtml(message || 'Failed to load plugins.')}</p>
|
||||||
|
<p class="hint">Check your connection and try again.</p>
|
||||||
|
<div class="state-actions">
|
||||||
|
<button type="button" class="ui-btn ui-btn-primary" id="retry-plugins">Retry</button>
|
||||||
|
<a class="ui-btn ui-btn-secondary" href="/communities/${encodeURIComponent(String(slug || ''))}">Back to community</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById('retry-plugins')?.addEventListener('click', load);
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(str) {
|
function escapeHtml(str) {
|
||||||
|
|
@ -154,12 +214,23 @@ const { slug } = Astro.params;
|
||||||
const allowed = membership?.role === 'admin' || membership?.role === 'moderator';
|
const allowed = membership?.role === 'admin' || membership?.role === 'moderator';
|
||||||
|
|
||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
|
renderForbiddenState(community?.name || 'this community');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plugins || plugins.length === 0) {
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<div class="error">
|
<div class="state-card ui-card">
|
||||||
<h2>Forbidden</h2>
|
<p class="empty">No plugins available.</p>
|
||||||
<p>You must be an admin or moderator to manage plugins for ${escapeHtml(community.name)}.</p>
|
<p class="hint">If this seems wrong, try reloading the page.</p>
|
||||||
|
<div class="state-actions">
|
||||||
|
<button type="button" class="ui-btn ui-btn-primary" id="retry-plugins-empty">Retry</button>
|
||||||
|
<a class="ui-btn ui-btn-secondary" href="/communities/${encodeURIComponent(String(slug || ''))}">Back to community</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
document.getElementById('retry-plugins-empty')?.addEventListener('click', load);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,9 +424,14 @@ const { slug } = Astro.params;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!token) {
|
||||||
|
renderLoginRequiredState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const community = await fetchCommunityBySlug();
|
const community = await fetchCommunityBySlug();
|
||||||
if (!community) {
|
if (!community) {
|
||||||
container.innerHTML = '<div class="error">Community not found</div>';
|
renderNotFoundState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -364,7 +440,14 @@ const { slug } = Astro.params;
|
||||||
|
|
||||||
renderPlugins(community, membership, plugins);
|
renderPlugins(community, membership, plugins);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
container.innerHTML = `<div class="error">${escapeHtml(err?.message || 'Failed to load')}</div>`;
|
const msg = err?.message || 'Failed to load plugins.';
|
||||||
|
|
||||||
|
if (String(msg || '').toLowerCase().includes('unauthorized') || String(msg || '').includes('401')) {
|
||||||
|
renderLoginRequiredState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPluginsErrorState(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,13 +561,21 @@ const { slug } = Astro.params;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.plugins-error {
|
||||||
background: var(--color-error-muted);
|
background: var(--color-error-muted);
|
||||||
border: 1px solid var(--color-error);
|
border: 1px solid var(--color-error);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.state-actions {
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-body-wrap {
|
.settings-body-wrap {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue