From 3d2598d35d4f7664fa024fca631635477e6fb825 Mon Sep 17 00:00:00 2001 From: judymoody59 Date: Wed, 11 Jun 2025 15:47:02 +0900 Subject: [PATCH 1/3] =?UTF-8?q?KW-653/fix:=20=EC=B6=9C=EC=9E=85=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=A0=95?= =?UTF-8?q?=EC=83=81=EC=9D=BC=20=EB=95=8C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=9B=84=20Warning=20=EB=A0=8C=EB=8D=94=EB=A7=81=20=EC=98=A4?= =?UTF-8?q?=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 --- src/components/_Admin/AdminLoginBox.tsx | 10 ++++++++-- src/contexts/PassLogContext.tsx | 13 +++++++++++-- src/pages/DashboardStats.tsx | 20 +++++++++++++++++++- src/pages/css/DashboardStats.css | 8 ++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/components/_Admin/AdminLoginBox.tsx b/src/components/_Admin/AdminLoginBox.tsx index 0069e8d..1c30f69 100644 --- a/src/components/_Admin/AdminLoginBox.tsx +++ b/src/components/_Admin/AdminLoginBox.tsx @@ -6,6 +6,7 @@ import ReusableInput from "../input/ReusableInput"; import { adminLogin } from "../../apis/loginApi"; import { fetchEntryPassLog } from "../../apis/passApi"; +import { usePassLogContext } from "../../contexts/PassLogContext.tsx"; interface AdminLoginProps { onLogin: () => void; @@ -16,6 +17,7 @@ const AdminLogin: React.FC = ({ onLogin }) => { const [password, setPassword] = useState(""); const [error, setError] = useState(""); const navigate = useNavigate(); + const { setIsPassLogAvailable, setHasCheckedAvailability } = usePassLogContext(); useEffect(() => { const darkMode = localStorage.getItem("theme") === "dark"; @@ -35,16 +37,20 @@ const AdminLogin: React.FC = ({ onLogin }) => { const token = response.accessToken; if (token) { localStorage.setItem("accessToken", token); + localStorage.setItem("skipFirstCheck", "true"); onLogin(); try { await fetchEntryPassLog(0); + setIsPassLogAvailable(true); + setHasCheckedAvailability(true); navigate("/dashboardstats"); } catch (error) { - console.error("<--- 출입 로그 조회 실패:", error); + console.error("<--- 출입 로그 조회 실패:", error); + setIsPassLogAvailable(false); + setHasCheckedAvailability(true); navigate("/admin/mypage"); } - } else { setError("로그인 실패: 엑세스 토큰이 없음"); } diff --git a/src/contexts/PassLogContext.tsx b/src/contexts/PassLogContext.tsx index cc6c2f2..50bfe79 100644 --- a/src/contexts/PassLogContext.tsx +++ b/src/contexts/PassLogContext.tsx @@ -3,27 +3,34 @@ import { fetchEntryPassLog } from '../apis/passApi'; export interface PassLogContextType { isPassLogAvailable: boolean; + hasCheckedAvailability: boolean; checkAccessLogAvailability: () => Promise; setIsPassLogAvailable: React.Dispatch>; + setHasCheckedAvailability: React.Dispatch>; } export const PassLogContext = createContext({ isPassLogAvailable: true, + hasCheckedAvailability: false, checkAccessLogAvailability: async () => false, setIsPassLogAvailable: () => {}, + setHasCheckedAvailability: () => {}, }); export const PassLogProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [isPassLogAvailable, setIsPassLogAvailable] = useState(false); + const [hasCheckedAvailability, setHasCheckedAvailability] = useState(false); const checkAccessLogAvailability = async (): Promise => { try { await fetchEntryPassLog(0); setIsPassLogAvailable(true); + setHasCheckedAvailability(true); return true; } catch (error) { console.error('<---출입 로그 사용 불가--->:', error); setIsPassLogAvailable(false); + setHasCheckedAvailability(true); return false; } }; @@ -34,12 +41,12 @@ export const PassLogProvider: React.FC<{ children: React.ReactNode }> = ({ child if (reloaded === 'true') { console.log('새로고침 후 checkAccessLogAvailability 실행'); checkAccessLogAvailability(); - // sessionStorage.removeItem('reloaded'); + sessionStorage.removeItem('reloaded'); } const intervalId = setInterval(() => { checkAccessLogAvailability(); - }, 20000); + }, 5000); const handleStorageChange = (event: StorageEvent) => { if (event.key === 'accessToken') { @@ -63,8 +70,10 @@ export const PassLogProvider: React.FC<{ children: React.ReactNode }> = ({ child {children} diff --git a/src/pages/DashboardStats.tsx b/src/pages/DashboardStats.tsx index 2c6ece0..c574ab5 100644 --- a/src/pages/DashboardStats.tsx +++ b/src/pages/DashboardStats.tsx @@ -10,11 +10,29 @@ import Layout from '../components/layout/Layout'; import Background from '../components/background/Background'; import Warning from '../components/warning/Warning'; +import Loading from "../components/loading/Loading.tsx"; import './css/DashboardStats.css'; +import '../components/loading/css/Loading.css' const DashboardStats = () => { - const { isPassLogAvailable } = usePassLogContext(); + const { isPassLogAvailable, hasCheckedAvailability } = usePassLogContext(); + + if (!hasCheckedAvailability) { + return ( + <> + + +
+
+ +
방문자 통계를 불러오는 중입니다...
+
+
+
+ + ); + } if (!isPassLogAvailable) { return ( diff --git a/src/pages/css/DashboardStats.css b/src/pages/css/DashboardStats.css index 91d6cf1..1751778 100644 --- a/src/pages/css/DashboardStats.css +++ b/src/pages/css/DashboardStats.css @@ -6,6 +6,14 @@ justify-items: center; } +.dashboard-stats-loading-container { + position: relative; + display: flex; + align-items: center; + justify-items: center; + min-height: 400px; +} + .dashboard-stats-container > :first-child { grid-column: span 2; } From 61d0f5ce2b59d607c483517ad7423647f728923e Mon Sep 17 00:00:00 2001 From: judymoody59 Date: Wed, 11 Jun 2025 16:22:27 +0900 Subject: [PATCH 2/3] =?UTF-8?q?KW-653/fix:=20=EC=B6=9C=EC=9E=85=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20health-check=20API=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=9C=EC=9E=85=20=EB=A1=9C=EA=B7=B8=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 출입 로그 서비스 사용 가능 여부를 확인하고 있지만 추후에는 출입 로그 서비스 전용 health-check API 함수로 대체할 예정입니다. --- src/apis/passApi.ts | 14 +++++++++++++- src/components/_Admin/AdminLoginBox.tsx | 4 ++-- src/contexts/PassLogContext.tsx | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/apis/passApi.ts b/src/apis/passApi.ts index 8f11164..610ce9f 100644 --- a/src/apis/passApi.ts +++ b/src/apis/passApi.ts @@ -4,7 +4,7 @@ import axiosWithAuthorization from "../contexts/axiosWithAuthorization"; export const fetchEntryPassLog = async (page: number) => { try { const res = await axiosWithAuthorization.get(`/pass-logs/enter?page=${page}`); - console.log("---> 출입 내역 조회:", res.data); + console.log("출입 내역 조회:", res.data); return res.data.data; } catch (error) { console.log("출입 내역 조회 오류:", error); @@ -51,4 +51,16 @@ export const reviewPass = async (passId: number, issuanceStatus: "ISSUED" | "REJ } }; +// 출입 로그 health-check +export const checkPassLogHealthCheck = async () => { + try { + const res = await axiosWithAuthorization.get(`/pass-logs/health`); + console.log("출입 로그 health-check:", res.data); + return res.data.data; + } catch (error) { + console.log("출입 로그 health-check 오류:", error); + throw error; + } +}; + diff --git a/src/components/_Admin/AdminLoginBox.tsx b/src/components/_Admin/AdminLoginBox.tsx index 1c30f69..61ef1f1 100644 --- a/src/components/_Admin/AdminLoginBox.tsx +++ b/src/components/_Admin/AdminLoginBox.tsx @@ -5,7 +5,7 @@ import ReusableButton from "../buttons/ReusableButton"; import ReusableInput from "../input/ReusableInput"; import { adminLogin } from "../../apis/loginApi"; -import { fetchEntryPassLog } from "../../apis/passApi"; +import { checkPassLogHealthCheck } from "../../apis/passApi"; import { usePassLogContext } from "../../contexts/PassLogContext.tsx"; interface AdminLoginProps { @@ -40,7 +40,7 @@ const AdminLogin: React.FC = ({ onLogin }) => { localStorage.setItem("skipFirstCheck", "true"); onLogin(); try { - await fetchEntryPassLog(0); + await checkPassLogHealthCheck(); setIsPassLogAvailable(true); setHasCheckedAvailability(true); navigate("/dashboardstats"); diff --git a/src/contexts/PassLogContext.tsx b/src/contexts/PassLogContext.tsx index 50bfe79..3bddb20 100644 --- a/src/contexts/PassLogContext.tsx +++ b/src/contexts/PassLogContext.tsx @@ -1,5 +1,5 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; -import { fetchEntryPassLog } from '../apis/passApi'; +import { checkPassLogHealthCheck } from '../apis/passApi'; export interface PassLogContextType { isPassLogAvailable: boolean; @@ -23,7 +23,7 @@ export const PassLogProvider: React.FC<{ children: React.ReactNode }> = ({ child const checkAccessLogAvailability = async (): Promise => { try { - await fetchEntryPassLog(0); + await checkPassLogHealthCheck(); setIsPassLogAvailable(true); setHasCheckedAvailability(true); return true; From 0965b8750df67ad7ef22e335e7285ad3f6270eff Mon Sep 17 00:00:00 2001 From: judymoody59 Date: Wed, 11 Jun 2025 17:10:17 +0900 Subject: [PATCH 3/3] =?UTF-8?q?KW-653/fix:=20IssueDetailPage=EC=97=90=20Wa?= =?UTF-8?q?rning=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/IssueDetailPage.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/pages/IssueDetailPage.tsx b/src/pages/IssueDetailPage.tsx index 42d61fe..2c96ad8 100644 --- a/src/pages/IssueDetailPage.tsx +++ b/src/pages/IssueDetailPage.tsx @@ -1,9 +1,11 @@ import { useLocation } from 'react-router-dom'; +import { usePassLogContext } from "../contexts/PassLogContext.tsx"; import Layout from '../components/layout/Layout.tsx'; import Background from '../components/background/Background.tsx'; import Breadcrumb from '../components/breadcrumb/Breadcrumb.tsx'; import DefaultTable from '../components/table/DefaultTable.tsx'; +import Warning from "../components/warning/Warning.tsx"; import './css/IssueDetailPage.css'; @@ -33,6 +35,19 @@ const IssueDetailPage = () => { const issue = [data]; const areasInfo = data?.areas || []; + const { isPassLogAvailable } = usePassLogContext(); + + if (!isPassLogAvailable) { + return ( + <> + + + + + + ); + } + return ( <>