aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/templates
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/templates')
-rw-r--r--internal/admin/templates/duplicate-rooms.html93
-rw-r--r--internal/admin/templates/layout.html1
2 files changed, 94 insertions, 0 deletions
diff --git a/internal/admin/templates/duplicate-rooms.html b/internal/admin/templates/duplicate-rooms.html
new file mode 100644
index 0000000..4e603bb
--- /dev/null
+++ b/internal/admin/templates/duplicate-rooms.html
@@ -0,0 +1,93 @@
+{{define "body-duplicate-rooms"}}
+<style>
+.dup-body{max-width:800px;margin:40px auto;font-family:monospace}
+.dup-body h1{color:var(--danger)}
+.dup-body p.hint{color:#aaa;margin-bottom:20px;line-height:1.6}
+.dup-group{border:1px solid var(--border);border-radius:5px;margin-bottom:12px;overflow:hidden}
+.dup-group-header{background:rgba(192,57,43,.15);padding:8px 12px;font-size:13px;font-weight:bold;color:var(--danger)}
+.dup-row{display:flex;align-items:center;gap:8px;padding:6px 12px;border-top:1px solid rgba(255,255,255,.03);font-size:11px}
+.dup-row .dup-path{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
+.dup-row .dup-path code{font-size:10px;color:#6cf}
+.dup-row input{width:80px;padding:3px 5px;font-size:11px;background:var(--input-bg);color:var(--text);border:1px solid var(--input-border);border-radius:3px;font-family:monospace}
+.dup-row button{padding:3px 8px;font-size:11px;white-space:nowrap}
+.dup-actions{margin:20px 0;display:flex;gap:8px;align-items:center}
+.dup-actions .dup-count{color:#888;font-size:11px;flex:1}
+.dup-none{color:var(--success);font-size:14px;text-align:center;margin:30px 0}
+</style>
+<div class="dup-body">
+ <h1>Duplicate Room IDs Detected</h1>
+ <p class="hint">
+ The following room IDs appear in multiple files. This corrupts the map and makes
+ the editor unreliable. Delete extra copies or rename them to new unique IDs.
+ </p>
+ <div id="dupList"><p style="color:#888;text-align:center">Loading…</p></div>
+ <div class="dup-actions">
+ <button class="btn btn-primary" onclick="checkDups()">Re-check</button>
+ <span class="dup-count" id="dupCount"></span>
+ <button class="btn btn-success" id="continueBtn" style="display:none" onclick="window.location='/'">Continue to Map Editor</button>
+ </div>
+ <div id="dupMsg" style="margin-top:12px"></div>
+</div>
+<script>
+function checkDups() {
+ var listEl = document.getElementById('dupList');
+ listEl.innerHTML = '<p style="color:#888;text-align:center">Loading…</p>';
+ API.get('/api/duplicate-rooms').then(function(data) {
+ var dups = data.duplicates || [];
+ document.getElementById('dupCount').textContent = dups.length + ' duplicate group' + (dups.length !== 1 ? 's' : '');
+ var continueBtn = document.getElementById('continueBtn');
+ continueBtn.style.display = dups.length === 0 ? 'inline-block' : 'none';
+
+ if (dups.length === 0) {
+ document.getElementById('dupMsg').innerHTML = '';
+ listEl.innerHTML = '<div class="dup-none">No duplicate room IDs found.</div>';
+ return;
+ }
+ var html = '';
+ dups.forEach(function(d) {
+ html += '<div class="dup-group"><div class="dup-group-header">Room ID: ' + esc(d.id) + ' (' + d.paths.length + ' copies)</div>';
+ d.paths.forEach(function(p, idx) {
+ var short = p.replace(/^.*\/data\/rooms\//, '');
+ html += '<div class="dup-row">';
+ html += '<span class="dup-path"><code>' + esc(short) + '</code></span>';
+ html += '<button class="btn btn-sm btn-danger" onclick="deleteDupFile(\'' + escAttr(p) + '\')">Delete</button>';
+ html += '<input type="number" id="rename-' + escAttr(d.id) + '-' + idx + '" placeholder="new ID" style="width:80px">';
+ html += '<button class="btn btn-sm btn-primary" onclick="renameDupFile(\'' + escAttr(p) + '\',\'rename-' + escAttr(d.id) + '-' + idx + '\')">Rename</button>';
+ html += '</div>';
+ });
+ html += '</div>';
+ });
+ listEl.innerHTML = html;
+ }).catch(function(e) {
+ listEl.innerHTML = '<p style="color:var(--danger)">Failed to load: ' + esc(e.message) + '</p>';
+ });
+}
+
+function deleteDupFile(path) {
+ if (!confirm('Delete this file?\n\n' + path)) return;
+ API.post('/api/rooms/resolve-duplicate', {path: path, action: 'delete'}).then(function() {
+ notify('Deleted', 'success');
+ checkDups();
+ }).catch(function(e) {
+ notify('Delete failed: ' + e.message, 'error');
+ });
+}
+
+function renameDupFile(path, inputId) {
+ var el = document.getElementById(inputId);
+ var newID = parseInt(el.value, 10);
+ if (!newID || newID <= 0) { notify('Enter a valid new room ID', 'error'); return; }
+ if (!confirm('Rename this file to ID ' + newID + '?\n\n' + path)) return;
+ API.post('/api/rooms/resolve-duplicate', {path: path, action: 'rename', new_id: newID}).then(function() {
+ notify('Renamed to ' + newID, 'success');
+ checkDups();
+ }).catch(function(e) {
+ notify('Rename failed: ' + e.message, 'error');
+ });
+}
+
+function esc(s) { return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
+function escAttr(s) { return String(s || '').replace(/&/g,'&amp;').replace(/"/g,'&quot;'); }
+checkDups();
+</script>
+{{end}}
diff --git a/internal/admin/templates/layout.html b/internal/admin/templates/layout.html
index ed939bd..410c8df 100644
--- a/internal/admin/templates/layout.html
+++ b/internal/admin/templates/layout.html
@@ -42,6 +42,7 @@
{{else if eq .Page "players"}}{{template "body-players" .}}
{{else if eq .Page "dashboard"}}{{template "body-dashboard" .}}
{{else if eq .Page "files"}}{{template "body-files" .}}
+{{else if eq .Page "duplicate-rooms"}}{{template "body-duplicate-rooms" .}}
{{else}}<p style="color:#888;text-align:center;margin-top:60px">Unknown page: {{.Page}}</p>{{end}}
</body>
</html>