Skip to content

Commit 5e7291a

Browse files
authored
Refactor project management functions and HTML rendering
1 parent b3c41e7 commit 5e7291a

1 file changed

Lines changed: 29 additions & 39 deletions

File tree

‎js/projects.js‎

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
(function () {
22
'use strict';
33

4-
var LS_KEY = 'dtd_projects';
4+
/* Shared helpers (/js/shared.js): 0.1.0 output, old-key migration, safe embedding */
5+
var buildHTML = DTD.buildHTML;
6+
var loadProjects = DTD.loadProjects;
7+
var saveProjects = DTD.saveProjects;
8+
var esc = DTD.esc;
59

6-
function loadProjects() {
7-
try { return JSON.parse(localStorage.getItem(LS_KEY) || '[]'); } catch (e) { return []; }
8-
}
9-
function saveProjects(arr) {
10-
try { localStorage.setItem(LS_KEY, JSON.stringify(arr)); } catch (e) {}
11-
}
1210
function fmt(ts) {
1311
var d = new Date(ts);
1412
return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' }) +
1513
' · ' + d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });
1614
}
17-
function esc(s) {
18-
return String(s || '').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
19-
}
20-
function buildHTML(c) {
21-
return '<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width,initial-scale=1">\n<title>' + (c.logoName||'Page') + '</title>\n<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/devtemdesign@0.0.2/style.css">\n<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">\n<script src="https://cdn.jsdelivr.net/npm/devtemdesign@0.0.2/script.js"><\/script>\n</head>\n<body>\n<div id="app"></div>\n<script>devtemDesign("app",' + JSON.stringify(c) + ');<\/script>\n</body>\n</html>';
22-
}
2315

