Skip to content

Repository files navigation

Luyka Dashboard Starter

Modern React dashboard starter with PHP backend, Radix UI Themes, dark/light mode, authentication flow, and responsive design.

Stack

  • Frontend: React 19 + Vite 8 + @radix-ui/themes + react-router-dom
  • Backend: PHP 8+ (custom router, no framework)
  • Database: MySQL (PDO)
  • Linting: Oxlint

Structure

├── api/                       # PHP backend
│   ├── index.php              # Front-controller / router
│   ├── Database.php           # PDO singleton
│   ├── .env                   # DB creds + FRONTEND_URL
│   ├── .htaccess              # URL rewriting (API + SPA fallback)
│   ├── controllers/
│   │   ├── AuthTrait.php      # authenticate() middleware
│   │   ├── AuthController.php # Login, register, 2FA, password reset
│   │   ├── UserController.php # CRUD users + admin 2FA management
│   │   ├── DashboardController.php # Stats endpoints
│   │   └── SettingsController.php  # Mail settings
│   ├── helpers/
│   │   ├── TOTP.php           # TOTP (RFC 6238) secret generation & verification
│   │   └── Mailer.php         # PHPMailer wrapper
│   ├── lib/phpmailer/         # PHPMailer library
│   └── migrations/
│       └── database.sql       # Full DB backup
├── dist/                      # Production frontend build (SPA fallback)
src/
├── auth.jsx                   # Auth context + hook (sessionStorage)
├── components/
│   ├── ActivitySection.jsx    # Recent activity list
│   ├── ChartsSection.jsx      # Revenue chart + traffic sources
│   ├── Footer.jsx             # Public footer
│   ├── Icon.jsx               # SVG icon library
│   ├── PublicNavbar.jsx       # Public site navbar with theme toggle
│   ├── Sidebar.jsx            # Dashboard sidebar (collapsible, nav, user, theme)
│   ├── StatsGrid.jsx          # Stats cards (Revenue, Users, Orders, Growth)
│   └── TopBar.jsx             # Dashboard top bar (search, notifications, avatar)
├── pages/
│   ├── Landing.jsx            # Public landing page (hero, features, stats, CTA)
│   ├── Login.jsx              # Login form
│   ├── ForgotPassword.jsx     # Password reset request
│   ├── ResetPassword.jsx      # New password form
│   └── Dashboard.jsx          # Protected admin dashboard
├── App.jsx                    # Router + Theme provider
├── main.jsx                   # Entry point
├── index.css                  # Global reset
└── App.css                    # All component styles

Frontend Routes

Path Page Auth
/ Landing Public
/login Login Public
/forgot-password Forgot password Public
/reset-password Reset password Public
/dashboard Dashboard Protected

Frontend Features

  • Dark/Light mode — toggle in sidebar (dashboard) and navbar (landing), persisted via Theme prop
  • Collapsible sidebar — expand/collapse with animated width transition (260px ↔ 64px)
  • Responsive — sidebar becomes overlay on mobile (<768px), stats grid adapts
  • Auth flow — auth context, protected routes, logout
  • Login system — login, forgot password, reset password pages
  • Dashboard widgets — stats cards, bar chart, traffic progress bars, activity feed
  • Radix theming — accent color, radius, and dark mode controlled from <Theme>

API

All endpoints are prefixed with /dashboard-starter/api.
Authentication via Authorization: Bearer <token> header (exceptions noted).

Auth

Method Endpoint Auth Body Response
POST /auth/login No { email, password } { data: { token, user } } or { data: { requires_2fa: true, user_id } }
POST /auth/register No { name, email, password } { data: { id, name, email } }
GET /auth/me Yes { data: { id, name, email, role, two_factor_enabled } }
POST /auth/forgot-password No { email } { data: { message } }
POST /auth/reset-password No { token, password } { data: { message } }

2FA (self-service, for the authenticated user)

