- Implemented the complete first-run experience:
Account creation and guarded onboarding flow. Current-cash starting balance with automatic rollover enabled. Dynamic bill generation, shared/custom categories, recurring targets, and optional same-day onboarding transactions. Optional dormant reserve and additional categories. Mailgun email or authenticator-app 2FA configuration. Responsive dark/light UI with no overflow at 390px. Fixed administrator session-ID creation bug. Core implementation: [OnboardingService.php (line 59)](/Users/tyemeclifford/Documents/GH/budget/app/OnboardingService.php:59), [onboarding.php (line 19)](/Users/tyemeclifford/Documents/GH/budget/views/onboarding.php:19), and [index.php (line 143)](/Users/tyemeclifford/Documents/GH/budget/public/index.php:143). Verification passed: financial self-test, onboarding integration test, full browser walkthrough, mobile layout, routing guards, and zero browser console errors. Live email delivery requires actual Mailgun credentials and was not sent during testing.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
$appName = (string) $settings->get('app.name', 'Neon Ledger');
|
||||
$defaultTheme = (string) $settings->get('theme.default', 'dark');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="<?= h($defaultTheme) ?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<meta name="theme-color" content="#090b12">
|
||||
<title><?= h($title ?? 'Welcome') ?> · <?= h($appName) ?></title>
|
||||
<link rel="stylesheet" href="/assets/app.css?v=<?= (int) filemtime(APP_ROOT . '/public/assets/app.css') ?>">
|
||||
<script>document.documentElement.dataset.theme=localStorage.getItem('budget-theme')||<?= json_encode($defaultTheme) ?>;</script>
|
||||
</head>
|
||||
<body class="onboarding-body">
|
||||
<div class="onboarding-shell">
|
||||
<header class="onboarding-header">
|
||||
<div class="brand onboarding-brand">
|
||||
<span class="brand-mark"><i></i><b>N</b></span>
|
||||
<span class="brand-copy"><strong><?= h($appName) ?></strong><small>Personal finance planner</small></span>
|
||||
</div>
|
||||
<div class="onboarding-account">
|
||||
<span><small>Signed in as</small><strong><?= h($user['email'] ?? '') ?></strong></span>
|
||||
<button class="icon-control" type="button" data-theme-toggle aria-label="Toggle light and dark mode"><?= icon('sun') ?></button>
|
||||
<form method="post">
|
||||
<?= csrf_field() ?><input type="hidden" name="action" value="logout">
|
||||
<button class="icon-control" type="submit" aria-label="Sign out"><?= icon('logout') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php foreach ($flashes as $flash): ?>
|
||||
<div class="flash onboarding-flash <?= h($flash['type']) ?>" role="status">
|
||||
<span><?= $flash['type'] === 'success' ? '✓' : '!' ?></span>
|
||||
<p><?= h($flash['message']) ?></p>
|
||||
<button type="button" aria-label="Dismiss"><?= icon('close') ?></button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<main class="onboarding-main"><?= $content ?></main>
|
||||
<footer class="onboarding-footer">
|
||||
<span>Private by default</span>
|
||||
<span>SQLite powered · Your data stays under your control</span>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="/assets/app.js?v=<?= (int) filemtime(APP_ROOT . '/public/assets/app.js') ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user