2416
/* ── THEME ── */
2517
document.getElementById('btn-dark').addEventListener('click', function () {
@@ -41,10 +33,9 @@
4133
var modalEditBtn = document.getElementById('modal-edit-btn');
4234
var modalExportBtn = document.getElementById('modal-export-btn');
4335
var _modalCfg = null;
44-
var _modalId = null;
4536

4637
function openModal(id, name, cfg) {
47-
_modalCfg = cfg; _modalId = id;
38+
_modalCfg = cfg;
4839
modalTitle.textContent = name;
4940
modalFrame.srcdoc = buildHTML(cfg);
5041
modalEditBtn.href = '/builder?id=' + id;
@@ -59,30 +50,29 @@
5950
});
6051
modalExportBtn.addEventListener('click', function () {
6152
if (!_modalCfg) return;
62-
var html = buildHTML(_modalCfg);
63-
var name = (_modalCfg.logoName||'page').toLowerCase().replace(/\s+/g,'-');
64-
var blob = new Blob([html],{type:'text/html'});
53+
var name = (_modalCfg.logoName || 'page').toLowerCase().replace(/\s+/g, '-');
54+
var blob = new Blob([buildHTML(_modalCfg)], { type: 'text/html' });
6555
var a = document.createElement('a');
66-
a.href = URL.createObjectURL(blob); a.download = name+'.html'; a.click();
56+
a.href = URL.createObjectURL(blob); a.download = name + '.html'; a.click();
6757
URL.revokeObjectURL(a.href);
6858
});
6959
document.addEventListener('keydown', function (e) {
7060
if (e.key === 'Escape' && previewModal.classList.contains('open')) modalClose.click();
7161
});
7262

7363
/* ── RENDER ── */
74-
var grid = document.getElementById('projects-grid');
75-
var emptyState = document.getElementById('empty-state');
76-
var countBadge = document.getElementById('count-badge');
77-
var searchInput= document.getElementById('search-input');
64+
var grid = document.getElementById('projects-grid');
65+
var emptyState = document.getElementById('empty-state');
66+
var countBadge = document.getElementById('count-badge');
67+
var searchInput = document.getElementById('search-input');
7868

7969
function render(filter) {
8070
var list = loadProjects();
8171
if (filter) {
8272
var f = filter.toLowerCase();
8373
list = list.filter(function (p) { return p.name.toLowerCase().includes(f); });
8474
}
85-
countBadge.textContent = loadProjects().length; // always real count
75+
countBadge.textContent = loadProjects().length; // always the real count
8676

8777
if (list.length === 0) {
8878
emptyState.style.display = 'flex';
@@ -91,26 +81,25 @@
9181
}
9282
emptyState.style.display = 'none';
9383

94-
// Sort newest first
95-
list = list.slice().sort(function (a, b) { return b.updatedAt - a.updatedAt; });
84+
list = list.slice().sort(function (a, b) { return b.updatedAt - a.updatedAt; }); // newest first
9685

9786
grid.innerHTML = list.map(function (p) {
98-
return '<div class="proj-card" data-id="' + p.id + '">' +
99-
'<div class="proj-thumb" data-preview-id="' + p.id + '">' +
100-
'<iframe srcdoc="' + esc(buildHTML(p.config)) + '" sandbox="allow-scripts allow-same-origin"></iframe>' +
101-
'<div class="proj-thumb-overlay"><button class="ov-btn" data-preview-id="' + p.id + '"><i class="fas fa-eye"></i> Preview</button></div>' +
87+
return '<div class="proj-card" data-id="' + esc(p.id) + '">' +
88+
'<div class="proj-thumb" data-preview-id="' + esc(p.id) + '">' +
89+
'<iframe srcdoc="' + esc(buildHTML(p.config, true)) + '" sandbox="allow-scripts allow-same-origin" loading="lazy" title="' + esc(p.name) + '"></iframe>' +
90+
'<div class="proj-thumb-overlay"><button class="ov-btn" data-preview-id="' + esc(p.id) + '"><i class="fas fa-eye"></i> Preview</button></div>' +
10291
'</div>' +
10392
'<div class="proj-body">' +
10493
'<div class="proj-name-row">' +
105-
'<span class="proj-name" data-rename-id="' + p.id + '">' + esc(p.name) + '</span>' +
106-
'<input class="proj-name-input" type="text" value="' + esc(p.name) + '" data-rename-input="' + p.id + '" maxlength="60">' +
107-
'<span class="proj-tpl">' + esc(p.config.template||'figsh') + '</span>' +
94+
'<span class="proj-name" data-rename-id="' + esc(p.id) + '">' + esc(p.name) + '</span>' +
95+
'<input class="proj-name-input" type="text" value="' + esc(p.name) + '" data-rename-input="' + esc(p.id) + '" maxlength="60">' +
96+
'<span class="proj-tpl">' + esc(p.config.template || 'figsh') + '</span>' +
10897
'</div>' +
10998
'<div class="proj-meta">' + fmt(p.updatedAt) + '</div>' +
11099
'<div class="proj-actions">' +
111-
'<a class="pa-btn" href="/builder?id=' + p.id + '"><i class="fas fa-pen"></i> Edit</a>' +
112-
'<button class="pa-btn" data-preview-id="' + p.id + '"><i class="fas fa-eye"></i> Preview</button>' +
113-
'<button class="pa-btn danger" data-delete-id="' + p.id + '"><i class="fas fa-trash"></i> Delete</button>' +
100+
'<a class="pa-btn" href="/builder?id=' + esc(p.id) + '"><i class="fas fa-pen"></i> Edit</a>' +
101+
'<button class="pa-btn" data-preview-id="' + esc(p.id) + '"><i class="fas fa-eye"></i> Preview</button>' +
102+
'<button class="pa-btn danger" data-delete-id="' + esc(p.id) + '"><i class="fas fa-trash"></i> Delete</button>' +
114103
'</div>' +
115104
'</div>' +
116105
'</div>';
@@ -128,7 +117,7 @@
128117
function commit() {
129118
var val = inp.value.trim(); if (!val) { render(searchInput.value); return; }
130119
var id = inp.dataset.renameInput;
131-
var all = loadProjects(); var p = all.find(function(x){return x.id===id;});
120+
var all = loadProjects(); var p = all.find(function (x) { return x.id === id; });
132121
if (p) { p.name = val; saveProjects(all); }
133122
render(searchInput.value);
134123
}
@@ -144,7 +133,7 @@
144133
el.addEventListener('click', function (e) {
145134
e.preventDefault();
146135
var id = el.dataset.previewId;
147-
var all = loadProjects(); var p = all.find(function(x){return x.id===id;});
136+
var p = loadProjects().find(function (x) { return x.id === id; });
148137
if (p) openModal(p.id, p.name, p.config);
149138
});
150139
});
@@ -154,7 +143,7 @@
154143
btn.addEventListener('click', function () {
155144
if (!confirm('Delete "' + btn.closest('.proj-card').querySelector('.proj-name').textContent + '"?')) return;
156145
var id = btn.dataset.deleteId;
157-
saveProjects(loadProjects().filter(function(x){return x.id!==id;}));
146+
saveProjects(loadProjects().filter(function (x) { return x.id !== id; }));
158147
render(searchInput.value);
159148
});
160149
});
@@ -164,3 +153,4 @@
164153
render();
165154

166155
})();
156+

0 commit comments

Comments
 (0)