90 lines
3.1 KiB
JavaScript
90 lines
3.1 KiB
JavaScript
(function(){
|
|
// 테마 자동/토글
|
|
const THEME_KEY = 'theme-preference';
|
|
const themeToggle = document.getElementById('themeToggle');
|
|
|
|
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
|
|
const getPreferredTheme = () => localStorage.getItem(THEME_KEY) || 'auto';
|
|
|
|
const resolveTheme = (pref) => {
|
|
if (pref === 'dark' || pref === 'light') return pref;
|
|
return prefersDark && prefersDark.matches ? 'dark' : 'light';
|
|
};
|
|
|
|
const applyTheme = (themePref) => {
|
|
const theme = resolveTheme(themePref);
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
const meta = document.querySelector('meta[name="theme-color"]');
|
|
if (meta) meta.setAttribute('content', theme === 'dark' ? '#0b1220' : '#ffffff');
|
|
};
|
|
|
|
applyTheme(getPreferredTheme());
|
|
prefersDark && prefersDark.addEventListener('change', () => applyTheme(getPreferredTheme()));
|
|
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', () => {
|
|
const now = getPreferredTheme();
|
|
const next = now === 'dark' ? 'light' : now === 'light' ? 'auto' : 'dark';
|
|
localStorage.setItem(THEME_KEY, next);
|
|
applyTheme(next);
|
|
});
|
|
}
|
|
|
|
// htmx modal 지원
|
|
document.body.addEventListener('htmx:afterSwap', (e) => {
|
|
if (e.target.id === 'modal') {
|
|
const dlg = e.target;
|
|
if (typeof dlg.showModal === 'function') dlg.showModal();
|
|
}
|
|
});
|
|
document.body.addEventListener('click', (e) => {
|
|
const dlg = document.getElementById('modal');
|
|
if (dlg && e.target === dlg) {
|
|
dlg.close();
|
|
dlg.innerHTML = '';
|
|
}
|
|
});
|
|
|
|
// 탭 선택 상태 토글 (상단 섹션/서브탭)
|
|
document.addEventListener('click', (e) => {
|
|
const sectionTabBtn = e.target.closest('#topSections .tab-button');
|
|
const topTabBtn = e.target.closest('#tabs .tab-button');
|
|
const subTabBtn = e.target.closest('#subtabs .tab-button');
|
|
|
|
// 상단 섹션 탭: 선택 상태 토글
|
|
if (sectionTabBtn) {
|
|
document.querySelectorAll('#topSections .tab-button')
|
|
.forEach(x => x.setAttribute('aria-selected', 'false'));
|
|
sectionTabBtn.setAttribute('aria-selected', 'true');
|
|
}
|
|
|
|
// 상단 제조사 탭: 섹션 값 전달 + 선택 상태 토글
|
|
if (topTabBtn) {
|
|
const sectionRoot = document.getElementById('currentSectionRoot');
|
|
if (sectionRoot) topTabBtn.setAttribute('hx-vals', JSON.stringify({ section: sectionRoot.value }));
|
|
|
|
document.querySelectorAll('#tabs .tab-button')
|
|
.forEach(x => x.setAttribute('aria-selected', 'false'));
|
|
topTabBtn.setAttribute('aria-selected', 'true');
|
|
}
|
|
|
|
// 하위 서브탭: 선택 상태 토글
|
|
if (subTabBtn) {
|
|
document.querySelectorAll('#subtabs .tab-button')
|
|
.forEach(x => x.setAttribute('aria-selected', 'false'));
|
|
subTabBtn.setAttribute('aria-selected', 'true');
|
|
}
|
|
});
|
|
|
|
// PWA 등록
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', () => {
|
|
navigator.serviceWorker.register('/static/sw.js').catch(()=>{});
|
|
});
|
|
}
|
|
|
|
// 로컬 SQLite / PWA 동기화 제거됨 (Supabase 직접 조회)
|
|
})();
|
|
|
|
|