Add: 캘린더 로딩 중 스피너 + 텍스트 표시 (ko/en/ja/zh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
68893236+KINDNICK@users.noreply.github.com 2026-03-18 01:25:46 +09:00
parent 3fc2cae788
commit 9923ef8989
2 changed files with 66 additions and 10 deletions

View File

@ -77,6 +77,7 @@
.cal-body { .cal-body {
display: grid; display: grid;
grid-template-columns: repeat(7, 1fr); grid-template-columns: repeat(7, 1fr);
position: relative;
} }
/* 날짜 셀 */ /* 날짜 셀 */
@ -302,24 +303,49 @@
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
} }
/* 로딩 상태 - 그리드 위에 펄스 효과 */ /* 로딩 상태 */
.cal-body.loading { .cal-body.loading {
position: relative; position: relative;
min-height: 280px;
} }
.cal-body.loading::after { .cal-body.loading::after {
content: ''; content: '';
position: absolute; position: absolute;
inset: 0; inset: 0;
background: rgba(255, 255, 255, 0.5); background: rgba(255, 255, 255, 0.7);
animation: pulse 1.2s ease-in-out infinite;
pointer-events: none; pointer-events: none;
z-index: 1; z-index: 1;
} }
@keyframes pulse { .cal-loading-overlay {
0%, 100% { opacity: 0.3; } position: absolute;
50% { opacity: 0.6; } inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 2;
gap: var(--spacing-md);
}
.cal-loading-overlay .loading-spinner {
width: 36px;
height: 36px;
border: 3px solid var(--border-light);
border-top-color: var(--primary-color);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.cal-loading-overlay .loading-text {
font-size: var(--font-sm);
color: var(--text-secondary);
font-weight: var(--font-weight-medium);
}
@keyframes spin {
to { transform: rotate(360deg); }
} }
/* ======================================== /* ========================================
@ -522,7 +548,16 @@
} }
[data-theme="dark"] .cal-body.loading::after { [data-theme="dark"] .cal-body.loading::after {
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.5);
}
[data-theme="dark"] .cal-loading-overlay .loading-spinner {
border-color: var(--glass-border);
border-top-color: var(--primary-color);
}
[data-theme="dark"] .cal-loading-overlay .loading-text {
color: var(--dark-text-secondary);
} }
/* ======================================== /* ========================================

View File

@ -39,18 +39,39 @@
if (cached !== null) { if (cached !== null) {
buildGrid(cached); buildGrid(cached);
} else { } else {
// 즉시 빈 그리드 렌더링 (체감 속도 향상) // 즉시 빈 그리드 렌더링 + 로딩 표시
buildGrid([]); buildGrid([]);
calBody.classList.add('loading'); showLoading();
fetchBookedDates(currentYear, currentMonth, function(dates) { fetchBookedDates(currentYear, currentMonth, function(dates) {
setCache(currentYear, currentMonth, dates); setCache(currentYear, currentMonth, dates);
buildGrid(dates); buildGrid(dates);
calBody.classList.remove('loading'); hideLoading();
prefetchAdjacent(); prefetchAdjacent();
}); });
} }
} }
function showLoading() {
calBody.classList.add('loading');
// 기존 오버레이 제거
var existing = calBody.querySelector('.cal-loading-overlay');
if (existing) existing.remove();
var lang = (window.i18n && window.i18n.currentLang) || 'ko';
var loadingTexts = { ko: '불러오는 중...', en: 'Loading...', ja: '読み込み中...', zh: '加载中...' };
var overlay = document.createElement('div');
overlay.className = 'cal-loading-overlay';
overlay.innerHTML = '<div class="loading-spinner"></div><span class="loading-text">' + (loadingTexts[lang] || loadingTexts.ko) + '</span>';
calBody.appendChild(overlay);
}
function hideLoading() {
calBody.classList.remove('loading');
var overlay = calBody.querySelector('.cal-loading-overlay');
if (overlay) overlay.remove();
}
function prefetchAdjacent() { function prefetchAdjacent() {
var nextM = currentMonth + 1, nextY = currentYear; var nextM = currentMonth + 1, nextY = currentYear;
if (nextM > 12) { nextM = 1; nextY++; } if (nextM > 12) { nextM = 1; nextY++; }