All checks were successful
build-and-push / build (push) Successful in 31s
- 브랜드 포인트컬러 #03143F로 팔레트 전면 재설정, 회사 로고 흰 wrap 제거+크롭, 로고 블렌딩 - 사이드바 접기/펼치기(localStorage), 로고 아래 근무상태 드롭다운(출근/퇴근/휴식/미팅/이동) - 대시보드 역할 무관 동일(회계/전사 위젯 제거) - 유저 근무화면 단순화(남은연차 소수점·기록·휴가/공가만), 관리자 근무관리(/admin/attendance) - 프로젝트: 관리자 전용 관리창(/admin/projects), 나의 업무는 본인 참여분 read-only - 메일함(/inbox)+탑바 벨(미확인), 프로필(부서·연락처·사진 업로드) - 인센티브 유저: BE/non-BE·환율 숨김, 할당량 세그먼트 게이지(지급완료→반영완료→반영중→예정, 할당량 화살표) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
65 lines
2.8 KiB
TypeScript
65 lines
2.8 KiB
TypeScript
import { Routes, Route, Navigate } from "react-router-dom";
|
|
import { AuthProvider, useAuth } from "@/context/Auth";
|
|
import { AppShell } from "@/components/AppShell";
|
|
import { LoadingState } from "@/components/ui";
|
|
import { DashboardPage } from "@/pages/Dashboard";
|
|
import { AttendancePage } from "@/pages/Attendance";
|
|
import { ProjectsPage } from "@/pages/Projects";
|
|
import { ProjectDetailPage } from "@/pages/ProjectDetail";
|
|
import { IncentivePage } from "@/pages/Incentive";
|
|
import { ProfilePage } from "@/pages/Profile";
|
|
import { InboxPage } from "@/pages/Inbox";
|
|
import { ApprovalsPage } from "@/pages/admin/Approvals";
|
|
import { AttendanceAdminPage } from "@/pages/admin/AttendanceAdmin";
|
|
import { ProjectsAdminPage } from "@/pages/admin/ProjectsAdmin";
|
|
import { IncentiveAdminPage } from "@/pages/admin/IncentiveAdmin";
|
|
import { AccountingPage } from "@/pages/admin/Accounting";
|
|
import { MembersPage } from "@/pages/admin/Members";
|
|
import { SettingsPage } from "@/pages/admin/Settings";
|
|
|
|
function RequireAdmin({ children }: { children: JSX.Element }) {
|
|
const { isAdmin, loading } = useAuth();
|
|
if (loading) return <LoadingState />;
|
|
return isAdmin ? children : <Navigate to="/" replace />;
|
|
}
|
|
|
|
function Shell() {
|
|
const { loading } = useAuth();
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-canvas">
|
|
<LoadingState label="spin 로딩 중…" />
|
|
</div>
|
|
);
|
|
}
|
|
return (
|
|
<Routes>
|
|
<Route element={<AppShell />}>
|
|
<Route path="/" element={<DashboardPage />} />
|
|
<Route path="/attendance" element={<AttendancePage />} />
|
|
<Route path="/projects" element={<ProjectsPage />} />
|
|
<Route path="/projects/:id" element={<ProjectDetailPage />} />
|
|
<Route path="/incentive" element={<IncentivePage />} />
|
|
<Route path="/profile" element={<ProfilePage />} />
|
|
<Route path="/inbox" element={<InboxPage />} />
|
|
<Route path="/admin/approvals" element={<RequireAdmin><ApprovalsPage /></RequireAdmin>} />
|
|
<Route path="/admin/attendance" element={<RequireAdmin><AttendanceAdminPage /></RequireAdmin>} />
|
|
<Route path="/admin/projects" element={<RequireAdmin><ProjectsAdminPage /></RequireAdmin>} />
|
|
<Route path="/admin/incentive" element={<RequireAdmin><IncentiveAdminPage /></RequireAdmin>} />
|
|
<Route path="/admin/accounting" element={<RequireAdmin><AccountingPage /></RequireAdmin>} />
|
|
<Route path="/admin/members" element={<RequireAdmin><MembersPage /></RequireAdmin>} />
|
|
<Route path="/admin/settings" element={<RequireAdmin><SettingsPage /></RequireAdmin>} />
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Route>
|
|
</Routes>
|
|
);
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<AuthProvider>
|
|
<Shell />
|
|
</AuthProvider>
|
|
);
|
|
}
|