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
14 changes: 13 additions & 1 deletion src/apis/passApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
};


14 changes: 10 additions & 4 deletions src/components/_Admin/AdminLoginBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ 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 {
onLogin: () => void;
Expand All @@ -16,6 +17,7 @@ const AdminLogin: React.FC<AdminLoginProps> = ({ onLogin }) => {
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const navigate = useNavigate();
const { setIsPassLogAvailable, setHasCheckedAvailability } = usePassLogContext();

useEffect(() => {
const darkMode = localStorage.getItem("theme") === "dark";
Expand All @@ -35,16 +37,20 @@ const AdminLogin: React.FC<AdminLoginProps> = ({ onLogin }) => {
const token = response.accessToken;
if (token) {
localStorage.setItem("accessToken", token);
localStorage.setItem("skipFirstCheck", "true");
onLogin();
try {
await fetchEntryPassLog(0);
await checkPassLogHealthCheck();
setIsPassLogAvailable(true);
setHasCheckedAvailability(true);
navigate("/dashboardstats");
} catch (error) {
console.error("<--- 출입 로그 조회 실패:", error);
console.error("<--- 출입 로그 조회 실패:", error);
setIsPassLogAvailable(false);
setHasCheckedAvailability(true);
navigate("/admin/mypage");
}


} else {
setError("로그인 실패: 엑세스 토큰이 없음");
}
Expand Down
17 changes: 13 additions & 4 deletions src/contexts/PassLogContext.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { fetchEntryPassLog } from '../apis/passApi';
import { checkPassLogHealthCheck } from '../apis/passApi';

export interface PassLogContextType {
isPassLogAvailable: boolean;
hasCheckedAvailability: boolean;
checkAccessLogAvailability: () => Promise<boolean>;
setIsPassLogAvailable: React.Dispatch<React.SetStateAction<boolean>>;
setHasCheckedAvailability: React.Dispatch<React.SetStateAction<boolean>>;
}

export const PassLogContext = createContext<PassLogContextType>({
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<boolean> => {
try {
await fetchEntryPassLog(0);
await checkPassLogHealthCheck();
setIsPassLogAvailable(true);
setHasCheckedAvailability(true);
return true;
} catch (error) {
console.error('<---출입 로그 사용 불가--->:', error);
setIsPassLogAvailable(false);
setHasCheckedAvailability(true);
return false;
}
};
Expand All @@ -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') {
Expand All @@ -63,8 +70,10 @@ export const PassLogProvider: React.FC<{ children: React.ReactNode }> = ({ child
<PassLogContext.Provider
value={{
isPassLogAvailable,
hasCheckedAvailability,
checkAccessLogAvailability,
setIsPassLogAvailable,
setHasCheckedAvailability,
}}>
{children}
</PassLogContext.Provider>
Expand Down
20 changes: 19 additions & 1 deletion src/pages/DashboardStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<>
<Background />
<Layout>
<div className="ddashboard-stats-loading-container ">
<div className="loading-overlay">
<Loading />
<div className="loading-text">방문자 통계를 불러오는 중입니다...</div>
</div>
</div>
</Layout>
</>
);
}

if (!isPassLogAvailable) {
return (
Expand Down
15 changes: 15 additions & 0 deletions src/pages/IssueDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -33,6 +35,19 @@ const IssueDetailPage = () => {
const issue = [data];
const areasInfo = data?.areas || [];

const { isPassLogAvailable } = usePassLogContext();

if (!isPassLogAvailable) {
return (
<>
<Background />
<Layout>
<Warning />
</Layout>
</>
);
}

return (
<>
<Background />
Expand Down
8 changes: 8 additions & 0 deletions src/pages/css/DashboardStats.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down