When building internal tools or dashboard prototypes, it can be tempting to immediately install heavy component libraries like Material-UI or Ant Design.
While these libraries are powerful, for many early-stage prototypes a lightweight setup using Vite, React, and Vanilla CSS can be simpler to customize and easier to maintain.
In this tutorial, we'll look at the frontend architecture of a light-themed CRM dashboard featuring a Kanban-style sales pipeline layout.
Technical Scope
Before looking at the code, it's important to define what this example actually includes.
What this is:
- A static frontend UI prototype
- A React application built with Vite
- A responsive Kanban-style layout
- Static mock CRM data
- Vanilla CSS styling
- Basic menu state using React
useState
What this is NOT:
- A production CRM
- A backend application
- A database-connected system
- An API-integrated application
- An authentication system
- A drag-and-drop Kanban board
The goal here is simply to demonstrate how a clean CRM-style frontend can be structured using React and standard CSS.
The React Component
A dashboard like this can be split into two main areas:
- A sidebar used for navigation
- A main content area containing the sales pipeline
For this prototype, we use React's useState hook to visually track the active navigation item.
The pipeline itself uses static mock data.
import { useState } from 'react';
import './index.css';
function App() {
const [activeMenu, setActiveMenu] = useState('pipeline');
const leads = {
new: [
{
id: 1,
name: 'Acme Corp',
value: '$5,000'
}
],
contacted: [
{
id: 3,
name: 'Wayne Ent',
value: '$8,200'
}
],
qualified: [
{
id: 5,
name: 'Oscorp',
value: '$25,000'
}
],
won: [
{
id: 6,
name: 'Globex',
value: '$14,000'
}
]
};
return (
<div className="crm-app">
{/* Sidebar Navigation */}
<aside className="sidebar-light">
<div className="brand">
<h1>LeadFlow CRM</h1>
</div>
<nav className="nav-menu">
<button
className={
activeMenu === 'dashboard'
? 'active'
: ''
}
onClick={() =>
setActiveMenu('dashboard')
}
>
Dashboard
</button>
<button
className={
activeMenu === 'pipeline'
? 'active'
: ''
}
onClick={() =>
setActiveMenu('pipeline')
}
>
Sales Pipeline
</button>
</nav>
</aside>
{/* Main Content */}
<main className="main-board">
<header className="board-header">
<h2>Sales Pipeline</h2>
<button className="btn-primary">
+ New Deal
</button>
</header>
{/* Kanban Board */}
<div className="kanban-board">
<div className="kanban-column">
<h3>New Leads</h3>
{leads.new.map((lead) => (
<div
className="kanban-card"
key={lead.id}
>
<h4>{lead.name}</h4>
<span className="value">
{lead.value}
</span>
</div>
))}
</div>
{/* Additional columns can be rendered here */}
</div>
</main>
</div>
);
}
export default App;
The CSS Layout
The main layout can be handled entirely with CSS Flexbox.
The root container is displayed as a flex layout so the sidebar and the main dashboard sit next to each other.
.crm-app {
display: flex;
height: 100vh;
overflow: hidden;
background-color: #f8fafc;
color: #0f172a;
}
Sidebar
The sidebar uses a fixed width and does not shrink when the main dashboard grows.
.sidebar-light {
width: 260px;
background-color: #ffffff;
border-right: 1px solid #e2e8f0;
display: flex;
flex-direction: column;
flex-shrink: 0;
}
This keeps the navigation visually stable while the main dashboard content remains flexible.
Main Dashboard Area
The main content area takes up the remaining screen space.
.main-board {
flex-grow: 1;
display: flex;
flex-direction: column;
overflow-x: auto;
}
Horizontal Kanban Layout
The Kanban board is also a flex container.
Each column has a fixed minimum width so the board can scroll horizontally if more columns are added.
.kanban-board {
display: flex;
padding: 32px;
gap: 24px;
overflow-x: auto;
flex-grow: 1;
align-items: flex-start;
}
Individual Kanban Columns
Each pipeline stage is represented by a simple column.
.kanban-column {
min-width: 280px;
width: 280px;
background-color: #f1f5f9;
border-radius: 12px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
}
Cards inside each column can then display information such as:
- Company name
- Deal value
- Status
- Contact information
- Sales stage
For this prototype, the data is intentionally static.
Responsive Behavior
A simple media query can adapt the layout for smaller screens.
For example:
@media (max-width: 768px) {
.crm-app {
flex-direction: column;
}
.sidebar-light {
width: 100%;
}
.kanban-board {
padding: 16px;
overflow-x: auto;
}
}
This can move the sidebar above the dashboard and keep the Kanban board horizontally scrollable on smaller screens.
Why This Approach Can Be Useful
1. Simple Setup
No additional UI component library is required for this prototype, which keeps the setup simple and gives you direct control over the styling.
2. Fast Development Workflow
Vite provides a fast development experience with quick startup and hot module replacement for typical frontend projects.
3. Full Styling Control
Using Vanilla CSS means you control:
- spacing
- typography
- colors
- borders
- shadows
- responsive behavior
without overriding a component library's existing design system.
4. Clear Component Structure
React makes it easy to break a dashboard into reusable pieces such as:
- Sidebar
- Header
- Kanban Column
- Deal Card
- Metric Card
- Table
- Form
As the prototype grows, these can be separated into individual components.
Important Limitations
This example is intentionally limited to frontend UI structure.
It does not include:
- API requests
- Authentication
- Database storage
- Drag-and-drop behavior
- Real CRM data
- Backend business logic
Those features would require additional development beyond the scope of this lightweight frontend prototype.
Final Result
Using only:
- React
- Vite
- Vanilla CSS
- Static mock data
you can build a clean and responsive CRM-style dashboard prototype without immediately introducing large UI libraries or backend infrastructure.
This type of setup can be useful when validating an interface, building an internal-tool prototype, or turning an existing wireframe into a functional frontend.
If you need help building a small responsive React dashboard or frontend prototype, you can view my Upwork service here:
Top comments (0)