Routing
Router Configuration
Frontend menggunakan React Router v7 dengan createBrowserRouter.
// src/router.tsx
export const router = createBrowserRouter([
{ path: "/login", element: <LoginPage /> },
{
element: <AuthGuard />,
children: [
{ path: "/", element: <DashboardPage /> },
{ path: "/sources", element: <SourcesPage /> },
{ path: "/search", element: <SearchPage /> },
{ path: "/alerting", element: <AlertingPage /> },
{ path: "/apm", element: <ApmPage /> },
{ path: "/security", element: <SecurityPage /> },
{ path: "/compliance", element: <CompliancePage /> },
{ path: "/reporting", element: <ReportingPage /> },
{ path: "/master-data", element: <MasterDataPage /> },
{ path: "/architecture", element: <ArchitecturePage /> },
{ path: "/infrastructure", element: <InfrastructurePage /> },
],
},
{ path: "*", element: <NotFoundPage /> },
]);
Authentication Guard
function AuthGuard() {
const { isAuthed } = useApp();
if (!isAuthed) return <Navigate to="/login" replace />;
return <Outlet />;
}
Behavior:
- Jika user belum login → redirect ke
/login - Jika user sudah login → render child routes
- Menggunakan
<Outlet />untuk nested routes
Route Definitions
| Path | Component | Description | Permission |
|---|---|---|---|
/login | LoginPage | Authentication page | Public |
/ | DashboardPage | Main dashboard | All authenticated |
/sources | SourcesPage | Log sources management | logs:read |
/search | SearchPage | Log search | logs:read |
/alerting | AlertingPage | Alert management | alerts:read |
/apm | ApmPage | Application monitoring | dashboard:read |
/security | SecurityPage | Security/SIEM | alerts:read |
/compliance | CompliancePage | Compliance dashboard | audit:read |
/reporting | ReportingPage | Reports | audit:read |
/master-data | MasterDataPage | Master data management | Admin only |
/architecture | ArchitecturePage | System architecture | All authenticated |
/infrastructure | InfrastructurePage | Infrastructure monitoring | dashboard:read |
* | NotFoundPage | 404 page | Public |
Page Components
Dashboard Page
// src/routes/index.tsx
export default function DashboardPage() {
return (
<div className="p-6 space-y-6">
<h1 className="text-2xl font-bold">Dashboard</h1>
{/* Pipeline Status */}
<PipelineStatus />
{/* Data Center Status */}
<DCStatus />
{/* Throughput Metrics */}
<ThroughputMetrics />
{/* Log Volume Chart */}
<LogVolumeChart />
</div>
);
}
Search Page
// src/routes/search.tsx
export default function SearchPage() {
const [query, setQuery] = useState('');
const [timeRange, setTimeRange] = useState('24h');
const [filters, setFilters] = useState<Filter[]>([]);
return (
<div className="p-6 space-y-6">
{/* Search Bar */}
<SearchBar
query={query}
onQueryChange={setQuery}
timeRange={timeRange}
onTimeRangeChange={setTimeRange}
/>
{/* Filters */}
<FilterPanel
filters={filters}
onFilterChange={setFilters}
/>
{/* Results */}
<LogResults
query={query}
timeRange={timeRange}
filters={filters}
/>
{/* Histogram */}
<LogHistogram
query={query}
timeRange={timeRange}
/>
</div>
);
}
Alerting Page
// src/routes/alerting.tsx
export default function AlertingPage() {
return (
<div className="p-6 space-y-6">
<Tabs defaultValue="active">
<TabsList>
<TabsTrigger value="active">Active Alerts</TabsTrigger>
<TabsTrigger value="rules">Alert Rules</TabsTrigger>
<TabsTrigger value="channels">Channels</TabsTrigger>
<TabsTrigger value="history">History</TabsTrigger>
</TabsList>
<TabsContent value="active">
<ActiveAlerts />
</TabsContent>
<TabsContent value="rules">
<AlertRules />
</TabsContent>
<TabsContent value="channels">
<NotificationChannels />
</TabsContent>
<TabsContent value="history">
<AlertHistory />
</TabsContent>
</Tabs>
</div>
);
}
Navigation
Sidebar Navigation
const menuItems = [
{ path: '/', label: 'Dashboard', icon: LayoutDashboard },
{ path: '/sources', label: 'Sources', icon: Server },
{ path: '/search', label: 'Search', icon: Search },
{ path: '/alerting', label: 'Alerting', icon: Bell },
{ path: '/apm', label: 'APM', icon: Activity },
{ path: '/security', label: 'Security', icon: Shield },
{ path: '/compliance', label: 'Compliance', icon: FileCheck },
{ path: '/reporting', label: 'Reporting', icon: FileText },
{ path: '/master-data', label: 'Master Data', icon: Database, adminOnly: true },
{ path: '/architecture', label: 'Architecture', icon: Network },
{ path: '/infrastructure', label: 'Infrastructure', icon: Cpu },
];
Active Route Highlighting
function NavLink({ path, label, icon: Icon }: NavItem) {
const location = useLocation();
const isActive = location.pathname === path;
return (
<Link
to={path}
className={cn(
"flex items-center gap-2 px-4 py-2 text-sm",
isActive
? "bg-primary text-primary-foreground"
: "text-muted-foreground hover:bg-muted"
)}
>
<Icon className="h-4 w-4" />
{label}
</Link>
);
}
404 Page
function NotFoundPage() {
return (
<div className="dark flex min-h-screen items-center justify-center bg-background px-4">
<div className="max-w-md text-center">
<h1 className="text-7xl font-bold text-foreground">404</h1>
<h2 className="mt-4 text-xl font-semibold text-foreground">
Halaman tidak ditemukan
</h2>
<p className="mt-2 text-sm text-muted-foreground">
URL yang Anda akses tidak terdaftar pada TS-SmartLog Systems.
</p>
<div className="mt-6">
<Link
to="/"
className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground"
>
Kembali ke Dashboard
</Link>
</div>
</div>
</div>
);
}
Next Steps
- State Management - State management
- Components - Component documentation
- i18n - Internationalization