- 모바일 하단 네비: 메뉴 제거, 4개 핵심 기능(홈/TBM/작업보고/출근) SVG 아이콘 - 모바일 사이드바 스킵: 768px 이하에서 사이드바 미로드, 레이아웃 오프셋 해결 - 모바일 헤더: 햄버거 메뉴 숨김, 본문 margin/overflow 정리 - TBM 모바일: 풀스크린 모달, 저장 버튼 하단 고정, 터치 UX 개선 - PWA: manifest.json, sw.js(network-first), 앱 아이콘, iOS 메타태그, 킬스위치 - 로그인 무한루프 수정: 토큰 만료 검증, 쿠키 정리, loginPage 경로 수정 - 신고 메뉴 tkreport 리다이렉트: navbar + sidebar cross-system-link 적용 - TBM API: 작업장별 안전점검 체크리스트 조회 엔드포인트 추가 - 안전점검 체크리스트 관리 UI 개선 - tkuser: 이슈유형 관리 기능 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74 lines
1.9 KiB
JavaScript
74 lines
1.9 KiB
JavaScript
// sw.js - TK공장관리 Service Worker (network-first)
|
|
// 주의: 이 파일을 수정할 때는 반드시 CACHE_VERSION을 올려주세요.
|
|
// 잘못된 수정은 사용자 브라우저에 최대 24시간 캐시됩니다.
|
|
// 자세한 내용: /docs/PWA-GUIDE.md
|
|
|
|
const CACHE_VERSION = 'tkfb-v3';
|
|
const CACHE_NAME = `tkfb-cache-${CACHE_VERSION}`;
|
|
|
|
// 캐시할 정적 리소스 (앱 셸)
|
|
const APP_SHELL = [
|
|
'/pages/dashboard.html',
|
|
'/css/design-system.css',
|
|
'/css/mobile.css',
|
|
'/img/icon-192x192.png'
|
|
];
|
|
|
|
// 설치: 앱 셸 프리캐시
|
|
self.addEventListener('install', (event) => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => cache.addAll(APP_SHELL))
|
|
.then(() => self.skipWaiting())
|
|
);
|
|
});
|
|
|
|
// 활성화: 이전 버전 캐시 삭제
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(
|
|
caches.keys()
|
|
.then((keys) => Promise.all(
|
|
keys
|
|
.filter((key) => key.startsWith('tkfb-cache-') && key !== CACHE_NAME)
|
|
.map((key) => caches.delete(key))
|
|
))
|
|
.then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
// 요청 가로채기: network-first 전략
|
|
self.addEventListener('fetch', (event) => {
|
|
const request = event.request;
|
|
|
|
// API 요청은 캐시하지 않음 (항상 네트워크)
|
|
if (request.url.includes('/api/')) {
|
|
return;
|
|
}
|
|
|
|
// 로그인 관련 경로는 캐시하지 않음
|
|
if (request.url.includes('/login')) {
|
|
return;
|
|
}
|
|
|
|
// GET 요청만 캐시
|
|
if (request.method !== 'GET') {
|
|
return;
|
|
}
|
|
|
|
event.respondWith(
|
|
fetch(request)
|
|
.then((response) => {
|
|
// 정상 응답이면 캐시에 저장
|
|
if (response.ok) {
|
|
const clone = response.clone();
|
|
caches.open(CACHE_NAME).then((cache) => cache.put(request, clone));
|
|
}
|
|
return response;
|
|
})
|
|
.catch(() => {
|
|
// 네트워크 실패 시 캐시에서 응답
|
|
return caches.match(request);
|
|
})
|
|
);
|
|
});
|