Eneza Admin Dashboard
The Admin Dashboard is a React + TypeScript application for internal management of the Eneza platform.
Technology Stack
| Component | Technology |
|---|---|
| Framework | React 18 |
| Build Tool | Vite |
| Language | TypeScript |
| State | React Query |
| Routing | React Router |
| UI | Tailwind CSS, Radix UI |
| Charts | Recharts |
| Hosting | Cloudflare Pages |
Project Structure
admin-dashboard/
├── src/
│ ├── main.tsx
│ ├── App.tsx
│ ├── pages/ # Page components (14 modules)
│ │ ├── admins/
│ │ ├── ads/
│ │ ├── advertisers/
│ │ ├── auth/
│ │ ├── dashboard/
│ │ ├── finance/
│ │ ├── kanban/
│ │ ├── notifications/
│ │ ├── screenshots/
│ │ ├── settings/
│ │ ├── subscriptions/
│ │ ├── support/
│ │ ├── system/
│ │ └── users/
│ ├── components/ # Reusable components
│ ├── hooks/ # Custom hooks
│ ├── services/ # API clients
│ ├── stores/ # Global state
│ ├── types/ # TypeScript types
│ └── utils/ # Utilities
├── tailwind.config.js
└── vite.config.tsPage Modules
Dashboard (/dashboard)
Main analytics overview.
Files:
DashboardPage.tsx- Overview with key metrics
Features:
- Total users, advertisers, earnings
- Active campaigns
- Real-time graphs
- Recent activity feed
Users (/users)
User (poster) management.
Files:
UsersPage.tsx- User list with filtersUserDetailsPage.tsx- Individual user detailsUserActivitiesPage.tsx- User activity log
Features:
- Search by phone/name
- Filter by country, status, KYC
- View/edit user profiles
- Ban/unban users
- View transaction history
- View screenshot submissions
Advertisers (/advertisers)
Advertiser account management.
Files:
AdvertisersPage.tsx- Advertiser listAdvertiserDetailsPage.tsx- Advertiser profileAdvertiserEmailPage.tsx- Email management
Features:
- Search by company/email
- View campaigns
- Credit balance manually
- View invoices
- Manage email preferences
Ads (/ads)
Ad campaign moderation.
Files:
AdsPage.tsx- Ad list with status tabsAdDetailsPage.tsx- Full ad details
Features:
- Moderation queue (pending review)
- Approve/reject ads
- View campaign statistics
- Edit ad details
- Pause/resume campaigns
- Process refunds
Status Tabs:
- Under Review
- Active
- Paused
- Completed
- Rejected
Screenshots (/screenshots)
Screenshot verification queue.
Files:
ScreenshotsPage.tsx- Screenshot queueScreenshotDetailsPage.tsx- Individual review
Features:
- Pending review queue
- Manual approve/reject
- View AI verification results
- View fraud scores
- Bulk approve
- Request additional proof
Finance (/finance)
Financial operations.
Files:
FinancePage.tsx- Financial overviewTransactionsPage.tsx- All transactionsTransactionDetailsPage.tsxDepositsPage.tsx- Advertiser depositsDepositDetailsPage.tsxInvoicesPage.tsx- All invoicesInvoiceDetailsPage.tsxRefundsPage.tsx- Refund requestsRefundDetailsPage.tsx
Features:
- Pending withdrawals queue
- Process payouts (mark as paid)
- Download invoices
- View deposit history
- Process refunds
Settings (/settings)
Platform configuration.
Files:
SettingsPage.tsx- Settings overviewCategoriesPage.tsx- Ad categoriesCountriesPage.tsx- Country managementCountryDetailsPage.tsxCitiesPage.tsx- City managementPaymentProcessorsPage.tsx- Mobile money providersAppVersionPage.tsx- Mobile app versionsEmailTemplatesPage.tsx- Email templatesTestingToolsPage.tsx- Dev tools
Features:
- Manage ad categories
- Configure countries (currencies, pricing tiers)
- Manage cities
- Configure payment processors
- Set minimum app versions
- Edit email templates
Admin Users (/admins)
Internal admin management.
Files:
AdminUsersPage.tsx- Admin listAdminDetailsPage.tsx- Admin profilePermissionManagementPage.tsx- Role permissionsRoleTemplatesPage.tsx- Role templates
Features:
- Invite new admins
- Assign roles
- Configure permissions
- View admin activity
- Deactivate admins
Support (/support)
Customer support tickets.
Files:
SupportPage.tsx- Ticket listSupportTicketDetailsPage.tsx- Ticket thread
Features:
- View open tickets
- Reply to tickets
- Close/resolve tickets
- Assign to admin
- View ticket history
Notifications (/notifications)
Notification management.
Files:
NotificationsPage.tsx- Broadcast listNotificationSettingsPage.tsx- Notification config
Features:
- Create broadcast notifications
- Schedule broadcasts
- Target by country/segment
- View delivery stats
Kanban (/kanban)
Internal task management.
Files:
KanbanPage.tsx- Kanban boardTaskDetailPage.tsx- Task details
Features:
- Drag-and-drop tasks
- Create/edit tasks
- Assign to admins
- Track progress
System (/system)
System monitoring.
Files:
SystemHealthPage.tsx- Health dashboardAlertsPage.tsx- System alertsFailedJobsPage.tsx- Failed jobsActivityLogsPage.tsx- Audit logs
Features:
- Service health status
- View system alerts
- Retry failed jobs
- View admin activity logs
Authentication
Admin authentication uses JWT tokens with role-based access.
typescript
// services/auth.ts
export const authService = {
async login(email: string, password: string) {
const response = await api.post('/admin/auth/login', { email, password });
localStorage.setItem('adminToken', response.data.token);
return response.data;
},
async logout() {
await api.post('/admin/auth/logout');
localStorage.removeItem('adminToken');
},
async getCurrentAdmin() {
const response = await api.get('/admin/auth/me');
return response.data;
}
};Permission Checking
typescript
// hooks/usePermission.ts
export function usePermission(permission: string): boolean {
const { admin } = useAdminStore();
if (!admin) return false;
if (admin.role === 'super_admin') return true;
return admin.permissions.includes(permission);
}
// Usage in components
function AdApproveButton({ adId }: { adId: string }) {
const canApprove = usePermission('ads:moderate');
if (!canApprove) return null;
return <Button onClick={() => approveAd(adId)}>Approve</Button>;
}API Client
typescript
// services/api.ts
import axios from 'axios';
export const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || 'https://api.eneza.app',
headers: {
'Content-Type': 'application/json',
},
});
// Add auth header
api.interceptors.request.use((config) => {
const token = localStorage.getItem('adminToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Handle auth errors
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
localStorage.removeItem('adminToken');
window.location.href = '/login';
}
return Promise.reject(error);
}
);Data Fetching with React Query
typescript
// hooks/useUsers.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../services/api';
export function useUsers(filters: UserFilters) {
return useQuery({
queryKey: ['users', filters],
queryFn: async () => {
const { data } = await api.get('/admin/users', { params: filters });
return data;
},
});
}
export function useBanUser() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (userId: string) => {
await api.post(`/admin/users/${userId}/ban`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
},
});
}Deployment
Hosted on Cloudflare Pages with automatic deployments.
bash
# Build
npm run build
# Deploy
npx wrangler pages deploy dist --project-name=eneza-admin-dashboardURLs:
- Production:
https://admin.eneza.app - Preview:
https://dev-admin.eneza.app
Environment Variables
bash
VITE_API_URL=https://api.eneza.app
VITE_STRIPE_PUBLISHABLE_KEY=pk_live_...