feat(nav): unified navbar, account page, corpus summary widget, and i18n fixes
- New includes/nav.php: sticky site-wide nav with Tools dropdown, Dashboard link, compact language switcher, user identity → /account.php, Log out - New account.php: credits & plan, profile, team, usage sections - New api/corpus-summary.php: JSON endpoint for corpus doc count + last updated - Replaces topbar in layout.php, layout_dashboard.php, and dashboard.php - Fixes hardcoded Norwegian strings in dashboard.php credit cards via dbnToolsT() - Adds 35 new i18n keys across all 4 languages (en/no/uk/pl) in i18n.php - CSS: .dbn-nav navbar + .account-* account page styles in tools.css Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+42
-37
@@ -47,68 +47,50 @@ window.DBN_TOOLS_AUTHENTICATED = true;
|
||||
window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
</script>
|
||||
|
||||
<?php include __DIR__ . '/includes/nav.php'; ?>
|
||||
|
||||
<main id="appShell" class="app-shell dashboard-shell">
|
||||
<header class="topbar">
|
||||
<div>
|
||||
<p class="eyebrow"><?= htmlspecialchars(dbnToolsT('brand_line', $uiLang)) ?></p>
|
||||
<h1><?= htmlspecialchars(dbnToolsT('dashboard_title', $uiLang)) ?></h1>
|
||||
<div class="case-no">
|
||||
<span class="pulse"></span>
|
||||
<span>family-legal</span>
|
||||
<span class="case-sep">.</span>
|
||||
<span><?= htmlspecialchars(dbnToolsT('retention', $uiLang)) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<nav class="shell-lang-switcher" aria-label="Language">
|
||||
<?php foreach (dbnToolsSupportedLanguages() as $langCode): ?>
|
||||
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
|
||||
<?php endforeach; ?>
|
||||
</nav>
|
||||
<span id="healthPill" class="status-pill"><?= htmlspecialchars(dbnToolsT('session_active', $uiLang)) ?></span>
|
||||
<?php if ($dashIsSso): ?>
|
||||
<a href="/billing.php" class="tier-pill" style="background: <?= htmlspecialchars($tierLabel[1]) ?>; color: <?= htmlspecialchars($tierLabel[2]) ?>; padding: 4px 12px; border-radius: 999px; font-size: 0.82rem; font-weight: 600; text-decoration: none;">
|
||||
<?= htmlspecialchars($tierLabel[0]) ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<button id="healthButton" class="secondary-button" type="button"><?= htmlspecialchars(dbnToolsT('health', $uiLang)) ?></button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ($dashIsSso && $dashDetail): ?>
|
||||
<section class="dashboard-status-row" style="display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap:1rem; margin: 1.5rem 0;">
|
||||
<div class="status-card" style="background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:1.1rem 1.25rem;">
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;">Tilgjengelige kreditter</p>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;"><?= htmlspecialchars(dbnToolsT('credits_available', $uiLang)) ?></p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.8rem; font-weight:700; color:#00205B;">
|
||||
<?php $eff = (int)$dashDetail['balance'] + (int)$dashDetail['bonus_balance']; ?>
|
||||
<?= number_format($eff, 0, ',', ' ') ?>
|
||||
</p>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem;"><?= (int)$dashDetail['balance'] ?> månedlige · <?= (int)$dashDetail['bonus_balance'] ?> bonus · <a href="/billing.php">Detaljer</a></p>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem;"><?= (int)$dashDetail['balance'] ?> <?= htmlspecialchars(dbnToolsT('credits_monthly', $uiLang)) ?> · <?= (int)$dashDetail['bonus_balance'] ?> <?= htmlspecialchars(dbnToolsT('credits_bonus', $uiLang)) ?> · <a href="/billing.php"><?= htmlspecialchars(dbnToolsT('details_link', $uiLang)) ?></a></p>
|
||||
</div>
|
||||
<?php if (in_array($dashTier, ['plus','pro'], true)): ?>
|
||||
<a class="status-card" href="/min-sak.php" style="background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:1.1rem 1.25rem; text-decoration:none; color:inherit;">
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;">Min sak</p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.4rem; font-weight:700; color:#00205B;">Bygg din egen sak →</p>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;"><?= htmlspecialchars(dbnToolsT('my_case', $uiLang)) ?></p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.4rem; font-weight:700; color:#00205B;"><?= htmlspecialchars(dbnToolsT('build_your_case', $uiLang)) ?> →</p>
|
||||
<?php
|
||||
$used = (int)$dashDetail['storage_used_bytes'];
|
||||
$quota = (int)$dashDetail['storage_quota_bytes'];
|
||||
$usedMb = $used > 0 ? round($used / 1048576, 1) : 0;
|
||||
$quotaMb = $quota > 0 ? round($quota / 1048576, 0) : 0;
|
||||
?>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem;"><?= $usedMb ?> MB / <?= $quotaMb ?> MB brukt</p>
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem;"><?= $usedMb ?> MB / <?= $quotaMb ?> MB</p>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a class="status-card" href="/pricing.php" style="background:linear-gradient(135deg,#00205B,#003478); color:#fff; border-radius:10px; padding:1.1rem 1.25rem; text-decoration:none;">
|
||||
<p style="margin:0; opacity:0.85; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;">Bygg din egen sak</p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.4rem; font-weight:700;">Last opp dokumenter →</p>
|
||||
<p style="margin:0; opacity:0.85; font-size:0.85rem;">Tilgjengelig fra Plus NOK 129/mnd</p>
|
||||
<p style="margin:0; opacity:0.85; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;"><?= htmlspecialchars(dbnToolsT('build_your_case', $uiLang)) ?></p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.4rem; font-weight:700;"><?= htmlspecialchars(dbnToolsT('upload_documents', $uiLang)) ?> →</p>
|
||||
<p style="margin:0; opacity:0.85; font-size:0.85rem;"><?= htmlspecialchars(dbnToolsT('upgrade_from_plus', $uiLang)) ?></p>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<!-- Corpus summary widget — populated via fetch('/api/corpus-summary.php') -->
|
||||
<a id="corpusSummaryCard" class="status-card" href="/dashboard/" style="background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:1.1rem 1.25rem; text-decoration:none; color:inherit; display:block;">
|
||||
<p style="margin:0; color:#6b7280; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em;"><?= htmlspecialchars(dbnToolsT('my_corpus', $uiLang)) ?></p>
|
||||
<p id="corpusDocCount" style="margin:0.35rem 0 0; font-size:1.4rem; font-weight:700; color:#00205B;">—</p>
|
||||
<p id="corpusUpdated" style="margin:0; color:#6b7280; font-size:0.85rem;"><?= htmlspecialchars(dbnToolsT('open_corpus', $uiLang)) ?> →</p>
|
||||
</a>
|
||||
<?php if ($showSurveyCta): ?>
|
||||
<a class="status-card" href="https://dobetternorge.no/survey.php" style="background:#fef3c7; color:#92400e; border-radius:10px; padding:1.1rem 1.25rem; text-decoration:none;">
|
||||
<p style="margin:0; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em; opacity:0.85;">Tjen 25 ekstra kreditter</p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.2rem; font-weight:700;">Ta vår 5-spørsmåls undersøkelse →</p>
|
||||
<p style="margin:0; font-size:0.85rem; opacity:0.85;">Ingen salgspitch — bare research</p>
|
||||
<p style="margin:0; font-size:0.85rem; text-transform:uppercase; letter-spacing:0.06em; opacity:0.85;"><?= htmlspecialchars(dbnToolsT('earn_credits_eyebrow', $uiLang)) ?></p>
|
||||
<p style="margin:0.35rem 0 0; font-size:1.2rem; font-weight:700;"><?= htmlspecialchars(dbnToolsT('survey_btn', $uiLang)) ?> →</p>
|
||||
<p style="margin:0; font-size:0.85rem; opacity:0.85;"><?= htmlspecialchars(dbnToolsT('survey_cta_text', $uiLang)) ?></p>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
@@ -246,5 +228,28 @@ foreach ($tools as $slug => $item):
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
<?php if ($dashIsSso): ?>
|
||||
<script>
|
||||
(function () {
|
||||
var card = document.getElementById('corpusSummaryCard');
|
||||
var countEl = document.getElementById('corpusDocCount');
|
||||
var updEl = document.getElementById('corpusUpdated');
|
||||
if (!card || !countEl) return;
|
||||
fetch('/api/corpus-summary.php')
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (data) {
|
||||
if (!data) return;
|
||||
countEl.textContent = data.doc_count !== undefined
|
||||
? data.doc_count.toLocaleString() + ' docs'
|
||||
: '—';
|
||||
if (data.last_updated && updEl) {
|
||||
var d = new Date(data.last_updated);
|
||||
updEl.textContent = d.toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric' });
|
||||
}
|
||||
})
|
||||
.catch(function () {});
|
||||
}());
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user