feat: React 프론트엔드 기능 대폭 확장
- 월별근무표: 휴일/근무일 관리, 자동 초기화 - 메일양식: 템플릿 CRUD, To/CC/BCC 설정 - 그룹정보: 부서 관리, 비트 연산 기반 권한 설정 - 업무일지: 수정 성공 메시지 제거, 오늘 근무시간 필터링 수정 - 웹소켓 메시지 type 충돌 버그 수정 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
99
Project/frontend/src/App.tsx
Normal file
99
Project/frontend/src/App.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { HashRouter, Routes, Route } from 'react-router-dom';
|
||||
import { Layout } from '@/components/layout';
|
||||
import { Dashboard, Todo, Kuntae, Jobreport, PlaceholderPage, Login, CommonCodePage, ItemsPage, UserListPage, MonthlyWorkPage, MailFormPage, UserGroupPage } from '@/pages';
|
||||
import { comms } from '@/communication';
|
||||
import { UserInfo } from '@/types';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
export default function App() {
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null); // null = 체크 중
|
||||
const [user, setUser] = useState<UserInfo | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// 통신 상태 구독
|
||||
const unsubscribe = comms.subscribe((msg: unknown) => {
|
||||
const message = msg as { type?: string; connected?: boolean };
|
||||
if (message?.type === 'CONNECTION_STATE') {
|
||||
setIsConnected(message.connected ?? false);
|
||||
// 연결되면 로그인 상태 체크
|
||||
if (message.connected) {
|
||||
checkLoginStatus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 초기 연결 상태 설정
|
||||
setIsConnected(comms.getConnectionState());
|
||||
|
||||
// 연결되어 있으면 바로 로그인 상태 체크
|
||||
if (comms.getConnectionState()) {
|
||||
checkLoginStatus();
|
||||
}
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkLoginStatus = async () => {
|
||||
try {
|
||||
const result = await comms.checkLoginStatus();
|
||||
if (result.Success) {
|
||||
setIsLoggedIn(result.IsLoggedIn);
|
||||
setUser(result.User);
|
||||
} else {
|
||||
setIsLoggedIn(false);
|
||||
setUser(null);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('로그인 상태 체크 실패:', err);
|
||||
setIsLoggedIn(false);
|
||||
setUser(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLoginSuccess = () => {
|
||||
checkLoginStatus();
|
||||
};
|
||||
|
||||
// 로그인 상태 체크 중
|
||||
if (isLoggedIn === null) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-blue-900 via-purple-900 to-indigo-900 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Loader2 className="w-10 h-10 text-white animate-spin mx-auto mb-4" />
|
||||
<p className="text-white/70">로그인 상태 확인 중...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 로그인 안됨 → 로그인 화면 표시
|
||||
if (!isLoggedIn) {
|
||||
return <Login onLoginSuccess={handleLoginSuccess} />;
|
||||
}
|
||||
|
||||
// 로그인 됨 → 메인 앱 표시
|
||||
return (
|
||||
<HashRouter>
|
||||
<Routes>
|
||||
<Route element={<Layout isConnected={isConnected} user={user} />}>
|
||||
<Route path="/" element={<Dashboard />} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/todo" element={<Todo />} />
|
||||
<Route path="/kuntae" element={<Kuntae />} />
|
||||
<Route path="/jobreport" element={<Jobreport />} />
|
||||
<Route path="/project" element={<PlaceholderPage title="프로젝트" />} />
|
||||
<Route path="/common" element={<CommonCodePage />} />
|
||||
<Route path="/items" element={<ItemsPage />} />
|
||||
<Route path="/user/list" element={<UserListPage />} />
|
||||
<Route path="/monthly-work" element={<MonthlyWorkPage />} />
|
||||
<Route path="/mail-form" element={<MailFormPage />} />
|
||||
<Route path="/user-group" element={<UserGroupPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</HashRouter>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user