Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function App() {

<Route element={<PrivateRoute />}>
<Route path="/building/select" element={<BuildingSelectPage />} />
<Route path="/zone/select" element={<ZoneSelectPage />} />
<Route path="/zone/select/*" element={<ZoneSelectPage />} />
<Route path="/qr" element={<QRCodeScanner />} />
</Route>
</Routes>
Expand Down
1 change: 1 addition & 0 deletions src/components/building/BuildingLoginCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const BuildingLoginCard: React.FC<Props> = ({ onSwitch: _, isExiting, direction,
if (token) {
localStorage.setItem("accessToken", token);
onLogin();
sessionStorage.clear();
navigate("/building/select");
} else {
setError("로그인 실패: 엑세스 토큰이 없음");
Expand Down
2 changes: 2 additions & 0 deletions src/components/buttons/LogoutButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/components/zone/ZoneLoginCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const ZoneLoginCard: React.FC<Props> = ({ onSwitch: _, isExiting, direction, onL
if (token) {
localStorage.setItem("accessToken", token);
onLogin();
sessionStorage.clear();
navigate("/zone/select");
} else {
setError("로그인 실패: 엑세스 토큰이 없음");
Expand Down
2 changes: 1 addition & 1 deletion src/components/zone/ZoneSelectMainZoneCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const ZoneSelectMainZoneCard: React.FC<Props> = ({ buildingId, buildingName, onB
localStorage.setItem("deviceAreaCode", areaCode);
localStorage.setItem("zoneName", areaName);
localStorage.setItem("buildingName", buildingName);
navigate("/qr");
navigate("/qr", { replace: false });
};

return (
Expand Down
3 changes: 2 additions & 1 deletion src/contexts/axiosWithAuthorization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/QRCodeScanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ const QRCodeScanner = () => {
console.error("카메라 정리 중 오류", err);
} finally {
scannerRef.current = null;
navigate(-1);
sessionStorage.setItem("zoneSelectStep", 'zone');
navigate(-1);
}
} else {
navigate(-1);
Expand Down
83 changes: 71 additions & 12 deletions src/pages/ZoneSelectPage.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -9,25 +10,85 @@ import ZoneSelectMainZoneCard from '../components/zone/ZoneSelectMainZoneCard';
import zonewrapperBackground from '../assets/images/zone-background.png';

const ZoneSelectPage: React.FC = () => {
const [buildingId, setBuildingId] = useState<string | null>(null);
const [buildingName, setBuildingName] = useState<string | null>(null);
const navigate = useNavigate();
const location = useLocation();
const [buildingId, setBuildingId] = useState<string | null>(sessionStorage.getItem("buildingId"));
const [buildingName, setBuildingName] = useState<string | null>(sessionStorage.getItem("buildingName"));
const [currentStep, setCurrentStep] = useState<'white' | 'building' | 'zone'>('white');
const [isInternalChange, setIsInternalChange] = useState(false);

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');

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 (
<div
className="zone-select-page-wrapper"
Expand All @@ -36,14 +97,12 @@ const ZoneSelectPage: React.FC = () => {
<div className="zone-select-page-card-wrapper">
<ZoneSelectGreenCard />
{currentStep === 'white' && <ZoneSelectWhiteCard />}
{currentStep === 'building' && (
<ZoneSelectMainBuildingCard onNext={handleNext} />
)}
{currentStep === 'building' && <ZoneSelectMainBuildingCard onNext={handleNext} />}
{currentStep === 'zone' && buildingId && buildingName && (
<ZoneSelectMainZoneCard
buildingId={buildingId}
buildingName={buildingName}
onBack={() => setCurrentStep('building')}
onBack={handleBack}
/>
)}
</div>
Expand Down