Files
budget/views/settings.php
T
Ty Clifford b7eaa81501 -
2026-06-14 15:25:31 -04:00

108 lines
8.8 KiB
PHP

<?php $s = $allSettings; ?>
<?php if ($newSecret): ?>
<div class="setup-secret card glow-green">
<div><p class="eyebrow">Authenticator setup</p><h2>Store this key now</h2><p>Add the key manually in an authenticator app. It is only shown once.</p></div>
<code><?= h($newSecret) ?></code>
<details><summary>Authenticator URI</summary><code class="wrap-code"><?= h($totpUri) ?></code></details>
</div>
<?php endif; ?>
<form method="post">
<?= csrf_field() ?><input type="hidden" name="action" value="settings.save">
<section class="settings-grid">
<article class="card settings-nav">
<p class="eyebrow">Configuration</p>
<a href="#general">General</a><a href="#modules">Modules</a><a href="#dormant">Dormant rules</a><a href="#alerts">Alerts & Mailgun</a><a href="#security">Security</a>
</article>
<div class="stack span-2">
<article class="card" id="general">
<div class="card-heading"><div><p class="eyebrow">Identity and display</p><h2>General</h2></div></div>
<div class="form-grid">
<label class="span-2">Planner name<input type="text" name="app.name" value="<?= h($s['app.name']) ?>" required></label>
<label>Currency symbol<input type="text" name="app.currency_symbol" value="<?= h($s['app.currency_symbol']) ?>" maxlength="4" required></label>
<label>Default theme<select name="theme.default"><option value="dark" <?= $s['theme.default'] === 'dark' ? 'selected' : '' ?>>Dark</option><option value="light" <?= $s['theme.default'] === 'light' ? 'selected' : '' ?>>Light</option></select></label>
<label class="span-2">Timezone<input type="text" name="app.timezone" value="<?= h($s['app.timezone']) ?>" placeholder="America/New_York"></label>
</div>
</article>
<article class="card" id="modules">
<div class="card-heading"><div><p class="eyebrow">Modular planner</p><h2>Enabled modules</h2></div></div>
<div class="toggle-grid">
<?php
$moduleLabels = [
'income' => ['Income tracking', 'Starting points and additional income'],
'bills' => ['Budget items', 'Targets, bills, and progress'],
'calendar' => ['Bill calendar', 'Due dates and personal events'],
'dead_account' => ['Dormant account', 'Withholding and restorations'],
'comparisons' => ['Comparisons', 'Monthly and yearly analysis'],
'alerts' => ['Email alerts', 'Mailgun bill reminders'],
'import_export' => ['Data portability', 'JSON, HTML, and PDF'],
];
foreach ($moduleLabels as $key => [$label, $description]):
?>
<label class="toggle-card"><span><strong><?= h($label) ?></strong><small><?= h($description) ?></small></span><input type="checkbox" name="modules_<?= h($key) ?>" value="1" <?= !empty($s['modules.' . $key]) ? 'checked' : '' ?>><i></i></label>
<?php endforeach; ?>
</div>
</article>
<article class="card" id="dormant">
<div class="card-heading"><div><p class="eyebrow">Automated set-aside</p><h2>Dormant account rules</h2></div></div>
<div class="form-grid">
<label>Income rule<select name="dead.income_mode"><option value="percent" <?= $s['dead.income_mode'] === 'percent' ? 'selected' : '' ?>>Percentage</option><option value="fixed" <?= $s['dead.income_mode'] === 'fixed' ? 'selected' : '' ?>>Direct amount</option></select></label>
<label>Income value<input type="number" name="dead.income_value" min="0" step="0.01" value="<?= h((string) $s['dead.income_value']) ?>"></label>
<label>Per-transaction rule<select name="dead.transaction_mode"><option value="percent" <?= $s['dead.transaction_mode'] === 'percent' ? 'selected' : '' ?>>Percentage</option><option value="fixed" <?= $s['dead.transaction_mode'] === 'fixed' ? 'selected' : '' ?>>Direct amount</option></select></label>
<label>Per-transaction value<input type="number" name="dead.transaction_value" min="0" step="0.01" value="<?= h((string) $s['dead.transaction_value']) ?>"></label>
<label class="check-row span-2"><input type="checkbox" name="dead_hide_balance" value="1" <?= $s['dead.hide_balance'] ? 'checked' : '' ?>><span><strong>Conceal dormant balance</strong><small>Require a hover and confirmation click to reveal it.</small></span></label>
</div>
</article>
<article class="card" id="alerts">
<div class="card-heading"><div><p class="eyebrow">Upcoming bills</p><h2>Email alerts via Mailgun</h2></div><span class="status-badge <?= $mailgunConfigured ? 'success' : 'warning' ?>"><?= $mailgunConfigured ? 'Configured' : 'Needs setup' ?></span></div>
<div class="form-grid">
<label class="span-2">Alert recipient<input type="email" name="alerts.email" value="<?= h($s['alerts.email']) ?>" placeholder="alerts@example.com"></label>
<label>Alert windows (days)<input type="text" name="alerts.windows" value="<?= h(implode(', ', (array) $s['alerts.windows'])) ?>" placeholder="7, 3, 1"></label>
<label>Reminder times<input type="text" name="alerts.times" value="<?= h(implode(', ', (array) $s['alerts.times'])) ?>" placeholder="09:00, 17:30"></label>
<label>Mailgun domain<input type="text" name="mailgun.domain" value="<?= h($s['mailgun.domain']) ?>" placeholder="mg.example.com"></label>
<label>Mailgun region<select name="mailgun.region"><option value="us" <?= $s['mailgun.region'] === 'us' ? 'selected' : '' ?>>United States</option><option value="eu" <?= $s['mailgun.region'] === 'eu' ? 'selected' : '' ?>>European Union</option></select></label>
<label class="span-2">From address<input type="text" name="mailgun.from" value="<?= h($s['mailgun.from']) ?>"></label>
<label class="span-2">Mailgun API key<input type="password" name="mailgun.api_key" placeholder="<?= $s['mailgun.api_key'] ? 'Stored — enter a value to replace it' : 'key-…' ?>" autocomplete="off"></label>
<?php if ($s['mailgun.api_key']): ?><label class="check-row span-2 slim"><input type="checkbox" name="clear_mailgun_key" value="1"><span>Clear the stored API key</span></label><?php endif; ?>
</div>
<p class="form-note">Run <code>php scripts/send-reminders.php</code> every minute with cron; it only sends at configured times.</p>
</article>
<article class="card" id="security">
<div class="card-heading"><div><p class="eyebrow">Administrator protection</p><h2>Security</h2></div></div>
<label class="check-row"><input type="checkbox" name="security_2fa_required" value="1" <?= $s['security.2fa_required'] ? 'checked' : '' ?>><span><strong>Require two-factor authentication</strong><small>Uses any standard TOTP authenticator app.</small></span></label>
<p class="form-note">Administrator: <?= h($user['email']) ?> · account created <?= h(date('M j, Y', strtotime($user['created_at']))) ?></p>
</article>
<button class="button primary sticky-save" type="submit">Save all settings</button>
</div>
</section>
</form>
<section class="settings-actions">
<form method="post">
<?= csrf_field() ?><input type="hidden" name="action" value="2fa.regenerate">
<button class="button secondary" type="submit">Generate new 2FA key</button>
</form>
<?php if ($settings->module('alerts')): ?>
<form method="post" data-confirm="Run the reminder scan now? Configured emails may be sent through Mailgun.">
<?= csrf_field() ?><input type="hidden" name="action" value="alerts.run">
<button class="button secondary" type="submit">Run reminders now</button>
</form>
<?php endif; ?>
</section>
<article class="card">
<div class="card-heading"><div><p class="eyebrow">Organize spending</p><h2>Add an expense category</h2></div></div>
<form method="post" class="inline-fields">
<?= csrf_field() ?><input type="hidden" name="action" value="category.add">
<label>Name<input type="text" name="name" required placeholder="Utilities"></label>
<label>Color<input type="color" name="color" value="#7c5cff"></label>
<label>Optional monthly limit<input type="number" name="monthly_limit" min="0" step="0.01" value="0"></label>
<button class="button primary" type="submit">Add category</button>
</form>
</article>