fabrica

hanna/fabrica

style(web): show invite status as a leading used/unused pill

85fc506 · hanna committed on 2026-07-26

The invite's redemption state moves from a meta line under the note to a
coloured pill at the start of the row — green "unused" while open, muted
"used" once redeemed. Any expiry stays on the meta line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed by hannaSSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
2 files changed · +19 −4UnifiedSplit
assets/base.css +9 −0
@@ -1421,6 +1421,15 @@ label.checkbox input {
1421 color: var(--fb-warning);1421 color: var(--fb-warning);
1422 border-color: var(--fb-warning);1422 border-color: var(--fb-warning);
1423}1423}
1424/* Sign-up invite status: open (unused) reads as available, spent (used) muted. */
1425.badge-unused {
1426 color: var(--fb-success);
1427 border-color: var(--fb-success);
1428}
1429.badge-used {
1430 color: var(--fb-fg-muted);
1431 border-color: var(--fb-fg-muted);
1432}
14241433
1425/* Inline search row: input grows, button sits to its right with margin. */1434/* Inline search row: input grows, button sits to its right with margin. */
1426.search-row {1435.search-row {
crates/web/src/admin.rs +10 −4
@@ -590,10 +590,16 @@ pub async fn invites(
590 @for iv in &invites {590 @for iv in &invites {
591 li class="entry-row" {591 li class="entry-row" {
592 div class="entry-row-body" {592 div class="entry-row-body" {
593 span class="entry-row-title" { (iv.note.clone().unwrap_or_else(|| "(no note)".to_string())) }593 span class="entry-row-title" {
594 div class="entry-row-meta muted" {594 @if iv.used_at.is_some() {
595 @if iv.used_at.is_some() { "used" } @else { "unused" }595 span class="badge badge-used" { "used" }
596 @if let Some(exp) = iv.expires_at { " · expires " (crate::repo::fmt_date(exp)) }596 } @else {
597 span class="badge badge-unused" { "unused" }
598 }
599 " " (iv.note.clone().unwrap_or_else(|| "(no note)".to_string()))
600 }
601 @if let Some(exp) = iv.expires_at {
602 div class="entry-row-meta muted" { "expires " (crate::repo::fmt_date(exp)) }
597 }603 }
598 }604 }
599 div class="entry-row-actions admin-actions" {605 div class="entry-row-actions admin-actions" {