Replace action row with Save | Validate | Download layout

- Save (20%) and Validate (20%) as ghost buttons, Download (60%) as primary
- Validate runs full validation and shows error list or a green success note
- Save retains existing onSave behaviour (soft validation + persist)

https://claude.ai/code/session_01JyuActqTJG5tuRQNLmT7fZ
This commit is contained in:
Claude 2026-06-08 16:38:20 +00:00
parent ba64a27a1e
commit e47dc9c4b3
No known key found for this signature in database

View file

@ -865,11 +865,36 @@ function render() {
totals.appendChild(grandRow); totals.appendChild(grandRow);
actCard.appendChild(totals); actCard.appendChild(totals);
const actionRow = el('div', {style:{display:'flex', gap:'12px', marginTop:'16px', flexWrap:'wrap'}}); const actionRow = el('div', {style:{display:'flex', gap:'10px', marginTop:'16px'}});
const saveBtn = el('button', {className:'kb-btn kb-btn--soft', onClick: onSave}, 'Save form');
const genBtn = el('button', {className:'kb-btn kb-btn--primary kb-btn--lg', id:'gen-btn', style:{flex:'1'}, onClick: onGenerate}); const saveBtn = el('button', {className:'kb-btn kb-btn--ghost', style:{flex:'0 0 20%'}, onClick: onSave}, 'Save');
genBtn.innerHTML = `<svg viewBox="0 0 16 16" fill="currentColor" width="16" height="16"><path d="M8 1a1 1 0 0 1 1 1v6.6l2.3-2.3a1 1 0 0 1 1.4 1.4l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 0 1 1.4-1.4L7 8.6V2a1 1 0 0 1 1-1zM3 13h10a1 1 0 1 1 0 2H3a1 1 0 1 1 0-2z"/></svg>Generate PDF`;
actionRow.append(saveBtn, genBtn); const validateBtn = el('button', {className:'kb-btn kb-btn--ghost', style:{flex:'0 0 20%'}});
validateBtn.textContent = 'Validate';
validateBtn.addEventListener('click', () => {
const valBox = $('#val-box');
valBox.innerHTML = '';
const errs = validate();
if (errs.length) {
const note = el('div', {className:'kb-note kb-note--error'});
note.innerHTML = `<svg viewBox="0 0 16 16" fill="currentColor"><path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/></svg>`;
const txt = el('div');
txt.innerHTML = '<strong>Please fix the following:</strong><br>' + errs.join('<br>');
note.appendChild(txt);
valBox.appendChild(note);
valBox.scrollIntoView({behavior:'smooth'});
} else {
const note = el('div', {className:'kb-note kb-note--success'});
note.innerHTML = `<svg viewBox="0 0 16 16" fill="currentColor"><path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.061L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/></svg><div><strong>All good.</strong> The form is ready to download.</div>`;
valBox.appendChild(note);
valBox.scrollIntoView({behavior:'smooth'});
}
});
const genBtn = el('button', {className:'kb-btn kb-btn--primary kb-btn--lg', id:'gen-btn', style:{flex:'0 0 calc(60% - 20px)'}, onClick: onGenerate});
genBtn.innerHTML = `<svg viewBox="0 0 16 16" fill="currentColor" width="16" height="16"><path d="M8 1a1 1 0 0 1 1 1v6.6l2.3-2.3a1 1 0 0 1 1.4 1.4l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 0 1 1.4-1.4L7 8.6V2a1 1 0 0 1 1-1zM3 13h10a1 1 0 1 1 0 2H3a1 1 0 1 1 0-2z"/></svg>Download reimbursement form`;
actionRow.append(saveBtn, validateBtn, genBtn);
actCard.appendChild(actionRow); actCard.appendChild(actionRow);
wrap.appendChild(actCard); wrap.appendChild(actCard);