Welcome to my website U-GINE MEDIA. In this website I teach tutorials and share source code on some programming (HTML, CSS, JavaScript, React) tutorials.
Before we get started, do well to subscribe to my channel to never miss out on any update that I post every single day.
You can also visit my GitHub where I upload all the code I have.
In this tutorial topic "Build A Complete React Admin Dashboard from Scratch | Step by Step Tutorial", we will learn how to create it following these simple easy steps.
Share this to your programmer friends. If y'all learnt something today, make sure to let me in the comments.
Get Source Code.
If interested in watching the video before running the code below, you can click the play button to get started.
Setting Up the Project
Create a Project Folder:
- Make a new folder, for instance, “react-admin-dashboard”.
- Open this folder in your VS Code editor.
Initialize the Project:
npm create vite@latest ./ -- --template react
npm install
npm run dev
Modify folder and CSS Files:
- Remove the default assets folder and App.css file.
- Replace the content of index.css with the provided CSS code.
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;300;400;500;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Poppins", sans-serif;
}
.dashboard {
position: relative;
height: 100vh;
display: flex;
justify-content: flex-start;
align-items: flex-start;
overflow: hidden;
background: #000;
}
.sidebar {
background: #191C24;
height: 100%;
width: 300px;
transition: transform 0.3s ease-in;
}
.main-content {
background: #000;
height: 100%;
width: calc(100% - 300px);
flex: 1;
transition: margin 0.1s ease-in;
}
.sidebar.hide {
transform: translateX(-300px);
}
.sidebar.show {
transform: translateX(0);
}
.main-content.adjust {
width: 100%;
flex-grow: 1;
margin-left: -300px;
}
.logo {
display: block;
padding: 10px 30px;
padding-bottom: 0;
text-decoration: none;
color: #EB1616;
font-size: 1.8em;
font-weight: 600;
display: flex;
align-items: center;
gap: 10px;
}
.user {
padding: 20px;
display: flex;
gap: 15px;
}
.user > div:first-child {
position: relative;
}
.user > div:first-child img {
width: 50px;
height: 50px;
border-radius: 50%;
object-position: center;
object-fit: cover;
}
.user > div:first-child .user-active {
position: absolute;
bottom: 16px;
right: -1px;
width: 10px;
height: 10px;
background: green;
border-radius: 50%;
border: 1px solid #fff;
}
.user > div:last-child h2 {
line-height: normal;
color: #fff;
font-size: 1.1em;
}
.user > div:last-child span {
color: rgba(255, 255, 255, .5);
}
.sidebar-list li {
position: relative;
padding: 0 30px;
margin: 10px 0;
width: 90%;
border-top-right-radius: 30px;
border-bottom-right-radius: 30px;
transition: all 0.3s ease-in;
}
.sidebar-list li a {
display: block;
padding: 10px 0;
text-decoration: none;
font-size: 1.1em;
display: flex;
align-items: center;
gap: 10px;
color: #617293;
transition: all 0.3s ease-in;
}
.sidebar-list li a .icon {
padding: 10px;
border-radius: 50%;
background: #000;
width: 18px;
height: 18px;
transition: all 0.3s ease-in;
}
.sidebar-list li.active {
background: #000;
border-left: 3px solid #EB1616;
}
.sidebar-list li.active a {
color: #EB1616;
}
.sidebar-list li.active a .icon {
background: rgba(255, 255, 255, .2);
}
.sidebar-list li:hover {
background: #000;
border-left: 3px solid #EB1616;
}
.sidebar-list li:hover a {
color: #EB1616;
}
.sidebar-list li:hover a .icon {
background: rgba(255, 255, 255, .2);
}
.main-content-header {
background: #191C24;
padding: 10px 30px;
display: flex;
align-items: center;
justify-content: space-between;
}
.main-content-header > div:first-child {
display: flex;
align-items: center;
gap: 20px;
}
.hamburger {
background: transparent;
border: none;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1em;
cursor: pointer;
color: #EB1616;
background: #000;
padding: 20px;
border-radius: 50%;
}
.main-content-header > div:first-child input {
padding: 10px 15px;
outline: none;
background: #000;
border: none;
border-radius: 5px;
font-family: "Poppins", sans-serif;
color: #617293;
}
.main-content-header > div:first-child input:focus {
outline: 1px solid #EB1616;
}
.main-content-header > div:last-child {
display: flex;
align-items: center;
gap: 40px;
}
.main-content-header > div:last-child > a {
position: relative;
display: flex;
align-items: center;
gap: 10px;
font-size: 1.1em;
color: #617293;
cursor: pointer;
text-decoration: none;
transition: all 0.3s ease-in;
}
.main-content-header > div:last-child > a .icon {
display: inline-block;
width: 15px;
height: 15px;
background: #000;
padding: 15px;
border-radius: 50%;
}
.main-content-header > div:last-child > a:hover {
color: #EB1616;
}
.main-content-header > div:last-child > a .info {
position: absolute;
min-width: 320px;
top: 120%;
left: 0;
background: #191C24;
display: none;
}
.main-content-header > div:last-child > a .info img {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
object-position: center;
}
.main-content-header > div:last-child > a .info > div {
display: flex;
gap: 20px;
padding: 20px 10px;
border-bottom: 1px solid rgba(255, 255, 255, .2);
transition: all 0.3s ease-in;
}
.main-content-header > div:last-child > a .info > div span:first-child {
font-size: 0.9em;
display: block;
color: #fff;
}
.main-content-header > div:last-child > a .info > div span:last-child {
font-size: 0.8em;
color: #617293;
}
.main-content-header > div:last-child > a:focus .info {
display: block;
}
.main-content-header > div:last-child > a .info > div:hover {
background: #000;
}
.main-content-header > div:last-child > a img {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
object-position: center;
}
.info-2 {
position: absolute;
min-width: 180px;
top: 120%;
left: 0;
background: #191C24;
display: none;
}
.info-2 > div {
padding: 20px 10px;
border-bottom: 1px solid rgba(255, 255, 255, .2);
transition: all 0.3s ease-in;
}
.info-2 > div > span:first-child {
font-size: 0.9em;
display: block;
color: #fff;
}
.info-2 > div > span:last-child {
font-size: 0.8em;
color: #617293;
}
.info-2 > div:hover {
background: #000;
}
.main-content-header > div:last-child > a:nth-child(2):focus .info-2 {
display: block;
}
.info-3 {
position: absolute;
min-width: 120px;
top: 120%;
left: 0;
background: #191C24;
display: none;
}
.info-3 > p {
padding: 10px;
border-bottom: 1px solid rgba(255, 255, 255, .2);
transition: all 0.3s ease-in;
font-size: 0.9em;
color: #fff;
}
.info-3 > p:hover {
background: #000;
}
.main-content-header > div:last-child > a:nth-child(3):focus .info-3 {
display: block;
}
.dashboard-body {
padding: 20px;
height: 100vh;
padding-bottom: 50px;
overflow-y: scroll;
}
.top-dashboard {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
}
.top-dashboard > div {
background: #191C24;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 5px;
}
.top-dashboard > div .icon {
font-size: 3em;
color: #EB1616;
}
.top-dashboard > div > div span {
display: block;
text-align: right;
}
.top-dashboard > div > div span:first-child {
color: #617293;
}
.top-dashboard > div > div span:last-child {
color: #fff;
margin-top: 5px;
font-weight: 600;
}
.chart-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 30px;
}
.chart-card {
background: #191C24;
border-radius: 5px;
padding: 20px;
color: #fff;
}
.chart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
}
.chart-header h3 {
font-size: 16px;
}
.chart-header a {
color: #EB1616;
text-decoration: none;
font-size: 14px;
transition: all 0.3s ease-in;
}
.chart-header a:hover {
color: #710303;
}
.table-sales {
width: 100%;
padding: 20px;
background: #191C24;
margin-top: 30px;
border-radius: 5px;
}
.table-title {
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
font-weight: 550;
}
.table-title h3 {
font-size: 16px;
}
.table-title a {
text-decoration: none;
color: #EB1616;
font-weight: normal;
font-size: 14px;
transition: all 0.3s ease-in;
}
.table-title a:hover {
color: #710303;
}
.sales-table {
margin-top: 30px;
width: 100%;
border-collapse: collapse;
}
.sales-table tr {
border: 1px solid rgba(0, 0, 0, .5);
}
.sales-table th, .sales-table td {
padding: 12px 10px;
text-align: left;
font-size: 14px;
color: #617293;
}
.sales-table th {
color: #fff;
}
.detail-btn {
background: #EB1616;
color: #fff;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease-in;
}
.detail-btn:hover {
background: #710303;
}
.sales-table tr:hover {
background: rgba(0, 0, 0, .1);
}
footer {
background: #191C24;
margin-top: 30px;
padding: 20px;
padding-bottom: 40px;
border-radius: 5px;
color: #617293;
display: flex;
align-items: center;
justify-content: space-between;
}
footer a {
text-decoration: none;
color: #EB1616;
}
Creating the Components
- DashboardWidget.jsx
- DashboardWidget.css
Adding the Codes
import React from 'react'
import "./DashboardWidget.css"
import user from "./assets/user.jpg"
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleDoubleLeft, faDeleteLeft } from '@fortawesome/free-solid-svg-icons';
const DashboardWidget = () => {
return (
<div className="dashboard-widgets">
{/* Messages */}
<div className="widget messages">
<div className="widget-header">
<h3>Messages</h3>
<a href="#">Show All</a>
</div>
<div className="message-list">
{[...Array(4)].map((_, i) => (
<div key={i} className="message-item">
<img src={user} alt="User" />
<div className="message-content">
<strong>Peter Parker</strong>
<p>Short message goes here...</p>
</div>
<span className="time">15 minutes ago</span>
</div>
))}
</div>
</div>
{/* Calendar */}
<div className="widget calendar">
<div className="widget-header">
<h3>Calender</h3>
<a href="#">Show All</a>
</div>
<div className="calendar-container">
<div className="calendar-header">
<button>{"<"}</button>
<span>June 2025</span>
<button>{">"}</button>
</div>
<div className="calendar-grid">
{['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'].map((d) => (
<div key={d} className="day-name">{d}</div>
))}
{Array.from({ length: 42 }, (_, i) => (
<div
key={i}
className={`calendar-day ${i === 9 ? 'active-day' : ''}`}
>
{i < 1 || i > 30 ? '' : i}
</div>
))}
</div>
</div>
</div>
{/* To Do List */}
<div className="widget todo">
<div className="widget-header">
<h3>To Do List</h3>
<a href="#">Show All</a>
</div>
<div className="todo-input">
<input type="text" placeholder="Enter task" />
<button className="add-btn">Add</button>
</div>
<ul className="todo-list">
{[...Array(5)].map((_, i) => (
<li key={i} className={`todo-item ${i === 2 ? 'completed' : ''}`}>
<input type="checkbox" defaultChecked={i === 2} />
<span>Short task goes here...</span>
<FontAwesomeIcon icon={faDeleteLeft} className='delete-btn' />
</li>
))}
</ul>
</div>
</div>
);
}
export default DashboardWidget
/* DashboardWidgets.css */
.dashboard-widgets {
display: flex;
gap: 20px;
color: #fff;
flex-wrap: wrap;
margin-top: 30px;
}
.widget {
background-color: #191C24;
padding: 20px;
border-radius: 5px;
flex: 1;
min-width: 300px;
}
.widget-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.widget-header h3 {
font-size: 16px;
font-weight: 600;
}
.widget-header a {
color: #EB1616;
cursor: pointer;
text-decoration: none;
font-size: 14px;
transition: all 0.3s ease-in;
}
.widget-header a:hover {
color: #710303;
}
/* Messages */
.message-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.message-item {
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid rgba(0, 0, 0, .5);
padding-bottom: 0.5rem;
}
.message-item img {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
object-position: center;
}
.message-content p {
color: #617293;
font-size: 0.9rem;
margin: 0;
}
.time {
margin-left: auto;
font-size: 0.8rem;
color: #617293;
}
/* Calendar */
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.calendar-header button {
background: transparent;
border: none;
font-size: 1.2em;
color: #617293;
cursor: pointer;
}
.calendar-header span {
color: #617293;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0.5rem;
text-align: center;
}
.day-name {
font-weight: bold;
color: #617293;
}
.calendar-day {
padding: 0.5rem;
border-radius: 5px;
color: #617293;
cursor: pointer;
transition: all 0.3s ease-in;
}
.calendar-day.active-day {
background: #EB1616;
color: #fff;
}
.calendar-day:hover {
background: #EB1616;
color: #fff
}
/* To Do List */
.todo-input {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.todo-input input {
flex: 1;
padding: 10px 10px;
background: #000;
border: none;
border-radius: 5px;
color: #fff;
font-family: "Poppins", sans-serif;
outline: none;
font-size: 1em;
}
.todo-input input:focus {
outline: 1px solid #EB1616;
}
.add-btn {
background: #EB1616;
color: #fff;
border: none;
padding: 0 10px;
cursor: pointer;
border-radius: 5px;
font-size: 1em;
}
.todo-list {
list-style: none;
padding: 0;
margin: 0;
}
.todo-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 0;
margin: 10px 0;
border-bottom: 1px solid #3a3a4d;
}
.todo-item span {
color: #617293;
}
.todo-item.completed span {
text-decoration: line-through;
}
.delete-btn {
margin-left: auto;
border: none;
font-size: 1.2rem;
cursor: pointer;
color: #EB1616;
}
In App.jsx, add the code.
import React, { useState, useEffect } from "react";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBell, faChartArea, faChartLine, faChartPie, faChevronCircleDown, faMessage, faUserSecret } from "@fortawesome/free-solid-svg-icons";
import { faBars } from "@fortawesome/free-solid-svg-icons";
import user from "./assets/user.jpg"
import { faGauge } from "@fortawesome/free-solid-svg-icons/faGauge";
import { faDatabase } from "@fortawesome/free-solid-svg-icons";
import { faKeyboard } from "@fortawesome/free-solid-svg-icons";
import { faTable } from "@fortawesome/free-solid-svg-icons";
import { faChartColumn } from "@fortawesome/free-solid-svg-icons";
import { faFile } from "@fortawesome/free-solid-svg-icons";
import DashboardWidget from "./DashboardWidget";
//
import {
BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend,
LineChart, Line, AreaChart, Area, ResponsiveContainer
} from "recharts";
export default function App() {
const [sidebarVisible, setSidebarVisible] = useState(true);
const toggleSidebar = () => setSidebarVisible(vis => !vis);
//Bar Data
const barData = [
{ year: "2016", USA: 15, UK: 10, AU: 12 },
{ year: "2017", USA: 35, UK: 30, AU: 25 },
{ year: "2018", USA: 55, UK: 45, AU: 40 },
{ year: "2019", USA: 60, UK: 55, AU: 52 },
{ year: "2020", USA: 58, UK: 50, AU: 48 },
{ year: "2021", USA: 80, UK: 60, AU: 58 },
{ year: "2022", USA: 95, UK: 70, AU: 55 },
];
// Area Data
const areaData = [
{ year: "2016", sales: 10, revenue: 100 },
{ year: "2017", sales: 30, revenue: 150 },
{ year: "2018", sales: 55, revenue: 180 },
{ year: "2019", sales: 45, revenue: 140 },
{ year: "2020", sales: 65, revenue: 190 },
{ year: "2021", sales: 60, revenue: 185 },
{ year: "2022", sales: 85, revenue: 270 },
];
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div style={{
backgroundColor: "#191C24",
padding: "10px",
borderRadius: "3px",
color: "#fff",
fontSize: "13px"
}}>
<p>{label}</p>
{payload.map((entry, index) => (
<p key={index} style={{ color: entry.color }}>
{entry.name}: {entry.value}
</p>
))}
</div>
);
}
return null;
};
//Sales Data
const salesData = [
{ date: "01 Jan 2045", invoice: "INV-0123", customer: "Jhon Doe", amount: "$123", status: "Paid" },
{ date: "01 Jan 2045", invoice: "INV-0123", customer: "Jhon Doe", amount: "$123", status: "Paid" },
{ date: "01 Jan 2045", invoice: "INV-0123", customer: "Jhon Doe", amount: "$123", status: "Paid" },
{ date: "01 Jan 2045", invoice: "INV-0123", customer: "Jhon Doe", amount: "$123", status: "Paid" },
{ date: "01 Jan 2045", invoice: "INV-0123", customer: "Jhon Doe", amount: "$123", status: "Paid" },
];
return (
<div className="dashboard">
{/* Side Bar Navigatoin */}
<aside className={`sidebar ${sidebarVisible ? "show" : "hide"}`}>
<nav>
<a href="" className="logo"><FontAwesomeIcon icon={faUserSecret} /><span>Admin Panel</span></a>
<div className="user">
<div>
<img src={user} alt="user" />
<div className="user-active"></div>
</div>
<div>
<h2>Peter Parker</h2>
<span>Admin</span>
</div>
</div>
<ul className="sidebar-list">
<li className="active"><a href="#"><FontAwesomeIcon className="icon" icon={faGauge} /> <span>Dashboard</span></a></li>
<li><a href="#"><FontAwesomeIcon className="icon" icon={faDatabase} /> <span>Widgets</span></a></li>
<li><a href="#"><FontAwesomeIcon className="icon" icon={faKeyboard} /> <span>Forms</span></a></li>
<li><a href="#"><FontAwesomeIcon className="icon" icon={faTable} /> <span>Tables</span></a></li>
<li><a href="#"><FontAwesomeIcon className="icon" icon={faChartColumn} /> <span>Charts</span></a></li>
<li><a href="#"><FontAwesomeIcon className="icon" icon={faFile} /> <span>Pages</span></a></li>
</ul>
</nav>
</aside>
{/* Main Content */}
<main className={`main-content ${sidebarVisible ? "": "adjust"}`}>
<div className="main-content-header">
<div>
<button className="hamburger" onClick={toggleSidebar}>
<FontAwesomeIcon icon={faBars} />
</button>
<input type="search" placeholder="Search" />
</div>
<div>
<a href="#">
<FontAwesomeIcon className="icon" icon={faMessage} />
<span>Message</span>
<FontAwesomeIcon className="arrow" icon={faChevronCircleDown} />
<div className="info">
<div>
<img src={user} alt="" />
<div>
<span>Parker sends you a message</span>
<span>15 minutes ago</span>
</div>
</div>
<div>
<img src={user} alt="" />
<div>
<span>Parker sends you a message</span>
<span>15 minutes ago</span>
</div>
</div>
<div>
<img src={user} alt="" />
<div>
<span>Parker sends you a message</span>
<span>15 minutes ago</span>
</div>
</div>
</div>
</a>
<a href="#">
<FontAwesomeIcon className="icon" icon={faBell} />
<span>Notification</span>
<FontAwesomeIcon className="arrow" icon={faChevronCircleDown} />
<div className="info-2">
<div>
<span>Profile updated</span>
<span>15 minutes ago</span>
</div>
<div>
<span>New user added</span>
<span>15 minutes ago</span>
</div>
<div>
<span>Password changed</span>
<span>15 minutes ago</span>
</div>
</div>
</a>
<a href="#">
<img src={user} />
<span>Peter Parker</span>
<FontAwesomeIcon className="arrow" icon={faChevronCircleDown} />
<div className="info-3">
<p>My Profile</p>
<p>Settings</p>
<p>Log Out</p>
</div>
</a>
</div>
</div>
{/* Dashboard Body */}
<div className="dashboard-body">
{/* Top Dashboard */}
<div className="top-dashboard">
<div>
<FontAwesomeIcon icon={faChartLine} className="icon" />
<div>
<span>Today Sale</span>
<span>$1234</span>
</div>
</div>
<div>
<FontAwesomeIcon icon={faChartColumn} className="icon" />
<div>
<span>Today Sale</span>
<span>$1234</span>
</div>
</div>
<div>
<FontAwesomeIcon icon={faChartArea} className="icon" />
<div>
<span>Today Sale</span>
<span>$1234</span>
</div>
</div>
<div>
<FontAwesomeIcon icon={faChartPie} className="icon" />
<div>
<span>Today Sale</span>
<span>$1234</span>
</div>
</div>
</div>
{/* Chart Grid */}
<div className="chart-grid">
{/* Worldwide Sales */}
<div className="chart-card">
<div className="chart-header">
<h3>Worldwide Sales</h3>
<a href="#">Show All</a>
</div>
<ResponsiveContainer width="100%" height={250}>
<BarChart data={barData}>
<CartesianGrid strokeDasharray="3 3" stroke="#444" />
<XAxis dataKey="year" stroke="#aaa" />
<YAxis stroke="#aaa" />
<Tooltip content={<CustomTooltip />} />
<Legend />
<Bar dataKey="USA" stackId="a" fill="#eb1616" />
<Bar dataKey="UK" stackId="a" fill="#800e12" />
<Bar dataKey="AU" stackId="a" fill="#571419" />
</BarChart>
</ResponsiveContainer>
</div>
{/* Sales & Revenue */}
<div className="chart-card">
<div className="chart-header">
<h3>Salse & Revenue</h3>
<a href="#" className="show-all">Show All</a>
</div>
<ResponsiveContainer width="100%" height={250}>
<AreaChart data={areaData}>
<CartesianGrid strokeDasharray="3 3" stroke="#444" />
<XAxis dataKey="year" stroke="#aaa" />
<YAxis stroke="#aaa" />
<Tooltip content={<CustomTooltip />} />
<Legend />
<Area type="monotone" dataKey="revenue" stroke="#cc4444" fill="#eb1616" />
<Line type="monotone" dataKey="sales" stroke="#e63946" strokeWidth={2} dot />
</AreaChart>
</ResponsiveContainer>
</div>
</div>
{/* Table Sales */}
<div className="table-sales">
<div className="table-title">
<h3>Recent Sales</h3>
<a href="#">Show All</a>
</div>
<table className="sales-table" border={1}>
<thead>
<tr>
<th><input type="checkbox" /></th>
<th>Date</th>
<th>Invoice</th>
<th>Customer</th>
<th>Amount</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{salesData.map((sale, idx) => (
<tr key={idx}>
<td><input type="checkbox" /></td>
<td>{sale.date}</td>
<td>{sale.invoice}</td>
<td>{sale.customer}</td>
<td>{sale.amount}</td>
<td>{sale.status}</td>
<td><button className="detail-btn">Detail</button></td>
</tr>
))}
</tbody>
</table>
</div>
{/* DashBoard Widget */}
<DashboardWidget />
{/* Footer Widget */}
<footer>
<p>© <a href="#">U-GINE MEDIA</a>, All Rights Reserved</p>
<p>Distributed With <a href="#">YouTube</a></p>
</footer>
</div>
</main>
</div>
);
}
0 Comments
We are happy to hear from you.