feat(ui): supporto funnel - morte PG e rimpiazzo
test / test (push) Has been cancelled

- Card personaggi morti: grigia, teschio, 0 PF, filtro grayscale
- Bottone Nuovo PG quando ci sono caduti
- replaceFunnelDead() chiama POST /api/campaign/{id}/character
- Stato aggiornato dopo rimpiazzo
This commit is contained in:
truetype committed 2026-06-30 17:25:43 +02:00
1 parent e3edb87fac
commit 634625dbfb
1 file changed
+46 -4
+46 -4
View File
@@ -233,6 +233,35 @@ html, body {
margin-top: 2px;
}
/* Funnel - char dead */
.char-card.dead {
opacity: 0.4;
filter: grayscale(0.8);
}
.char-card.dead .char-name { color: var(--red); }
.funnel-actions {
padding: 8px 0;
}
.btn-funnel {
width: 100%;
background: var(--bg-elevated);
border: 1px dashed var(--border-light);
border-radius: var(--radius);
padding: 8px;
color: var(--text-secondary);
font-family: var(--font-display);
font-size: 11px;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 1px;
transition: background 0.2s, color 0.2s;
}
.btn-funnel:hover {
background: var(--gold-dim);
color: #fff;
border-style: solid;
}
/* Area map */
.area-item {
display: flex;
@@ -1046,19 +1075,22 @@ function renderChar(chars) {
charDisplay.innerHTML = '<div class="empty-state">Nessun PG</div>';
return;
}
const alive = chars.filter(c => c.status !== 'dead');
const dead = chars.filter(c => c.status === 'dead');
charDisplay.innerHTML = chars.map(c => {
const isDead = c.status === 'dead';
const isLv0 = c.level === 0;
const hpPct = Math.round((c.hp_current / c.hp_max) * 100);
const label = isLv0
? `${c.occupation || 'Mestiere'} · Lv0`
: `${c.char_class || ''} · Livello ${c.level}`;
return `
<div class="char-card" style="border-bottom:1px solid var(--border);padding:8px 0;">
<div class="char-name">${escapeHtml(c.name)}</div>
<div class="char-card ${isDead ? 'dead' : ''}" style="border-bottom:1px solid var(--border);padding:8px 0;">
<div class="char-name">${isDead ? '💀 ' : ''}${escapeHtml(c.name)}</div>
<div class="char-class">${escapeHtml(label)}</div>
<div class="hp-bar-wrapper">
<div class="hp-bar-bg"><div class="hp-bar-fill" style="width:${hpPct}%"></div></div>
<span class="hp-text">${c.hp_current}/${c.hp_max}</span>
<div class="hp-bar-bg"><div class="hp-bar-fill" style="width:${isDead ? 0 : hpPct}%"></div></div>
<span class="hp-text">${isDead ? '✝ morto' : c.hp_current+'/'+c.hp_max}</span>
</div>
<div class="stat-grid">
<div class="stat-row"><span class="stat-label">FOR</span><span class="stat-val">${c.str||'?'}</span></div>
@@ -1072,6 +1104,16 @@ function renderChar(chars) {
</div>
`;
}).join('');
if (dead.length > 0) {
charDisplay.innerHTML += `<div class="funnel-actions"><button onclick="replaceFunnelDead()" class="btn-funnel">➕ Nuovo PG (rimpiazza caduti)</button></div>`;
}
}
async function replaceFunnelDead() {
const resp = await fetch(`${BASE}/api/campaign/${campaignId}/character`, { method: 'POST' });
const data = await resp.json();
const s = await (await fetch(`${BASE}/api/campaign/${campaignId}`)).json();
applyState(s);
}
function renderQuests(quests) {