snp-connection-monitoring/frontend/src/components/RoleGuard.tsx
HYOJIN c2a71c1b77 feat(design): 디자인 시스템 적용 (CSS 토큰, Button/Badge, 차트, 다크모드) (#48)
- 디자인 시스템 가이드 문서 11개 생성 (docs/design/)
- CSS 변수 토큰 시스템 (@theme + :root/.dark 전환)
- cn() 유틸리티 (clsx + tailwind-merge)
- Button/Badge 공통 컴포넌트 (variant/size, 다크모드 대응)
- 하드코딩 Tailwind 색상 → CSS 변수 토큰 리팩토링 (30개 파일)
- 차트 팔레트 다크모드 색상 업데이트 (CHART_COLORS_HEX)
- 버튼 다크모드 채도/대비 강화 (primary-600 기반)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:38:00 +09:00

40 lines
1.8 KiB
TypeScript

import { useNavigate } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';
import Button from './ui/Button';
interface RoleGuardProps {
allowedRoles: string[];
children: React.ReactNode;
}
const RoleGuard = ({ allowedRoles, children }: RoleGuardProps) => {
const { user } = useAuth();
const navigate = useNavigate();
if (!user || !allowedRoles.includes(user.role)) {
return (
<div className="max-w-7xl mx-auto flex flex-col items-center justify-center py-32">
<div className="bg-[var(--color-bg-surface)] rounded-2xl border border-[var(--color-border)] shadow-lg p-10 text-center max-w-md">
<div className="w-16 h-16 mx-auto mb-5 rounded-full bg-[var(--color-danger-subtle)] border border-[var(--color-danger-border)] flex items-center justify-center">
<svg className="w-8 h-8 text-[var(--color-danger-text)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
</svg>
</div>
<h2 className="text-xl font-bold text-[var(--color-text-primary)] mb-2"> </h2>
<p className="text-sm text-[var(--color-text-secondary)] mb-6">
<span className="font-semibold text-[var(--color-text-primary)]">{allowedRoles.join(', ')}</span> .
<br /> : <span className="font-semibold text-[var(--color-text-primary)]">{user?.role || '-'}</span>
</p>
<Button onClick={() => navigate('/dashboard')}>
</Button>
</div>
</div>
);
}
return <>{children}</>;
};
export default RoleGuard;