Move viewer export/import into a dedicated Backup tab.
Keeps game save import in the sidebar while grouping viewer database backup actions with their explanation in the main navigation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -113,6 +113,8 @@ function applyStaticI18n() {
|
|||||||
document.querySelectorAll("[data-i18n]").forEach((el) => {
|
document.querySelectorAll("[data-i18n]").forEach((el) => {
|
||||||
el.textContent = t(el.dataset.i18n);
|
el.textContent = t(el.dataset.i18n);
|
||||||
});
|
});
|
||||||
|
const exportEl = document.getElementById("export-viewer");
|
||||||
|
if (exportEl) exportEl.title = t("viewerDb.exportHint");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupLanguage() {
|
function setupLanguage() {
|
||||||
@@ -146,6 +148,7 @@ function activateTab(tab) {
|
|||||||
document.getElementById(`tab-${tab}`).classList.add("active");
|
document.getElementById(`tab-${tab}`).classList.add("active");
|
||||||
if (tab === "history") loadHistoryTab();
|
if (tab === "history") loadHistoryTab();
|
||||||
if (tab === "goals") trackEvent("Goals Tab");
|
if (tab === "goals") trackEvent("Goals Tab");
|
||||||
|
if (tab === "backup") trackEvent("Backup Tab");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupNav() {
|
function setupNav() {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
"equipment": "Ausrüstung",
|
"equipment": "Ausrüstung",
|
||||||
"quests": "Quests",
|
"quests": "Quests",
|
||||||
"combat": "Kampf",
|
"combat": "Kampf",
|
||||||
"history": "Verlauf"
|
"history": "Verlauf",
|
||||||
|
"backup": "Backup"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"language": "Sprache",
|
"language": "Sprache",
|
||||||
@@ -229,6 +230,7 @@
|
|||||||
"title": "Viewer-Backup",
|
"title": "Viewer-Backup",
|
||||||
"helpTitle": "Was ist das?",
|
"helpTitle": "Was ist das?",
|
||||||
"helpBody": "Der Viewer speichert importierte Spiel-Backups, Verlaufsdiagramme und Ziele in einer SQLite-Datenbank auf dem Server. Export lädt diese Datenbank als Backup herunter. Import stellt sie wieder her und ersetzt alle aktuellen Viewer-Daten. Das ist nicht dasselbe wie ein Spiel-Backup (.json) importieren.",
|
"helpBody": "Der Viewer speichert importierte Spiel-Backups, Verlaufsdiagramme und Ziele in einer SQLite-Datenbank auf dem Server. Export lädt diese Datenbank als Backup herunter. Import stellt sie wieder her und ersetzt alle aktuellen Viewer-Daten. Das ist nicht dasselbe wie ein Spiel-Backup (.json) importieren.",
|
||||||
|
"gameBackupNote": "Um einen neuen Spielstand hinzuzufügen, nutze in der Sidebar „Spiel-Backup importieren“.",
|
||||||
"exportHint": "SQLite-Datenbank mit allen Snapshots, Verläufen und Zielen herunterladen",
|
"exportHint": "SQLite-Datenbank mit allen Snapshots, Verläufen und Zielen herunterladen",
|
||||||
"importConfirm": "Alle aktuellen Viewer-Daten (Snapshots, Verlauf, Ziele) werden durch die importierte .db-Datei ersetzt. Fortfahren?",
|
"importConfirm": "Alle aktuellen Viewer-Daten (Snapshots, Verlauf, Ziele) werden durch die importierte .db-Datei ersetzt. Fortfahren?",
|
||||||
"importSuccess": "Viewer wiederhergestellt: {snapshots} Snapshot(s), {goals} Ziel(e).",
|
"importSuccess": "Viewer wiederhergestellt: {snapshots} Snapshot(s), {goals} Ziel(e).",
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
"equipment": "Equipment",
|
"equipment": "Equipment",
|
||||||
"quests": "Quests",
|
"quests": "Quests",
|
||||||
"combat": "Combat",
|
"combat": "Combat",
|
||||||
"history": "History"
|
"history": "History",
|
||||||
|
"backup": "Backup"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
@@ -229,6 +230,7 @@
|
|||||||
"title": "Viewer backup",
|
"title": "Viewer backup",
|
||||||
"helpTitle": "What is this?",
|
"helpTitle": "What is this?",
|
||||||
"helpBody": "The viewer stores imported game backups, history charts, and goals in a SQLite database on the server. Export downloads that database as a backup. Import restores it and replaces all current viewer data. This is not the same as importing a game save (.json).",
|
"helpBody": "The viewer stores imported game backups, history charts, and goals in a SQLite database on the server. Export downloads that database as a backup. Import restores it and replaces all current viewer data. This is not the same as importing a game save (.json).",
|
||||||
|
"gameBackupNote": "To add a new game save snapshot, use Import game backup in the sidebar.",
|
||||||
"exportHint": "Download the SQLite database with all snapshots, history, and goals",
|
"exportHint": "Download the SQLite database with all snapshots, history, and goals",
|
||||||
"importConfirm": "All current viewer data (snapshots, history, goals) will be replaced by the imported .db file. Continue?",
|
"importConfirm": "All current viewer data (snapshots, history, goals) will be replaced by the imported .db file. Continue?",
|
||||||
"importSuccess": "Viewer restored: {snapshots} snapshot(s), {goals} goal(s).",
|
"importSuccess": "Viewer restored: {snapshots} snapshot(s), {goals} goal(s).",
|
||||||
|
|||||||
+24
-25
@@ -1028,35 +1028,34 @@ tr.has-goal td:first-child { font-weight: 600; }
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-backup-block {
|
.backup-tab-card {
|
||||||
margin-top: 4px;
|
max-width: 560px;
|
||||||
padding-top: 14px;
|
}
|
||||||
border-top: 1px solid var(--border);
|
.backup-tab-card h3 {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
.backup-tab-lead,
|
||||||
|
.backup-tab-note {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.backup-tab-note {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--bg-hover);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.backup-tab-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
.sidebar-backup-label {
|
.backup-tab-actions .upload-btn {
|
||||||
margin: 0;
|
width: 100%;
|
||||||
font-size: 0.72rem;
|
|
||||||
font-weight: 700;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
.sidebar-backup-help {
|
|
||||||
margin-top: 2px;
|
|
||||||
font-size: 0.78rem;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
.sidebar-backup-help summary {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--accent);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.sidebar-backup-help p {
|
|
||||||
margin: 8px 0 0;
|
|
||||||
line-height: 1.45;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.goal-modal {
|
.goal-modal {
|
||||||
|
|||||||
+15
-12
@@ -29,6 +29,7 @@
|
|||||||
<button class="nav-btn" data-tab="quests" data-i18n="nav.quests">Quests</button>
|
<button class="nav-btn" data-tab="quests" data-i18n="nav.quests">Quests</button>
|
||||||
<button class="nav-btn" data-tab="combat" data-i18n="nav.combat">Combat</button>
|
<button class="nav-btn" data-tab="combat" data-i18n="nav.combat">Combat</button>
|
||||||
<button class="nav-btn" data-tab="history" data-i18n="nav.history">History</button>
|
<button class="nav-btn" data-tab="history" data-i18n="nav.history">History</button>
|
||||||
|
<button class="nav-btn" data-tab="backup" data-i18n="nav.backup">Backup</button>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="sidebar-footer">
|
<div class="sidebar-footer">
|
||||||
<label class="lang-label" for="locale-select">
|
<label class="lang-label" for="locale-select">
|
||||||
@@ -43,18 +44,6 @@
|
|||||||
<span data-i18n="actions.importBackup">Import game backup</span>
|
<span data-i18n="actions.importBackup">Import game backup</span>
|
||||||
<input type="file" id="file-upload" accept=".json" hidden>
|
<input type="file" id="file-upload" accept=".json" hidden>
|
||||||
</label>
|
</label>
|
||||||
<div class="sidebar-backup-block">
|
|
||||||
<p class="sidebar-backup-label" data-i18n="viewerDb.title">Viewer backup</p>
|
|
||||||
<a class="upload-btn export-btn" id="export-viewer" href="#" data-i18n="actions.exportViewer">Export viewer</a>
|
|
||||||
<label class="upload-btn">
|
|
||||||
<span data-i18n="actions.importViewer">Import viewer</span>
|
|
||||||
<input type="file" id="viewer-db-upload" accept=".db,application/octet-stream" hidden>
|
|
||||||
</label>
|
|
||||||
<details class="sidebar-backup-help">
|
|
||||||
<summary data-i18n="viewerDb.helpTitle">What is this?</summary>
|
|
||||||
<p data-i18n="viewerDb.helpBody">The viewer stores imported game backups, history charts, and goals in a SQLite database on the server. Export downloads that database as a backup. Import restores it and replaces all current viewer data. This is not the same as importing a game save (.json).</p>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
@@ -90,6 +79,20 @@
|
|||||||
<section class="tab-panel" id="tab-quests"></section>
|
<section class="tab-panel" id="tab-quests"></section>
|
||||||
<section class="tab-panel" id="tab-combat"></section>
|
<section class="tab-panel" id="tab-combat"></section>
|
||||||
<section class="tab-panel" id="tab-history"></section>
|
<section class="tab-panel" id="tab-history"></section>
|
||||||
|
<section class="tab-panel" id="tab-backup">
|
||||||
|
<div class="card backup-tab-card">
|
||||||
|
<h3 data-i18n="viewerDb.title">Viewer backup</h3>
|
||||||
|
<p class="backup-tab-lead" data-i18n="viewerDb.helpBody">The viewer stores imported game backups, history charts, and goals in a SQLite database on the server. Export downloads that database as a backup. Import restores it and replaces all current viewer data. This is not the same as importing a game save (.json).</p>
|
||||||
|
<p class="backup-tab-note" data-i18n="viewerDb.gameBackupNote">To add a new game save snapshot, use Import game backup in the sidebar.</p>
|
||||||
|
<div class="backup-tab-actions">
|
||||||
|
<a class="upload-btn export-btn" id="export-viewer" href="#" data-i18n="actions.exportViewer">Export viewer</a>
|
||||||
|
<label class="upload-btn">
|
||||||
|
<span data-i18n="actions.importViewer">Import viewer</span>
|
||||||
|
<input type="file" id="viewer-db-upload" accept=".db,application/octet-stream" hidden>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<div id="goal-modal" class="goal-modal" hidden>
|
<div id="goal-modal" class="goal-modal" hidden>
|
||||||
|
|||||||
Reference in New Issue
Block a user