mirror of
https://codeberg.org/likwid/likwid.git
synced 2026-02-09 21:13:09 +00:00
ui: refresh proposals list page
This commit is contained in:
parent
5937a0fc54
commit
307a482b56
1 changed files with 87 additions and 60 deletions
|
|
@ -5,33 +5,48 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="All Proposals">
|
<Layout title="All Proposals">
|
||||||
<section class="proposals-page">
|
<section class="ui-page">
|
||||||
<div class="header-row">
|
<div class="ui-container">
|
||||||
<div>
|
<div class="hero ui-card ui-card-glass">
|
||||||
<h1>All Proposals</h1>
|
<div class="hero-top">
|
||||||
<p class="subtitle">Browse proposals across all communities</p>
|
<div>
|
||||||
|
<h1 class="hero-title">All Proposals</h1>
|
||||||
|
<p class="hero-subtitle">Browse proposals across all communities</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="filters">
|
<div class="toolbar ui-card">
|
||||||
<input type="text" id="search-input" placeholder="Search proposals..." />
|
<div class="toolbar-grid">
|
||||||
<select id="status-filter">
|
<div>
|
||||||
<option value="">All Statuses</option>
|
<label class="toolbar-label" for="search-input">Search</label>
|
||||||
<option value="draft">Draft</option>
|
<input type="text" id="search-input" class="ui-input" placeholder="Search proposals…" />
|
||||||
<option value="discussion">Discussion</option>
|
</div>
|
||||||
<option value="voting">Voting</option>
|
<div>
|
||||||
<option value="closed">Closed</option>
|
<label class="toolbar-label" for="status-filter">Status</label>
|
||||||
</select>
|
<select id="status-filter" class="ui-select">
|
||||||
<select id="sort-filter">
|
<option value="">All statuses</option>
|
||||||
<option value="newest">Newest First</option>
|
<option value="draft">Draft</option>
|
||||||
<option value="oldest">Oldest First</option>
|
<option value="discussion">Discussion</option>
|
||||||
<option value="most-votes">Most Votes</option>
|
<option value="voting">Voting</option>
|
||||||
<option value="most-comments">Most Comments</option>
|
<option value="closed">Closed</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="toolbar-label" for="sort-filter">Sort</label>
|
||||||
|
<select id="sort-filter" class="ui-select">
|
||||||
|
<option value="newest">Newest first</option>
|
||||||
|
<option value="oldest">Oldest first</option>
|
||||||
|
<option value="most-votes">Most votes</option>
|
||||||
|
<option value="most-comments">Most comments</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="proposals-list" class="list">
|
<div id="proposals-list" class="list">
|
||||||
<p class="loading">Loading proposals...</p>
|
<div class="state-card ui-card"><p class="loading">Loading proposals...</p></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
@ -57,12 +72,12 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
if (proposals.length === 0) {
|
if (proposals.length === 0) {
|
||||||
container.innerHTML = '<div class="empty"><p>No proposals found.</p></div>';
|
container.innerHTML = '<div class="state-card ui-card"><p class="empty">No proposals found.</p></div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
container.innerHTML = proposals.map(p => `
|
container.innerHTML = proposals.map(p => `
|
||||||
<a href="/proposals/${p.id}" class="proposal-card">
|
<a href="/proposals/${p.id}" class="proposal-card ui-card">
|
||||||
<div class="proposal-header">
|
<div class="proposal-header">
|
||||||
<h3>${p.title}</h3>
|
<h3>${p.title}</h3>
|
||||||
<span class="ui-pill status-${p.status}">${p.status}</span>
|
<span class="ui-pill status-${p.status}">${p.status}</span>
|
||||||
|
|
@ -126,43 +141,60 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.proposals-page {
|
.hero {
|
||||||
padding: 2rem 0;
|
padding: 1.25rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-row {
|
.hero-top {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
margin-bottom: 2rem;
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
.hero-title {
|
||||||
font-size: 2.5rem;
|
margin: 0;
|
||||||
margin-bottom: 0.5rem;
|
font-size: 2.125rem;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.hero-subtitle {
|
||||||
|
margin: 0.25rem 0 0;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters {
|
.toolbar {
|
||||||
display: flex;
|
padding: 1rem;
|
||||||
gap: 1rem;
|
margin-bottom: 1rem;
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters input, .filters select {
|
.toolbar-grid {
|
||||||
border-radius: var(--radius-md);
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr 1fr;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters input {
|
.toolbar-label {
|
||||||
flex: 1;
|
display: block;
|
||||||
max-width: 300px;
|
font-size: 0.75rem;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters select {
|
@media (max-width: 768px) {
|
||||||
min-width: 150px;
|
.toolbar-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-card {
|
||||||
|
padding: 2.25rem 1.5rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
|
@ -172,19 +204,17 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
|
|
||||||
.proposal-card {
|
.proposal-card {
|
||||||
display: block;
|
display: block;
|
||||||
background: var(--color-surface);
|
padding: 1.1rem;
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
border-radius: var(--radius-lg);
|
|
||||||
padding: 1.5rem;
|
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
box-shadow: var(--shadow-sm);
|
text-decoration: none;
|
||||||
transition: transform var(--motion-fast) var(--easing-standard), box-shadow var(--motion-fast) var(--easing-standard), border-color var(--motion-fast) var(--easing-standard);
|
transition: transform var(--motion-fast) var(--easing-standard), box-shadow var(--motion-fast) var(--easing-standard), border-color var(--motion-fast) var(--easing-standard), background var(--motion-fast) var(--easing-standard);
|
||||||
}
|
}
|
||||||
|
|
||||||
.proposal-card:hover {
|
.proposal-card:hover {
|
||||||
border-color: var(--color-border-hover);
|
border-color: var(--color-border-hover);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-2px);
|
||||||
box-shadow: var(--shadow-md);
|
box-shadow: var(--shadow-md);
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
.proposal-header {
|
.proposal-header {
|
||||||
|
|
@ -192,10 +222,13 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.proposal-card h3 {
|
.proposal-card h3 {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-draft { background: var(--color-neutral-muted); color: var(--color-on-primary); }
|
.status-draft { background: var(--color-neutral-muted); color: var(--color-on-primary); }
|
||||||
|
|
@ -230,10 +263,4 @@ import { API_BASE as apiBase } from '../lib/api';
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading, .empty, .error {
|
|
||||||
text-align: center;
|
|
||||||
padding: 3rem;
|
|
||||||
color: var(--color-text-muted);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue