From 41b7eb9ae405b444250b1755f4672c8cd56c2eea Mon Sep 17 00:00:00 2001 From: judymoody59 Date: Fri, 6 Jun 2025 17:02:43 +0900 Subject: [PATCH 1/2] =?UTF-8?q?KW-599/fix:=20QR=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=8F=8C=EC=95=84=EA=B0=80=EA=B8=B0=20?= =?UTF-8?q?=EC=8B=9C=20ZoneSelectMainZoneCard=EA=B0=80=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/building/BuildingLoginCard.tsx | 1 + src/components/buttons/LogoutButton.tsx | 2 ++ src/components/zone/ZoneLoginCard.tsx | 1 + src/contexts/axiosWithAuthorization.tsx | 3 +- src/pages/QRCodeScanner.tsx | 3 +- src/pages/ZoneSelectPage.tsx | 30 +++++++++++++------ 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/components/building/BuildingLoginCard.tsx b/src/components/building/BuildingLoginCard.tsx index 2847799..fcf7155 100644 --- a/src/components/building/BuildingLoginCard.tsx +++ b/src/components/building/BuildingLoginCard.tsx @@ -28,6 +28,7 @@ const BuildingLoginCard: React.FC = ({ onSwitch: _, isExiting, direction, if (token) { localStorage.setItem("accessToken", token); onLogin(); + sessionStorage.clear(); navigate("/building/select"); } else { setError("로그인 실패: 엑세스 토큰이 없음"); diff --git a/src/components/buttons/LogoutButton.tsx b/src/components/buttons/LogoutButton.tsx index 4b80188..d10a015 100644 --- a/src/components/buttons/LogoutButton.tsx +++ b/src/components/buttons/LogoutButton.tsx @@ -14,9 +14,11 @@ const LogoutButton: React.FC = () => { try { await adminLogout(); localStorage.clear(); + sessionStorage.clear(); navigate("/login"); } catch (err: any) { localStorage.clear(); + sessionStorage.clear(); const message = err?.message ?? "로그아웃 실패"; alert(message); console.warn("관리자 로그아웃 실패:", err); diff --git a/src/components/zone/ZoneLoginCard.tsx b/src/components/zone/ZoneLoginCard.tsx index f439364..607b3c4 100644 --- a/src/components/zone/ZoneLoginCard.tsx +++ b/src/components/zone/ZoneLoginCard.tsx @@ -28,6 +28,7 @@ const ZoneLoginCard: React.FC = ({ onSwitch: _, isExiting, direction, onL if (token) { localStorage.setItem("accessToken", token); onLogin(); + sessionStorage.clear(); navigate("/zone/select"); } else { setError("로그인 실패: 엑세스 토큰이 없음"); diff --git a/src/contexts/axiosWithAuthorization.tsx b/src/contexts/axiosWithAuthorization.tsx index 9edefb6..dfa33cd 100644 --- a/src/contexts/axiosWithAuthorization.tsx +++ b/src/contexts/axiosWithAuthorization.tsx @@ -72,7 +72,8 @@ axiosWithAuthorization.interceptors.response.use( } catch (refreshError) { console.error("엑세스 토큰 재발급 실패:", refreshError); localStorage.clear(); - window.location.href = "/admin/login"; + sessionStorage.clear(); + window.location.href = "/login"; return Promise.reject(refreshError); } } diff --git a/src/pages/QRCodeScanner.tsx b/src/pages/QRCodeScanner.tsx index 56e39c9..b117c1a 100644 --- a/src/pages/QRCodeScanner.tsx +++ b/src/pages/QRCodeScanner.tsx @@ -149,7 +149,8 @@ const QRCodeScanner = () => { console.error("카메라 정리 중 오류", err); } finally { scannerRef.current = null; - navigate(-1); + sessionStorage.setItem("zoneSelectStep", 'zone'); + navigate(-1); } } else { navigate(-1); diff --git a/src/pages/ZoneSelectPage.tsx b/src/pages/ZoneSelectPage.tsx index cdff79a..e149bd4 100644 --- a/src/pages/ZoneSelectPage.tsx +++ b/src/pages/ZoneSelectPage.tsx @@ -9,23 +9,32 @@ import ZoneSelectMainZoneCard from '../components/zone/ZoneSelectMainZoneCard'; import zonewrapperBackground from '../assets/images/zone-background.png'; const ZoneSelectPage: React.FC = () => { - const [buildingId, setBuildingId] = useState(null); - const [buildingName, setBuildingName] = useState(null); + const [buildingId, setBuildingId] = useState(sessionStorage.getItem("buildingId")); + const [buildingName, setBuildingName] = useState(sessionStorage.getItem("buildingName")); const [currentStep, setCurrentStep] = useState<'white' | 'building' | 'zone'>('white'); useEffect(() => { - const timer = setTimeout(() => { - setCurrentStep('building'); - }, 800); - - return () => clearTimeout(timer); + const savedStep = sessionStorage.getItem("zoneSelectStep") as 'white' | 'building' | 'zone' | null; + if (savedStep) { + setCurrentStep(savedStep); + } else { + const timer = setTimeout(() => { + setCurrentStep('building'); + sessionStorage.setItem("zoneSelectStep", 'building'); + }, 800); + return () => clearTimeout(timer); + } }, []); const handleNext = (selectedBuildingId: string, selectedBuildingName: string) => { setBuildingId(selectedBuildingId); setBuildingName(selectedBuildingName); localStorage.setItem("buildingName", selectedBuildingName); - setCurrentStep('zone'); + + sessionStorage.setItem("buildingId", selectedBuildingId); + sessionStorage.setItem("buildingName", selectedBuildingName); + sessionStorage.setItem("zoneSelectStep", 'zone'); + setCurrentStep('zone'); }; return ( @@ -43,7 +52,10 @@ const ZoneSelectPage: React.FC = () => { setCurrentStep('building')} + onBack={() => { + sessionStorage.setItem("zoneSelectStep", 'building'); + setCurrentStep('building'); + }} /> )} From cd48621a219fd5a3138b5575cd70c16f28b98e20 Mon Sep 17 00:00:00 2001 From: judymoody59 Date: Sat, 7 Jun 2025 15:11:21 +0900 Subject: [PATCH 2/2] =?UTF-8?q?KW-599/fix:=20ZoneSelectMainZoneCard?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=8F=8C=EC=95=84=EA=B0=80=EA=B8=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ZoneSelectMainZoneCard에서 돌아가기 시 ZoneSelectMainBuildingCard가 나오도록 수정 --- src/App.tsx | 2 +- .../zone/ZoneSelectMainZoneCard.tsx | 2 +- src/pages/ZoneSelectPage.tsx | 61 ++++++++++++++++--- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index a6a34c3..6833aa0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -72,7 +72,7 @@ function App() { }> } /> - } /> + } /> } /> diff --git a/src/components/zone/ZoneSelectMainZoneCard.tsx b/src/components/zone/ZoneSelectMainZoneCard.tsx index 53a5c43..5829abf 100644 --- a/src/components/zone/ZoneSelectMainZoneCard.tsx +++ b/src/components/zone/ZoneSelectMainZoneCard.tsx @@ -76,7 +76,7 @@ const ZoneSelectMainZoneCard: React.FC = ({ buildingId, buildingName, onB localStorage.setItem("deviceAreaCode", areaCode); localStorage.setItem("zoneName", areaName); localStorage.setItem("buildingName", buildingName); - navigate("/qr"); + navigate("/qr", { replace: false }); }; return ( diff --git a/src/pages/ZoneSelectPage.tsx b/src/pages/ZoneSelectPage.tsx index e149bd4..b6c9594 100644 --- a/src/pages/ZoneSelectPage.tsx +++ b/src/pages/ZoneSelectPage.tsx @@ -1,5 +1,6 @@ import './css/ZoneSelectPage.css'; import { useEffect, useState } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; import ZoneSelectGreenCard from '../components/zone/ZoneSelectGreenCard'; import ZoneSelectWhiteCard from '../components/zone/ZoneSelectWhiteCard'; @@ -9,9 +10,12 @@ import ZoneSelectMainZoneCard from '../components/zone/ZoneSelectMainZoneCard'; import zonewrapperBackground from '../assets/images/zone-background.png'; const ZoneSelectPage: React.FC = () => { + const navigate = useNavigate(); + const location = useLocation(); const [buildingId, setBuildingId] = useState(sessionStorage.getItem("buildingId")); const [buildingName, setBuildingName] = useState(sessionStorage.getItem("buildingName")); const [currentStep, setCurrentStep] = useState<'white' | 'building' | 'zone'>('white'); + const [isInternalChange, setIsInternalChange] = useState(false); useEffect(() => { const savedStep = sessionStorage.getItem("zoneSelectStep") as 'white' | 'building' | 'zone' | null; @@ -34,9 +38,57 @@ const ZoneSelectPage: React.FC = () => { sessionStorage.setItem("buildingId", selectedBuildingId); sessionStorage.setItem("buildingName", selectedBuildingName); sessionStorage.setItem("zoneSelectStep", 'zone'); + + setIsInternalChange(true); setCurrentStep('zone'); }; + const handleBack = () => { + sessionStorage.setItem("zoneSelectStep", 'building'); + setIsInternalChange(true); + setCurrentStep('building'); + }; + + useEffect(() => { + const handlePopState = () => { + const savedStep = sessionStorage.getItem("zoneSelectStep") as 'white' | 'building' | 'zone' | null; + if (savedStep) { + setCurrentStep(savedStep); + } else { + setCurrentStep('building'); + } + }; + + window.addEventListener('popstate', handlePopState); + return () => window.removeEventListener('popstate', handlePopState); + }, []); + + useEffect(() => { + if (!isInternalChange) return; + + if (currentStep === 'building' && location.pathname !== '/zone/select/building') { + navigate('/zone/select/building', { replace: false }); + } else if (currentStep === 'zone' && location.pathname !== '/zone/select/zone') { + navigate('/zone/select/zone', { replace: false }); + } + + setIsInternalChange(false); // reset flag + }, [currentStep, navigate, location.pathname, isInternalChange]); + + useEffect(() => { + if (location.pathname === '/zone/select') { + navigate('/zone/select/building', { replace: true }); + } + }, [location.pathname, navigate]); + + useEffect(() => { + if (location.pathname === '/zone/select/building') { + sessionStorage.setItem('zoneSelectStep', 'building'); + } else if (location.pathname === '/zone/select/zone') { + sessionStorage.setItem('zoneSelectStep', 'zone'); + } + }, [location.pathname]); + return (
{
{currentStep === 'white' && } - {currentStep === 'building' && ( - - )} + {currentStep === 'building' && } {currentStep === 'zone' && buildingId && buildingName && ( { - sessionStorage.setItem("zoneSelectStep", 'building'); - setCurrentStep('building'); - }} + onBack={handleBack} /> )}