feat: 모바일 UX 대폭 개선 + PWA 구현 + 로그인 루프 수정
- 모바일 하단 네비: 메뉴 제거, 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>
This commit is contained in:
73
system1-factory/web/sw.js
Normal file
73
system1-factory/web/sw.js
Normal file
@@ -0,0 +1,73 @@
|
||||
// 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);
|
||||
})
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user