Admin Panel Architecture
Overview
The admin panel is built with React Admin, providing a complete admin interface with minimal boilerplate.
┌────────────────────────────────────────────────────────────┐
│ Browser │
└────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ React App │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ React Admin │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Resource Views │ │ │
│ │ │ (List, Show, Create, Edit) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Data Provider │ │ │
│ │ │ (GraphQL operations) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Auth Provider │ │ │
│ │ │ (JWT authentication) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ URQL GraphQL Client │
│ (with auth exchange) │
└────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ Backend GraphQL API │
└────────────────────────────────────────────────────────────┘Key Components
App Entry (App.tsx)
<BrowserRouter>
<Theme>
<URQLProvider value={urqlClient}>
<Admin />
</URQLProvider>
</Theme>
</BrowserRouter>React Admin Setup (Admin.tsx)
<ReactAdmin
dataProvider={dataProvider}
authProvider={authProvider}
i18nProvider={i18nProvider}
theme={theme}
dashboard={Dashboard}
>
<Resource name="users" {...UserResource} />
<Resource name="games" {...GameResource} />
{/* ... more resources */}
</ReactAdmin>Data Layer
URQL Client (data/client.ts)
GraphQL client with:
- Auth exchange (JWT injection)
- Multipart fetch (file uploads)
- Error handling
Data Provider (data/provider.ts)
Implements React Admin’s DataProvider interface:
const dataProvider: DataProvider = {
getList, // → GraphQL query with pagination
getOne, // → GraphQL query by ID
getMany, // → GraphQL query by IDs
getManyReference, // → Related entities
create, // → GraphQL mutation
update, // → GraphQL mutation
delete, // → GraphQL mutation
deleteMany, // → Batch mutation
updateMany, // → Batch mutation
};Field Definitions (data/fields/)
Custom field configurations for each resource defining:
- Field types
- Labels
- Validation rules
- GraphQL mapping
Authentication
Auth Provider (auth/provider.ts)
const authProvider: AuthProvider = {
login: async ({ email, password }) => {
// GraphQL mutation: login
// Store JWT
},
logout: async () => {
// Clear JWT
},
checkAuth: async () => {
// Verify JWT exists
},
checkError: async (error) => {
// Handle 401/403
},
getPermissions: async () => {
// Return user permissions
},
};JWT Manager (auth/jwt-manager.ts)
Handles:
- Token storage (localStorage)
- Token refresh
- Token injection into requests
Component Architecture
Atomic Design Pattern
atoms/ → Basic UI elements
├── ImageField.tsx
├── PriceField.tsx
├── StatusField.tsx
└── ...
molecules/ → Composite components
├── CreateUpdateFields.tsx
├── ProList.tsx
└── ...
organisms/ → Complex features
├── Dashboard/
├── Menu/
└── ...
resources/ → Entity CRUD views
├── User/
├── Game/
└── ...Theming
MUI Theme (theme/)
Custom MUI theme with:
- Dark/Light mode
- RTL support (Farsi)
- Custom palette
- Custom typography
Internationalization
i18n (i18n/)
- Persian (Farsi) as primary language
- Uses
ra-language-farsi - Custom translations for business terms
Build & Deploy
Vite Config (vite.config.mts)
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@src': path.resolve(__dirname, './src'),
},
},
});Build Output
yarn build
# → dist/
# ├── index.html
# ├── assets/
# └── version.txtError Handling
Sentry Integration
Sentry.init({
dsn: 'YOUR_DSN',
integrations: [new Sentry.BrowserTracing()],
});GraphQL Errors
Custom error handling in data/GraphQLError.ts
Last updated on