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