Method Endpoint Auth Body Response
POST /auth/2fa/enable Yes { data: { secret, otpauth_url } }
POST /auth/2fa/confirm Yes { code } { data: { message, recovery_codes } }
POST /auth/2fa/disable Yes { password } { data: { message } }
POST /auth/2fa/verify No { user_id, code } { data: { token, user } }
POST /auth/2fa/recovery No { user_id, code } { data: { token, user } }

2FA (admin management, for any user)

Method Endpoint Auth Body Response
POST /users/{id}/2fa/enable Yes { data: { secret, otpauth_url } }
POST /users/{id}/2fa/confirm Yes { code } { data: { message, recovery_codes } }
POST /users/{id}/2fa/disable Yes { data: { message } }

Users

Method Endpoint Auth Body Response
GET /users Yes { data: [ { id, name, email, role, two_factor_enabled, created_at } ] }
POST /users Yes { name, email, password, role? } { data: { id, name, email, role } }
GET /users/{id} Yes { data: { id, name, email, role, two_factor_enabled, created_at } }
PUT /users/{id} Yes { name?, email?, role?, password? } { data: { ...user } }
DELETE /users/{id} Yes { data: { message } }

Dashboard

Method Endpoint Auth Response
GET /dashboard/stats Yes { data: [ { label, value, change, positive } ] }
GET /dashboard/revenue Yes { data: [ { month, total } ] }
GET /dashboard/activity Yes { data: [ { text, time } ] }
GET /dashboard/traffic Yes { data: [ { label, value } ] } (value = percentage)

Mail Settings

Method Endpoint Auth Body Response
GET /mail-settings Yes { data: { mail_host, mail_port, ... } }
PUT /mail-settings Yes { mail_host?, mail_port?, ... } { data: { message, updated } }
POST /mail-settings/test-email Yes { email } { data: { message } }

Error Responses

All endpoints return errors in the format { error: "message" } with appropriate HTTP status codes:

  • 400 — Bad request (missing/invalid fields)
  • 401 — Unauthorized (missing/expired token, invalid credentials)
  • 404 — Not found
  • 409 — Conflict (duplicate email)
  • 500 — Server error

Setup

1. Database

Create a MySQL database (e.g. dashboard-starter) and import the backup:

mysql -u root -p dashboard-starter < api/migrations/database.sql

Or via phpMyAdmin: create database → import api/migrations/database.sql.

2. Configure API

Copy the api/ folder to your web server root and edit api/.env:

DB_HOST=localhost
DB_PORT=3306
DB_NAME=dashboard-starter
DB_USER=root
DB_PASS=
FRONTEND_URL=http://localhost:5173

3. Web Server Setup

WAMP64

# Copy the whole project (or just api/) to:
D:\wamp64\www\dashboard-starter\
# Then access:
http://localhost/dashboard-starter/api/auth/login

XAMPP

# Copy the whole project (or just api/) to:
C:\xampp\htdocs\dashboard-starter\
# Then access:
http://localhost/dashboard-starter/api/auth/login

Laragon

# Copy the whole project (or just api/) to:
C:\laragon\www\dashboard-starter\
# Laragon auto-creates a virtual host, access:
http://dashboard-starter.test/api/auth/login

Note: Apache mod_rewrite must be enabled. The included .htaccess rewrites /api/* to index.php and serves the SPA from dist/ as fallback.

4. Frontend

npm install
npm run dev

The dev server runs on http://localhost:5173.
Make sure VITE_API_URL in .env matches your API URL:

VITE_API_URL=http://localhost/dashboard-starter/api

Default Admin User

Field Value
Email admin@luyka.com
Password admin123

This user is included in the database backup (api/migrations/database.sql) with 2FA disabled by default.

Commands

npm run dev       # Start Vite dev server (frontend)
npm run build     # Production build (frontend)
npm run preview   # Preview production build
npm run lint      # Run oxlint

About

A production-ready React dashboard starter with PHP API, JWT authentication, 2FA, password reset, Radix UI Themes, and MySQL.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages