mirror of
https://github.com/kbenestad/ClubLedger.git
synced 2026-06-18 09:44:33 +00:00
Admin settings as accordions; cashier mode tab for top-up/withdrawal
- Replace flat settings form with 6 collapsible accordion sections (General, Business Address, Branding, Transactions, Receipt Labels, Receipt Footers), each with its own Save button and feedback message - Add segmented mode-tab control to cashier form so staff pick Top Up or Withdrawal before entering amounts; withdrawal panel hidden by default, resets to Top Up on cancel/clear - Add toggleAcc(), setCashierMode() JS helpers - Add accordion + mode-tab CSS styles https://claude.ai/code/session_01JuRTR5Xjx8emQsyerBgGU7
This commit is contained in:
parent
ca344e3762
commit
db0ae227f1
3 changed files with 287 additions and 116 deletions
|
|
@ -141,7 +141,6 @@ async function startApp() {
|
||||||
document.getElementById('registerForm').addEventListener('submit', e => { e.preventDefault(); registerMember(); });
|
document.getElementById('registerForm').addEventListener('submit', e => { e.preventDefault(); registerMember(); });
|
||||||
document.getElementById('editForm').addEventListener('submit', e => { e.preventDefault(); saveEdit(); });
|
document.getElementById('editForm').addEventListener('submit', e => { e.preventDefault(); saveEdit(); });
|
||||||
document.getElementById('editAccountForm').addEventListener('submit', e => { e.preventDefault(); saveEditAccount(); });
|
document.getElementById('editAccountForm').addEventListener('submit', e => { e.preventDefault(); saveEditAccount(); });
|
||||||
document.getElementById('settingsForm').addEventListener('submit', e => { e.preventDefault(); saveSettings(); });
|
|
||||||
document.getElementById('addAccountForm').addEventListener('submit', e => { e.preventDefault(); addAccount(); });
|
document.getElementById('addAccountForm').addEventListener('submit', e => { e.preventDefault(); addAccount(); });
|
||||||
|
|
||||||
// Enter-key on search inputs
|
// Enter-key on search inputs
|
||||||
|
|
@ -367,6 +366,7 @@ function selectCashierMember(id, name, number, balance, balanceDisplay) {
|
||||||
|
|
||||||
function clearCashierSelection() {
|
function clearCashierSelection() {
|
||||||
cashierMember = null;
|
cashierMember = null;
|
||||||
|
setCashierMode('topup');
|
||||||
document.getElementById('cashierForm').classList.add('hidden');
|
document.getElementById('cashierForm').classList.add('hidden');
|
||||||
document.getElementById('cashierAmount').value = '';
|
document.getElementById('cashierAmount').value = '';
|
||||||
document.getElementById('cashierTransferType').value = '';
|
document.getElementById('cashierTransferType').value = '';
|
||||||
|
|
@ -602,7 +602,24 @@ async function loadAdminSettings() {
|
||||||
function _sv(id) { return document.getElementById(id).value; }
|
function _sv(id) { return document.getElementById(id).value; }
|
||||||
function _svt(id) { return _sv(id).trim(); }
|
function _svt(id) { return _sv(id).trim(); }
|
||||||
|
|
||||||
async function saveSettings() {
|
function toggleAcc(btn) {
|
||||||
|
const body = btn.closest('.acc-item').querySelector('.acc-body');
|
||||||
|
const chevron = btn.querySelector('.acc-chevron');
|
||||||
|
const opening = body.classList.contains('hidden');
|
||||||
|
body.classList.toggle('hidden');
|
||||||
|
btn.setAttribute('aria-expanded', opening);
|
||||||
|
if (chevron) chevron.style.transform = opening ? 'rotate(180deg)' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCashierMode(mode) {
|
||||||
|
document.querySelectorAll('.mode-tab').forEach(t =>
|
||||||
|
t.classList.toggle('active', t.dataset.mode === mode));
|
||||||
|
document.getElementById('topupPanel').classList.toggle('hidden', mode !== 'topup');
|
||||||
|
document.getElementById('withdrawalPanel').classList.toggle('hidden', mode !== 'withdrawal');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveSettings(msgId) {
|
||||||
|
const _msgId = msgId || 'settingsMsg';
|
||||||
const div = parseInt(_sv('s-currency-divisor'), 10) || 100;
|
const div = parseInt(_sv('s-currency-divisor'), 10) || 100;
|
||||||
const body = {
|
const body = {
|
||||||
// General
|
// General
|
||||||
|
|
@ -661,13 +678,13 @@ async function saveSettings() {
|
||||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
});
|
});
|
||||||
setMsg('settingsMsg', 'Settings saved.', 'ok');
|
setMsg(_msgId, 'Saved.', 'ok');
|
||||||
await loadConfig();
|
await loadConfig();
|
||||||
populateTransferTypes();
|
populateTransferTypes();
|
||||||
document.querySelectorAll('.currency-unit').forEach(el => { el.textContent = cfg.currency_major || cfg.currency_unit; });
|
document.querySelectorAll('.currency-unit').forEach(el => { el.textContent = cfg.currency_major || cfg.currency_unit; });
|
||||||
if (document.getElementById('navBrand'))
|
if (document.getElementById('navBrand'))
|
||||||
document.getElementById('navBrand').textContent = cfg.club_name;
|
document.getElementById('navBrand').textContent = cfg.club_name;
|
||||||
} catch (err) { setMsg('settingsMsg', err.message, 'err'); }
|
} catch (err) { setMsg(_msgId, err.message, 'err'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Staff accounts table
|
// Staff accounts table
|
||||||
|
|
|
||||||
|
|
@ -161,9 +161,12 @@
|
||||||
|
|
||||||
<div id="cashierForm" class="hidden">
|
<div id="cashierForm" class="hidden">
|
||||||
<div class="selected-member-box" id="cashierSelected"></div>
|
<div class="selected-member-box" id="cashierSelected"></div>
|
||||||
|
<div class="mode-tabs">
|
||||||
|
<button class="mode-tab active" data-mode="topup" type="button" onclick="setCashierMode('topup')">Top Up</button>
|
||||||
|
<button class="mode-tab" data-mode="withdrawal" type="button" onclick="setCashierMode('withdrawal')">Withdrawal</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="cashier-action-panel">
|
<div class="cashier-action-panel" id="topupPanel">
|
||||||
<h3>Top Up</h3>
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label>Amount (<span class="currency-unit"></span>)</label>
|
<label>Amount (<span class="currency-unit"></span>)</label>
|
||||||
<input type="number" id="cashierAmount" placeholder="e.g. 10.00" min="0.01" step="0.01">
|
<input type="number" id="cashierAmount" placeholder="e.g. 10.00" min="0.01" step="0.01">
|
||||||
|
|
@ -186,8 +189,7 @@
|
||||||
<div id="cashierTopupMsg" class="msg"></div>
|
<div id="cashierTopupMsg" class="msg"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cashier-action-panel">
|
<div class="cashier-action-panel hidden" id="withdrawalPanel">
|
||||||
<h3>Withdrawal</h3>
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label>Amount (<span class="currency-unit"></span>)</label>
|
<label>Amount (<span class="currency-unit"></span>)</label>
|
||||||
<input type="number" id="withdrawalAmount" placeholder="e.g. 10.00" min="0.01" step="0.01">
|
<input type="number" id="withdrawalAmount" placeholder="e.g. 10.00" min="0.01" step="0.01">
|
||||||
|
|
@ -269,123 +271,183 @@
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2>App Settings</h2>
|
<h2>App Settings</h2>
|
||||||
<form id="settingsForm">
|
<div id="settingsMsg" class="msg" style="margin-bottom:8px"></div>
|
||||||
|
<div class="accordion">
|
||||||
|
|
||||||
<h3 class="sub-heading">General</h3>
|
<div class="acc-item">
|
||||||
<div class="form-row"><label>Club Name</label>
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<input type="text" id="s-club-name"></div>
|
<span>General</span>
|
||||||
<div class="form-row"><label>Currency Symbol</label>
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
<input type="text" id="s-currency-symbol" style="max-width:80px"></div>
|
</button>
|
||||||
<div class="form-row"><label>Currency Name <span class="label-hint">(major unit, e.g. pounds)</span></label>
|
<div class="acc-body hidden">
|
||||||
<input type="text" id="s-currency-major" placeholder="pounds"></div>
|
<div class="form-row"><label>Club Name</label>
|
||||||
<div class="form-row"><label>Subunit Name <span class="label-hint">(minor unit, e.g. pence)</span></label>
|
<input type="text" id="s-club-name"></div>
|
||||||
<input type="text" id="s-currency-minor" placeholder="pence"></div>
|
<div class="form-row"><label>Currency Symbol</label>
|
||||||
<div class="form-row"><label>Subunits per unit <span class="label-hint">(e.g. 100)</span></label>
|
<input type="text" id="s-currency-symbol" style="max-width:80px"></div>
|
||||||
<input type="number" id="s-currency-divisor" min="1" step="1" style="max-width:100px"></div>
|
<div class="form-row"><label>Currency Name <span class="label-hint">(major unit, e.g. pounds)</span></label>
|
||||||
<div class="form-row"><label>Minimum top-up <span class="label-hint" id="s-min-hint"></span></label>
|
<input type="text" id="s-currency-major" placeholder="pounds"></div>
|
||||||
<input type="number" id="s-min-topup" step="0.01" min="0.01"></div>
|
<div class="form-row"><label>Subunit Name <span class="label-hint">(minor unit, e.g. pence)</span></label>
|
||||||
<div class="form-row"><label>Maximum top-up <span class="label-hint" id="s-max-hint"></span></label>
|
<input type="text" id="s-currency-minor" placeholder="pence"></div>
|
||||||
<input type="number" id="s-max-topup" step="0.01"></div>
|
<div class="form-row"><label>Subunits per unit <span class="label-hint">(e.g. 100)</span></label>
|
||||||
<div class="form-row"><label>Maximum single charge <span class="label-hint" id="s-charge-hint"></span></label>
|
<input type="number" id="s-currency-divisor" min="1" step="1" style="max-width:100px"></div>
|
||||||
<input type="number" id="s-max-charge" step="0.01"></div>
|
<div class="form-row"><label>Minimum top-up <span class="label-hint" id="s-min-hint"></span></label>
|
||||||
<div class="form-row">
|
<input type="number" id="s-min-topup" step="0.01" min="0.01"></div>
|
||||||
<label>Overdraft (bar charges)</label>
|
<div class="form-row"><label>Maximum top-up <span class="label-hint" id="s-max-hint"></span></label>
|
||||||
<select id="s-overdraft-policy">
|
<input type="number" id="s-max-topup" step="0.01"></div>
|
||||||
<option value="never">Not allowed</option>
|
<div class="form-row"><label>Maximum single charge <span class="label-hint" id="s-charge-hint"></span></label>
|
||||||
<option value="always">Allowed for all</option>
|
<input type="number" id="s-max-charge" step="0.01"></div>
|
||||||
<option value="staff_override">Default not allowed — staff may override per charge</option>
|
<div class="form-row">
|
||||||
<option value="admin_override">Default not allowed — admin may override per charge</option>
|
<label>Overdraft (bar charges)</label>
|
||||||
<option value="staff_block">Default allowed — staff may block per charge</option>
|
<select id="s-overdraft-policy">
|
||||||
</select>
|
<option value="never">Not allowed</option>
|
||||||
</div>
|
<option value="always">Allowed for all</option>
|
||||||
<div class="form-row">
|
<option value="staff_override">Default not allowed — staff may override per charge</option>
|
||||||
<label>Timezone <span class="label-hint">(IANA name, e.g. Europe/London, Asia/Bangkok — default is server timezone)</span></label>
|
<option value="admin_override">Default not allowed — admin may override per charge</option>
|
||||||
<input type="text" id="s-timezone" list="tz-list" placeholder="e.g. Europe/London" autocomplete="off">
|
<option value="staff_block">Default allowed — staff may block per charge</option>
|
||||||
<datalist id="tz-list"></datalist>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label>Default paper size <span class="label-hint">(for receipts and statements)</span></label>
|
<label>Timezone <span class="label-hint">(IANA name, e.g. Europe/London, Asia/Bangkok — default is server timezone)</span></label>
|
||||||
<select id="s-paper-size">
|
<input type="text" id="s-timezone" list="tz-list" placeholder="e.g. Europe/London" autocomplete="off">
|
||||||
<option value="A4">A4</option>
|
<datalist id="tz-list"></datalist>
|
||||||
<option value="A5">A5</option>
|
</div>
|
||||||
</select>
|
<div class="form-row">
|
||||||
|
<label>Default paper size <span class="label-hint">(for receipts and statements)</span></label>
|
||||||
|
<select id="s-paper-size">
|
||||||
|
<option value="A4">A4</option>
|
||||||
|
<option value="A5">A5</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="acc-footer">
|
||||||
|
<button class="btn btn-primary" type="button" onclick="saveSettings('generalMsg')">Save</button>
|
||||||
|
<div id="generalMsg" class="msg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-divider"></div>
|
<div class="acc-item">
|
||||||
<h3 class="sub-heading">Business Address</h3>
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<div class="form-row"><label>Address line 1</label><input type="text" id="s-biz-address1"></div>
|
<span>Business Address</span>
|
||||||
<div class="form-row"><label>Address line 2</label><input type="text" id="s-biz-address2"></div>
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
<div class="form-row"><label>Address line 3</label><input type="text" id="s-biz-address3"></div>
|
</button>
|
||||||
<div class="form-row"><label>Address line 4</label><input type="text" id="s-biz-address4"></div>
|
<div class="acc-body hidden">
|
||||||
<div class="form-row"><label>Country</label><input type="text" id="s-biz-country"></div>
|
<div class="form-row"><label>Address line 1</label><input type="text" id="s-biz-address1"></div>
|
||||||
<div class="form-row"><label>Phone</label><input type="text" id="s-biz-phone"></div>
|
<div class="form-row"><label>Address line 2</label><input type="text" id="s-biz-address2"></div>
|
||||||
<div class="form-row"><label>Email</label><input type="text" id="s-biz-email"></div>
|
<div class="form-row"><label>Address line 3</label><input type="text" id="s-biz-address3"></div>
|
||||||
<div class="form-row"><label>Website</label><input type="text" id="s-biz-website"></div>
|
<div class="form-row"><label>Address line 4</label><input type="text" id="s-biz-address4"></div>
|
||||||
|
<div class="form-row"><label>Country</label><input type="text" id="s-biz-country"></div>
|
||||||
<div class="panel-divider"></div>
|
<div class="form-row"><label>Phone</label><input type="text" id="s-biz-phone"></div>
|
||||||
<h3 class="sub-heading">Branding</h3>
|
<div class="form-row"><label>Email</label><input type="text" id="s-biz-email"></div>
|
||||||
<div class="form-row">
|
<div class="form-row"><label>Website</label><input type="text" id="s-biz-website"></div>
|
||||||
<label>Logo <span class="label-hint">(upload image file)</span></label>
|
<div class="acc-footer">
|
||||||
<input type="file" id="s-logo-upload" accept="image/*" style="padding:4px 0;border:none;background:none;">
|
<button class="btn btn-primary" type="button" onclick="saveSettings('bizMsg')">Save</button>
|
||||||
<div id="logoUploadMsg" class="msg" style="margin-top:4px"></div>
|
<div id="bizMsg" class="msg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row"><label>Logo URL <span class="label-hint">(or paste URL; upload above sets this automatically)</span></label>
|
|
||||||
<input type="text" id="s-logo-url" placeholder="https://..."></div>
|
<div class="acc-item">
|
||||||
<div class="form-row">
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<label>Logo alignment</label>
|
<span>Branding</span>
|
||||||
<select id="s-logo-align">
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
<option value="left">Left</option>
|
</button>
|
||||||
<option value="center">Center</option>
|
<div class="acc-body hidden">
|
||||||
<option value="right">Right</option>
|
<div class="form-row">
|
||||||
</select>
|
<label>Logo <span class="label-hint">(upload image file)</span></label>
|
||||||
|
<input type="file" id="s-logo-upload" accept="image/*" style="padding:4px 0;border:none;background:none;">
|
||||||
|
<div id="logoUploadMsg" class="msg" style="margin-top:4px"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row"><label>Logo URL <span class="label-hint">(or paste URL; upload above sets this automatically)</span></label>
|
||||||
|
<input type="text" id="s-logo-url" placeholder="https://..."></div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label>Logo alignment</label>
|
||||||
|
<select id="s-logo-align">
|
||||||
|
<option value="left">Left</option>
|
||||||
|
<option value="center">Center</option>
|
||||||
|
<option value="right">Right</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-row" style="flex-direction:row;gap:24px;align-items:flex-end">
|
||||||
|
<div style="flex:1"><label>Logo max width (px)</label>
|
||||||
|
<input type="number" id="s-logo-max-width" min="20" step="10" placeholder="200"></div>
|
||||||
|
<div style="flex:1"><label>Logo max height (px)</label>
|
||||||
|
<input type="number" id="s-logo-max-height" min="20" step="10" placeholder="80"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row"><label>Bar venue name</label>
|
||||||
|
<input type="text" id="s-bar-name" placeholder="Bar"></div>
|
||||||
|
<div class="form-row"><label>Cashier venue name</label>
|
||||||
|
<input type="text" id="s-cashier-name" placeholder="Cashier"></div>
|
||||||
|
<div class="acc-footer">
|
||||||
|
<button class="btn btn-primary" type="button" onclick="saveSettings('brandingMsg')">Save</button>
|
||||||
|
<div id="brandingMsg" class="msg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row" style="flex-direction:row;gap:24px;align-items:flex-end">
|
|
||||||
<div style="flex:1"><label>Logo max width (px)</label>
|
<div class="acc-item">
|
||||||
<input type="number" id="s-logo-max-width" min="20" step="10" placeholder="200"></div>
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<div style="flex:1"><label>Logo max height (px)</label>
|
<span>Transactions</span>
|
||||||
<input type="number" id="s-logo-max-height" min="20" step="10" placeholder="80"></div>
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
|
</button>
|
||||||
|
<div class="acc-body hidden">
|
||||||
|
<div class="form-row"><label>Transaction reference prefix</label>
|
||||||
|
<input type="text" id="s-txn-ref-prefix" placeholder="TXN" style="max-width:120px"></div>
|
||||||
|
<div class="form-row"><label>Transfer types <span class="label-hint">(comma-separated)</span></label>
|
||||||
|
<input type="text" id="s-transfer-types" placeholder="Bank Transfer,Cash,QR"></div>
|
||||||
|
<div class="acc-footer">
|
||||||
|
<button class="btn btn-primary" type="button" onclick="saveSettings('transactionsMsg')">Save</button>
|
||||||
|
<div id="transactionsMsg" class="msg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row"><label>Bar venue name</label>
|
|
||||||
<input type="text" id="s-bar-name" placeholder="Bar"></div>
|
|
||||||
<div class="form-row"><label>Cashier venue name</label>
|
|
||||||
<input type="text" id="s-cashier-name" placeholder="Cashier"></div>
|
|
||||||
|
|
||||||
<div class="panel-divider"></div>
|
<div class="acc-item">
|
||||||
<h3 class="sub-heading">Transactions</h3>
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<div class="form-row"><label>Transaction reference prefix</label>
|
<span>Receipt Labels <span class="label-hint">(for localisation)</span></span>
|
||||||
<input type="text" id="s-txn-ref-prefix" placeholder="TXN" style="max-width:120px"></div>
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
<div class="form-row"><label>Transfer types <span class="label-hint">(comma-separated)</span></label>
|
</button>
|
||||||
<input type="text" id="s-transfer-types" placeholder="Bank Transfer,Cash,QR"></div>
|
<div class="acc-body hidden">
|
||||||
|
<div class="form-row"><label>Receipt title (charge)</label><input type="text" id="s-lbl-receipt" placeholder="RECEIPT"></div>
|
||||||
|
<div class="form-row"><label>Receipt title (top-up)</label><input type="text" id="s-lbl-topup-receipt" placeholder="TOP-UP RECEIPT"></div>
|
||||||
|
<div class="form-row"><label>Receipt title (withdrawal)</label><input type="text" id="s-lbl-withdrawal-receipt" placeholder="WITHDRAWAL RECEIPT"></div>
|
||||||
|
<div class="form-row"><label>Staff label</label><input type="text" id="s-lbl-staff" placeholder="STAFF"></div>
|
||||||
|
<div class="form-row"><label>Transaction label</label><input type="text" id="s-lbl-transaction" placeholder="TRANSACTION"></div>
|
||||||
|
<div class="form-row"><label>Charge/venue label</label><input type="text" id="s-lbl-charge" placeholder="CHARGE"></div>
|
||||||
|
<div class="form-row"><label>Transaction time label</label><input type="text" id="s-lbl-txn-time" placeholder="TRANSACTION TIME"></div>
|
||||||
|
<div class="form-row"><label>Amount charged label</label><input type="text" id="s-lbl-amount-charged" placeholder="AMOUNT CHARGED"></div>
|
||||||
|
<div class="form-row"><label>Remaining balance label</label><input type="text" id="s-lbl-remaining-balance" placeholder="REMAINING BALANCE"></div>
|
||||||
|
<div class="form-row"><label>Balance transfer section header</label><input type="text" id="s-lbl-balance-transfer" placeholder="BALANCE TRANSFER"></div>
|
||||||
|
<div class="form-row"><label>Amount topped-up label</label><input type="text" id="s-lbl-amount-topup" placeholder="AMOUNT TOPPED-UP"></div>
|
||||||
|
<div class="form-row"><label>Amount withdrawn label</label><input type="text" id="s-lbl-amount-withdrawal" placeholder="AMOUNT WITHDRAWN"></div>
|
||||||
|
<div class="form-row"><label>Transfer type label</label><input type="text" id="s-lbl-transfer-type" placeholder="TRANSFER TYPE"></div>
|
||||||
|
<div class="form-row"><label>Transfer reference label</label><input type="text" id="s-lbl-transfer-ref" placeholder="TRANSFER REFERENCE"></div>
|
||||||
|
<div class="acc-footer">
|
||||||
|
<button class="btn btn-primary" type="button" onclick="saveSettings('labelsMsg')">Save</button>
|
||||||
|
<div id="labelsMsg" class="msg"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel-divider"></div>
|
<div class="acc-item">
|
||||||
<h3 class="sub-heading">Receipt Labels <span class="label-hint">(for localisation)</span></h3>
|
<button class="acc-header" type="button" onclick="toggleAcc(this)" aria-expanded="false">
|
||||||
<div class="form-row"><label>Receipt title (charge)</label><input type="text" id="s-lbl-receipt" placeholder="RECEIPT"></div>
|
<span>Receipt Footers</span>
|
||||||
<div class="form-row"><label>Receipt title (top-up)</label><input type="text" id="s-lbl-topup-receipt" placeholder="TOP-UP RECEIPT"></div>
|
<span class="material-symbols-outlined acc-chevron">expand_more</span>
|
||||||
<div class="form-row"><label>Receipt title (withdrawal)</label><input type="text" id="s-lbl-withdrawal-receipt" placeholder="WITHDRAWAL RECEIPT"></div>
|
</button>
|
||||||
<div class="form-row"><label>Staff label</label><input type="text" id="s-lbl-staff" placeholder="STAFF"></div>
|
<div class="acc-body hidden">
|
||||||
<div class="form-row"><label>Transaction label</label><input type="text" id="s-lbl-transaction" placeholder="TRANSACTION"></div>
|
<div class="form-row"><label>Footer — all <span class="label-hint">(fallback for all receipts and statement)</span></label>
|
||||||
<div class="form-row"><label>Charge/venue label</label><input type="text" id="s-lbl-charge" placeholder="CHARGE"></div>
|
<textarea id="s-receipt-footer" rows="2" placeholder="Printed at the bottom of every receipt and statement"></textarea></div>
|
||||||
<div class="form-row"><label>Transaction time label</label><input type="text" id="s-lbl-txn-time" placeholder="TRANSACTION TIME"></div>
|
<div class="form-row"><label>Footer — charge receipts <span class="label-hint">(overrides all-footer for bar charges)</span></label>
|
||||||
<div class="form-row"><label>Amount charged label</label><input type="text" id="s-lbl-amount-charged" placeholder="AMOUNT CHARGED"></div>
|
<textarea id="s-receipt-footer-charge" rows="2"></textarea></div>
|
||||||
<div class="form-row"><label>Remaining balance label</label><input type="text" id="s-lbl-remaining-balance" placeholder="REMAINING BALANCE"></div>
|
<div class="form-row"><label>Footer — cashier receipts <span class="label-hint">(overrides all-footer for top-ups and withdrawals)</span></label>
|
||||||
<div class="form-row"><label>Balance transfer section header</label><input type="text" id="s-lbl-balance-transfer" placeholder="BALANCE TRANSFER"></div>
|
<textarea id="s-receipt-footer-cashier" rows="2"></textarea></div>
|
||||||
<div class="form-row"><label>Amount topped-up label</label><input type="text" id="s-lbl-amount-topup" placeholder="AMOUNT TOPPED-UP"></div>
|
<div class="acc-footer">
|
||||||
<div class="form-row"><label>Amount withdrawn label</label><input type="text" id="s-lbl-amount-withdrawal" placeholder="AMOUNT WITHDRAWN"></div>
|
<button class="btn btn-primary" type="button" onclick="saveSettings('footersMsg')">Save</button>
|
||||||
<div class="form-row"><label>Transfer type label</label><input type="text" id="s-lbl-transfer-type" placeholder="TRANSFER TYPE"></div>
|
<div id="footersMsg" class="msg"></div>
|
||||||
<div class="form-row"><label>Transfer reference label</label><input type="text" id="s-lbl-transfer-ref" placeholder="TRANSFER REFERENCE"></div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel-divider"></div>
|
</div>
|
||||||
<h3 class="sub-heading">Receipt Footers</h3>
|
|
||||||
<div class="form-row"><label>Footer — all <span class="label-hint">(fallback for all receipts and statement)</span></label>
|
|
||||||
<textarea id="s-receipt-footer" rows="2" placeholder="Printed at the bottom of every receipt and statement"></textarea></div>
|
|
||||||
<div class="form-row"><label>Footer — charge receipts <span class="label-hint">(overrides all-footer for bar charges)</span></label>
|
|
||||||
<textarea id="s-receipt-footer-charge" rows="2"></textarea></div>
|
|
||||||
<div class="form-row"><label>Footer — cashier receipts <span class="label-hint">(overrides all-footer for top-ups and withdrawals)</span></label>
|
|
||||||
<textarea id="s-receipt-footer-cashier" rows="2"></textarea></div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary" style="margin-top:8px">Save Settings</button>
|
|
||||||
</form>
|
|
||||||
<div id="settingsMsg" class="msg"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
|
|
|
||||||
|
|
@ -712,3 +712,95 @@ select {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Accordion (admin settings) ---- */
|
||||||
|
.accordion {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-item {
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: var(--canvas-subtle);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--fg);
|
||||||
|
text-align: left;
|
||||||
|
transition: background .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-header:hover { background: var(--border-muted); }
|
||||||
|
|
||||||
|
.acc-chevron {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: var(--fg-muted);
|
||||||
|
transition: transform .2s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-body {
|
||||||
|
padding: 16px;
|
||||||
|
background: var(--canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
.acc-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding-top: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Mode tabs (cashier top-up / withdrawal switch) ---- */
|
||||||
|
.mode-tabs {
|
||||||
|
display: flex;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-tab {
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: var(--canvas-subtle);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--fg-muted);
|
||||||
|
transition: background .1s, color .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-tab + .mode-tab {
|
||||||
|
border-left: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-tab.active {
|
||||||
|
background: var(--canvas);
|
||||||
|
color: var(--fg);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-tab:hover:not(.active) {
|
||||||
|
background: var(--canvas);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue