Skip to content

Admin Dashboard

The YeboJobs Admin Dashboard is a React SPA for managing the platform.

Tech Stack

  • Framework: React 18 with TypeScript
  • Build Tool: Vite
  • Data Fetching: TanStack Query (React Query)
  • Routing: React Router v6
  • Styling: Tailwind CSS
  • Charts: Recharts
  • Tables: TanStack Table

Project Structure

yebojobs-admin/
├── src/
│   ├── App.tsx                 # App with providers
│   ├── main.tsx                # Entry point
│   │
│   ├── pages/
│   │   ├── auth/
│   │   │   └── LoginPage.tsx   # Admin login
│   │   │
│   │   ├── dashboard/
│   │   │   └── DashboardPage.tsx
│   │   │
│   │   ├── users/
│   │   │   ├── UsersListPage.tsx
│   │   │   └── UserDetailPage.tsx
│   │   │
│   │   ├── employers/
│   │   │   ├── EmployersListPage.tsx
│   │   │   └── EmployerDetailPage.tsx
│   │   │
│   │   ├── jobs/
│   │   │   ├── JobsListPage.tsx
│   │   │   └── JobDetailPage.tsx
│   │   │
│   │   ├── payments/
│   │   │   ├── PaymentRequestsPage.tsx
│   │   │   ├── CashoutRequestsPage.tsx
│   │   │   └── TransactionsPage.tsx
│   │   │
│   │   ├── services/
│   │   │   ├── WorkersListPage.tsx
│   │   │   ├── CategoriesPage.tsx
│   │   │   └── BookingsListPage.tsx
│   │   │
│   │   └── reviews/
│   │       └── ReviewsListPage.tsx
│   │
│   ├── components/
│   │   ├── layout/
│   │   │   ├── Layout.tsx      # Main layout with sidebar
│   │   │   ├── Sidebar.tsx
│   │   │   └── Header.tsx
│   │   │
│   │   ├── common/
│   │   │   ├── DataTable.tsx
│   │   │   ├── StatusBadge.tsx
│   │   │   ├── ConfirmDialog.tsx
│   │   │   └── Pagination.tsx
│   │   │
│   │   └── charts/
│   │       ├── LineChart.tsx
│   │       └── PieChart.tsx
│   │
│   ├── router/
│   │   └── index.tsx           # Route definitions
│   │
│   ├── api/
│   │   └── index.ts            # Admin API client
│   │
│   ├── context/
│   │   ├── AuthContext.tsx
│   │   └── ToastContext.tsx
│   │
│   └── hooks/
│       ├── useUsers.ts
│       ├── useJobs.ts
│       └── usePayments.ts

└── package.json

Routes

typescript
// router/index.tsx
export const router = createBrowserRouter([
  {
    path: '/login',
    element: <LoginPage />,
  },
  {
    path: '/',
    element: <Layout />,  // Protected with auth
    children: [
      { index: true, element: <Navigate to="/dashboard" replace /> },
      { path: 'dashboard', element: <DashboardPage /> },
      
      // Users
      { path: 'users', element: <UsersListPage /> },
      { path: 'users/:id', element: <UserDetailPage /> },
      
      // Employers
      { path: 'employers', element: <EmployersListPage /> },
      { path: 'employers/:id', element: <EmployerDetailPage /> },
      
      // Jobs
      { path: 'jobs', element: <JobsListPage /> },
      { path: 'jobs/:id', element: <JobDetailPage /> },
      
      // Payments
      { path: 'payments', element: <PaymentRequestsPage /> },
      { path: 'cashouts', element: <CashoutRequestsPage /> },
      { path: 'transactions', element: <TransactionsPage /> },
      
      // Services
      { path: 'workers', element: <WorkersListPage /> },
      { path: 'categories', element: <CategoriesPage /> },
      { path: 'bookings', element: <BookingsListPage /> },
      
      // Reviews
      { path: 'reviews', element: <ReviewsListPage /> },
    ],
  },
]);

Pages

Dashboard

File: pages/dashboard/DashboardPage.tsx

Overview of platform metrics.

Metrics Cards

  • Total Users (with growth %)
  • Total Employers
  • Active Jobs
  • Applications This Week
  • Total Bookings
  • Revenue (Credits sold)

Charts

  • User Growth - Line chart over 30 days
  • Job Categories - Pie chart distribution
  • Applications Trend - Bar chart weekly
  • Revenue - Area chart

Recent Activity

  • Latest registrations
  • Recent job postings
  • Pending payment requests
  • Flagged reviews

Users Management

File: pages/users/UsersListPage.tsx

List all users with filters and actions.

Table Columns

ColumnTypeSortable
NameStringYes
PhoneStringNo
EmailStringNo
LocationStringYes
RoleBadgeYes
StatusBadgeYes
CreditsNumberYes
CreatedDateYes
ActionsButtonsNo

Filters

  • Role (job_seeker, service_worker, client, hybrid)
  • Status (active, inactive)
  • Has credits
  • Date range

Actions

  • View details
  • Edit user
  • Add credits
  • Suspend/Activate
  • Delete (with confirmation)

File: pages/users/UserDetailPage.tsx

Detailed user view.

Sections

  1. Profile - Basic info, photo, bio
  2. Education - List of education entries
  3. Experience - Work history
  4. Credits - Balance and transaction history
  5. Applications - Job applications
  6. Interviews - AI interview results
  7. Activity Log - Login history, actions

Employers Management

File: pages/employers/EmployersListPage.tsx

Table Columns

