Tr_Code/static/app.js

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 직접 조회)
})();