Admin Panel
This document describes the Admin Panel architecture and development.
Purpose
The Admin Panel is the main interface for bank staff:
- Customer management
- Credit administration
- Deposit and withdrawal operations
- Approvals and governance
- Financial reports
Architecture
Project Structure
apps/admin-panel/
├── src/
│ ├── main.tsx # Application entry
│ ├── runtime-config.ts # Runtime config loader
│ ├── routes/ # TanStack Router file-based routes
│ ├── auth/ # Keycloak integration
│ ├── shell/ # App shell / layout
│ └── generated/ # Generated GraphQL types
├── components/ # React components
├── hooks/ # Custom hooks
└── lib/ # Utilities and Apollo config
Authentication
Keycloak Configuration
import Keycloak from 'keycloak-js';
import { getRuntimeConfig } from '@/src/runtime-config';
const config = getRuntimeConfig();
export const keycloak = new Keycloak({
url: config.keycloakUrl,
realm: config.keycloakRealm,
clientId: config.keycloakClientId,
});
Route Protection
export function ProtectedRoute({ children, requiredRole }) {
const { isAuthenticated, hasRole } = useAuth();
if (!isAuthenticated) {
return <LoginRedirect />;
}
if (requiredRole && !hasRole(requiredRole)) {
return <AccessDenied />;
}
return children;
}
Development
Commands
# Development
pnpm dev
# Production build
pnpm build
# Lint
pnpm lint
# Generate GraphQL types
pnpm codegen
Runtime Configuration
Configuration is injected at runtime via window.__APP_CONFIG__ (populated from an index.html template at deploy time) rather than build-time env vars. Local dev falls back to defaults from src/runtime-config.ts:
// src/runtime-config.ts (excerpt)
const devDefaults: RuntimeConfig = {
keycloakUrl: "http://localhost:8081",
keycloakRealm: "internal",
keycloakClientId: "admin-panel",
keycloakDefaultLoginHint: "admin@galoy.io",
coreAdminGqlUrl: "/graphql",
coreAdminSseUrl: "/graphql/stream",
};