ColumnType
CompanyString
IndustryString
LocationString
Jobs PostedNumber
Active JobsNumber
VerifiedBadge
CreatedDate
ActionsButtons

Actions

  • View details
  • Verify employer
  • Suspend
  • Delete

Jobs Management

File: pages/jobs/JobsListPage.tsx

Table Columns

ColumnType
TitleString
CompanyString
LocationString
SalaryCurrency
TypeBadge
ApplicationsNumber
StatusBadge
PostedDate
ActionsButtons

Bulk Actions

  • Deactivate selected
  • Boost selected
  • Delete selected

File: pages/jobs/JobDetailPage.tsx

Sections

  1. Job Info - All details
  2. Applications - List with status
  3. Analytics - Views, saves, shares
  4. AI Interviews - Interview results for this job

Payments Management

File: pages/payments/PaymentRequestsPage.tsx

Handle credit purchase requests.

Table Columns

ColumnType
UserLink
PackageString
AmountCurrency
CreditsNumber
Payment MethodString
ReferenceString
StatusBadge
CreatedDate
ActionsButtons

Status Flow

pending → confirmed (credits added)
       → rejected (no credits)
       → expired (auto after 48h)

Actions

  • Confirm - Add credits to user
  • Reject - Mark as rejected with reason
  • View Reference - See submitted payment reference

File: pages/payments/CashoutRequestsPage.tsx

Worker cashout requests.

Actions

  • Process - Mark as processing
  • Complete - Mark as paid (provide transaction ID)
  • Reject - Decline with reason

Services Management

File: pages/services/WorkersListPage.tsx

Service worker profiles.

Table Columns

ColumnType
NameString
HeadlineString
CategoriesTags
LocationString
RatingStars
Jobs CompletedNumber
VerifiedBadge
AvailableBadge
ActionsButtons

Actions

  • View profile
  • Verify worker
  • Suspend
  • Edit categories

File: pages/services/CategoriesPage.tsx

Manage service categories.

Features

  • Tree view of categories (parent → children)
  • Create new category
  • Edit category (name, slug, icon, description)
  • Reorder categories
  • Deactivate category
  • Merge categories

File: pages/services/BookingsListPage.tsx

All service bookings.

Table Columns

ColumnType
ClientLink
WorkerLink
CategoryString
DateDateTime
PriceCurrency
StatusBadge
CreatedDate
ActionsButtons

Reviews Management

File: pages/reviews/ReviewsListPage.tsx

Review moderation.

Table Columns

ColumnType
ReviewerLink
WorkerLink
RatingStars
CommentText (truncated)
StatusBadge
CreatedDate
ActionsButtons

Actions

  • View full review
  • Hide review (flag as inappropriate)
  • Restore hidden review
  • Delete permanently

Layout Components

Layout

File: components/layout/Layout.tsx

tsx
export function Layout() {
  const { user, isLoading } = useAuth();
  
  if (isLoading) return <LoadingScreen />;
  if (!user) return <Navigate to="/login" replace />;
  
  return (
    <div className="flex h-screen">
      <Sidebar />
      <div className="flex-1 flex flex-col overflow-hidden">
        <Header />
        <main className="flex-1 overflow-y-auto p-6 bg-gray-50">
          <Outlet />
        </main>
      </div>
    </div>
  );
}

Navigation sidebar with sections.

tsx
const navItems = [
  { label: 'Dashboard', icon: LayoutDashboard, path: '/dashboard' },
  { label: 'Users', icon: Users, path: '/users' },
  { label: 'Employers', icon: Building2, path: '/employers' },
  { label: 'Jobs', icon: Briefcase, path: '/jobs' },
  { section: 'Payments' },
  { label: 'Payment Requests', icon: CreditCard, path: '/payments' },
  { label: 'Cashouts', icon: Banknote, path: '/cashouts' },
  { label: 'Transactions', icon: ArrowLeftRight, path: '/transactions' },
  { section: 'Services' },
  { label: 'Workers', icon: Wrench, path: '/workers' },
  { label: 'Categories', icon: Tags, path: '/categories' },
  { label: 'Bookings', icon: Calendar, path: '/bookings' },
  { section: 'Content' },
  { label: 'Reviews', icon: Star, path: '/reviews' },
];

API Integration

typescript
// api/index.ts
const ADMIN_API_URL = import.meta.env.VITE_ADMIN_API_URL;

export const adminApi = {
  // Users
  getUsers: (params) => fetch(`${ADMIN_API_URL}/admin/users?${qs(params)}`),
  getUser: (id) => fetch(`${ADMIN_API_URL}/admin/users/${id}`),
  updateUser: (id, data) => fetch(`${ADMIN_API_URL}/admin/users/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  }),
  addCredits: (userId, amount, reason) => fetch(`${ADMIN_API_URL}/admin/users/${userId}/credits`, {
    method: 'POST',
    body: JSON.stringify({ amount, reason }),
  }),
  
  // Payments
  getPaymentRequests: (params) => fetch(`${ADMIN_API_URL}/admin/payments?${qs(params)}`),
  confirmPayment: (id) => fetch(`${ADMIN_API_URL}/admin/payments/${id}/confirm`, { method: 'POST' }),
  rejectPayment: (id, reason) => fetch(`${ADMIN_API_URL}/admin/payments/${id}/reject`, {
    method: 'POST',
    body: JSON.stringify({ reason }),
  }),
  
  // ... etc
};

Deployment

bash
# Build
npm run build

# Deploy to Cloudflare Pages
npx wrangler pages deploy dist --project-name=yebojobs-admin

Custom Domain: admin.yebojobs.com

One chat. Everything done.