Ideas: add 'won't implement' status with decline/reopen button

This commit is contained in:
Davide Scaini
2026-05-15 08:36:31 +02:00
parent c905449114
commit 15e9969ca2
2 changed files with 88 additions and 15 deletions
+65 -14
View File
@@ -181,7 +181,23 @@
}
function statusOrder(s: string | undefined) {
return s === 'awaiting' ? 0 : s === 'done' ? 2 : 1;
return s === 'awaiting' ? 0 : s === 'done' ? 2 : s === 'declined' ? 3 : 1;
}
async function declineIdea(idea: Idea) {
const r = await fetch(`/api/ideas/${idea.id}/decline`, {
method: 'POST',
credentials: 'include',
});
if (r.ok) {
const d = await r.json();
idea.status = d.status;
ideas = [...ideas].sort((a, b) =>
statusOrder(a.status) - statusOrder(b.status) ||
b.vote_count - a.vote_count ||
b.created_at - a.created_at
);
}
}
async function toggleStatus(idea: Idea) {
@@ -200,8 +216,9 @@
}
}
$: awaitingIdeas = ideas.filter(i => i.status === 'awaiting');
$: otherIdeas = ideas.filter(i => i.status !== 'awaiting');
$: awaitingIdeas = ideas.filter(i => i.status === 'awaiting');
$: otherIdeas = ideas.filter(i => i.status !== 'awaiting' && i.status !== 'declined');
$: declinedIdeas = ideas.filter(i => i.status === 'declined');
async function deleteIdea(idea: Idea) {
if (!confirm(`Delete "${idea.title}"?`)) return;
@@ -301,11 +318,30 @@
{/each}
</ul>
{/if}
{#if declinedIdeas.length > 0}
<div class="mt-6">
<p class="text-xs font-semibold uppercase tracking-wide mb-2" style="color: #71717a">
✗ Won't implement
</p>
<ul class="space-y-2">
{#each declinedIdeas as idea (idea.id)}
<li
class="rounded-xl border px-4 py-3 flex gap-3"
style="background: var(--bg-card); border-color: var(--border); opacity: 0.4"
>
{@render ideaContent(idea)}
</li>
{/each}
</ul>
</div>
{/if}
{/if}
{#snippet ideaContent(idea: Idea)}
{@const done = idea.status === 'done'}
{@const done = idea.status === 'done'}
{@const awaiting = idea.status === 'awaiting'}
{@const declined = idea.status === 'declined'}
<!-- Vote button -->
<div class="flex flex-col items-center shrink-0 pt-0.5">
<button
@@ -351,19 +387,34 @@
{:else}
<div class="flex items-start justify-between gap-2">
<p class="font-medium text-sm" style="color: var(--text-primary)">
{#if done}<span class="mr-1.5 text-green-500"></span>{/if}{idea.title}
{#if done}<span class="mr-1.5 text-green-500"></span>{:else if declined}<span class="mr-1.5" style="color:#71717a"></span>{/if}{idea.title}
</p>
<div class="flex items-center gap-1 shrink-0">
{#if isAdmin}
{@const nextLabel = done ? 'reopen' : awaiting ? 'done' : 'awaiting'}
{@const btnColor = done ? 'var(--text-5)' : awaiting ? 'var(--accent)' : '#f59e0b'}
{@const borderColor = done ? 'var(--border-sub)' : awaiting ? 'var(--accent)' : '#f59e0b'}
<button
on:click={() => toggleStatus(idea)}
class="text-xs px-1.5 py-0.5 rounded transition-colors"
style="color: {btnColor}; border: 1px solid {borderColor}"
title="Cycle status"
>{nextLabel}</button>
{#if declined}
<button
on:click={() => declineIdea(idea)}
class="text-xs px-1.5 py-0.5 rounded transition-colors"
style="color: var(--text-5); border: 1px solid var(--border-sub)"
title="Reopen"
></button>
{:else}
{@const nextLabel = done ? 'reopen' : awaiting ? 'done' : 'awaiting'}
{@const btnColor = done ? 'var(--text-5)' : awaiting ? 'var(--accent)' : '#f59e0b'}
{@const borderColor = done ? 'var(--border-sub)' : awaiting ? 'var(--accent)' : '#f59e0b'}
<button
on:click={() => toggleStatus(idea)}
class="text-xs px-1.5 py-0.5 rounded transition-colors"
style="color: {btnColor}; border: 1px solid {borderColor}"
title="Cycle status"
>{nextLabel}</button>
<button
on:click={() => declineIdea(idea)}
class="text-xs px-1.5 py-0.5 rounded transition-colors"
style="color: #ef4444; border: 1px solid rgba(239,68,68,0.35)"
title="Won't implement"
></button>
{/if}
{/if}
{#if isAdmin || idea.author === myHandle}
<button