fix: api/toast/timeAgo 함수를 body 스크립트보다 앞에 배치
스크립트 실행 순서: __INIT__ → 유틸함수 → 페이지 스크립트 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+17
-25
@@ -116,48 +116,40 @@ tr:hover td{background:rgba(255,255,255,.02)}
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<%- typeof ssrData !== 'undefined' ? ssrData : '' %>
|
<%- typeof ssrData !== 'undefined' ? ssrData : '' %>
|
||||||
<%- body %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="toast" id="toast"></div>
|
|
||||||
<script>
|
<script>
|
||||||
function api(method, url, data) {
|
function api(method, url, data) {
|
||||||
const opts = { method, headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin' };
|
var opts = { method: method, headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin' };
|
||||||
if (data) opts.body = JSON.stringify(data);
|
if (data) opts.body = JSON.stringify(data);
|
||||||
return fetch(url, opts).then(r => {
|
return fetch(url, opts).then(function(r) {
|
||||||
const ct = r.headers.get('content-type') || '';
|
var ct = r.headers.get('content-type') || '';
|
||||||
if (r.status === 401) {
|
if (r.status === 401) { window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname); return []; }
|
||||||
window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);
|
if (!ct.includes('application/json')) { console.error('API non-JSON:', r.status); return []; }
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if (!ct.includes('application/json')) {
|
|
||||||
console.error('API returned non-JSON:', r.status, ct);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return r.json();
|
return r.json();
|
||||||
}).catch(err => {
|
}).catch(function(err) { console.error('API Error:', err); return []; });
|
||||||
console.error('API Error:', err);
|
|
||||||
return [];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
function toast(msg, type = 'success') {
|
function toast(msg, type) {
|
||||||
const el = document.getElementById('toast');
|
type = type || 'success';
|
||||||
|
var el = document.getElementById('toast');
|
||||||
el.textContent = msg;
|
el.textContent = msg;
|
||||||
el.style.borderLeftColor = type === 'success' ? 'var(--success)' : type === 'error' ? 'var(--danger)' : 'var(--warning)';
|
el.style.borderLeftColor = type === 'success' ? 'var(--success)' : type === 'error' ? 'var(--danger)' : 'var(--warning)';
|
||||||
el.style.borderLeftWidth = '3px';
|
el.style.borderLeftWidth = '3px';
|
||||||
el.classList.add('show');
|
el.classList.add('show');
|
||||||
setTimeout(() => el.classList.remove('show'), 3000);
|
setTimeout(function() { el.classList.remove('show'); }, 3000);
|
||||||
}
|
}
|
||||||
function timeAgo(dateStr) {
|
function timeAgo(dateStr) {
|
||||||
if (!dateStr) return '-';
|
if (!dateStr) return '-';
|
||||||
const diff = Date.now() - new Date(dateStr).getTime();
|
var diff = Date.now() - new Date(dateStr).getTime();
|
||||||
const m = Math.floor(diff / 60000);
|
var m = Math.floor(diff / 60000);
|
||||||
if (m < 1) return '방금';
|
if (m < 1) return '방금';
|
||||||
if (m < 60) return m + '분 전';
|
if (m < 60) return m + '분 전';
|
||||||
const h = Math.floor(m / 60);
|
var h = Math.floor(m / 60);
|
||||||
if (h < 24) return h + '시간 전';
|
if (h < 24) return h + '시간 전';
|
||||||
return Math.floor(h / 24) + '일 전';
|
return Math.floor(h / 24) + '일 전';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<%- body %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toast" id="toast"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user