A modern, responsive dashboard built with React that features a drag-and-drop interface for customizable layouts. This project combines beautiful charts, interactive components, and a flexible grid system to create a powerful dashboard experience.
- Drag & Drop Interface: Rearrange dashboard components with ease
- Responsive Grid Layout: 12-column grid system with customizable positioning
- Rich Chart Library: Multiple chart types using Recharts
- Persistent Layout: Layout changes are saved to localStorage
- Modern UI: Built with Tailwind CSS and Material-UI
- Lazy Loading: Components load on-demand for better performance
- Collapsible Sidebar: Space-efficient navigation
- Node.js (v16 or higher)
- npm or yarn package manager
-
Clone the repository
git clone <repository-url> cd drag-and-drop-react
-
Install dependencies
npm install
-
Start the development server
npm run dev
-
Open your browser Navigate to
http://localhost:5173to view the dashboard
src/
├── components/
│ ├── Charts/ # Chart components (Recharts)
│ ├── Header/ # Top navigation bar
│ ├── Sidebar/ # Collapsible sidebar
│ ├── Tabs/ # Dashboard widgets and tabs
│ └── WelcomeCard/ # Welcome/overview card
├── pages/
│ └── Dashboard.jsx # Main dashboard with grid layout
├── assets/
│ └── avatars/ # Avatar components
├── App.jsx # Main application component
└── main.jsx # Application entry point
The dashboard uses react-grid-layout with a 12-column grid system. Each component has specific positioning and sizing properties:
x: Horizontal position (0-11, where 0 is the leftmost column)y: Vertical position (row number, starting from 0)w: Width in grid columns (1-12)h: Height in grid rows (each row is 80px by default)
{
i: "custom-line-chart", // Unique identifier
component: <CustomLineChart />,
x: 0, // Starts at leftmost column
y: 0, // Starts at top row
w: 4, // Takes 4 columns wide
h: 7, // Takes 7 rows tall (560px)
}| Component | Description | Default Size | Data Type |
|---|---|---|---|
CustomLineChart |
Multi-line revenue chart | 4×7 | Time series data |
PieChart |
Department distribution | 4×7 | Categorical data |
CustomRadarChart |
Performance radar chart | 4×7 | Multi-dimensional data |
WaveChart |
Animated wave chart | 4×5 | Real-time data |
SingleBarChart |
Simple bar chart | 4×5 | Single series data |
GroupedBarChart |
Multiple bar series | 4×5 | Multi-series data |
LinearChart |
Linear trend chart | 6×5 | Trend data |
PerformanceChart |
Performance metrics | 6×5 | KPI data |
HorizontalBarChart |
Horizontal bars | 6×5 | Ranking data |
CustomGaugeChart |
Gauge/progress chart | 6×5 | Percentage data |
SmoothCurveChart |
Smooth curve chart | 6×4 | Continuous data |
| Component | Description | Default Size |
|---|---|---|
RecentUpdateList |
Recent activity feed | 4×6 |
TeamStatus |
Team member status | 4×6 |
Schedule |
Calendar/schedule | 4×11 |
Holidays |
Holiday calendar | 4×7 |
Notes |
Notes widget | 4×7 |
RecentUpdates |
Update notifications | 8×7 |
LeaveSummary |
Leave management | 4×9 |
PostBox |
Post creation | 6×5 |
Post |
Post display | 6×9 |
BirthdayTabs |
Birthday notifications | 6×7 |
EmployeeCalendar |
Employee calendar | 6×12 |
-
Create the component file
// src/components/Charts/NewChart.jsx import React from "react"; import { LineChart, Line, XAxis, YAxis, ResponsiveContainer, } from "recharts"; const NewChart = () => { const data = [ { name: "Jan", value: 400 }, { name: "Feb", value: 300 }, // ... more data ]; return ( <div className="bg-white rounded-lg shadow-sm p-6 flex flex-col !h-[530px] overflow-hidden"> <div className="flex justify-between items-center mb-6"> <h2 className="text-xl font-bold text-gray-800">Chart Title</h2> </div> <div className="flex-grow min-h-0"> <ResponsiveContainer width="100%" height="100%"> <LineChart data={data}> <XAxis dataKey="name" /> <YAxis /> <Line type="monotone" dataKey="value" stroke="#8884d8" /> </LineChart> </ResponsiveContainer> </div> </div> ); }; export default NewChart;
-
Add lazy import to Dashboard.jsx
const NewChart = lazy(() => import("../components/Charts/NewChart"));
-
Add to defaultElements array
{ i: "new-chart", component: <NewChart />, x: 0, y: 0, w: 4, h: 7, }
Each chart component contains its own data. To customize:
- Locate the data array in the component file
- Replace with your data following the same structure
- Update chart properties like colors, titles, and dimensions
Example for CustomLineChart:
const data = [
{ sector: "Your Category", 2022: 30, 2023: 40, 2024: 80 },
// Add more data points
];Components use Tailwind CSS classes. Common styling patterns:
- Container:
bg-white rounded-lg shadow-sm p-6 - Title:
text-xl font-bold text-gray-800 - Chart container:
flex-grow min-h-0 - Responsive height:
!h-[530px](for consistent sizing)
Edit the defaultElements array in src/pages/Dashboard.jsx:
const defaultElements = [
{
i: "custom-line-chart",
component: <CustomLineChart />,
x: 0, // Horizontal position (0-11)
y: 0, // Vertical position (row number)
w: 4, // Width in columns (1-12)
h: 7, // Height in rows
},
// ... more components
];- Total width: 12 columns
- Row height: 80px (configurable in ReactGridLayout)
- Minimum size: 1×1
- Maximum size: 12×∞ (limited by container height)
The dashboard automatically saves layout changes to localStorage. To reset:
- Click the "Reset Layout" button in the top-right corner
- Or clear localStorage manually:
localStorage.removeItem("dashboardLayout")
In src/pages/Dashboard.jsx, modify the ReactGridLayout props:
<ReactGridLayout
className="layout"
layout={layout}
cols={12} // Number of columns
rowHeight={80} // Height of each row in pixels
width={1200} // Container width
onLayoutChange={handleLayoutChange}
draggableHandle=".grid-drag-handle"
// Additional props:
// isDraggable={true} // Enable/disable dragging
// isResizable={true} // Enable/disable resizing
// margin={[10, 10]} // Grid margins
// containerPadding={[10, 10]} // Container padding
/>The grid layout is responsive by default. For mobile-specific layouts:
const layouts = {
lg: layout, // Desktop layout
md: layout, // Tablet layout
sm: layout, // Mobile layout
};- Lazy loading: Components load only when needed
- Suspense boundaries: Loading states for better UX
- Memoization: Consider wrapping components in
React.memo()for heavy charts
The project uses a consistent color palette:
- Primary: Blue tones (
#3B82F6,#1E40AF) - Secondary: Gray tones (
#6B7280,#9CA3AF) - Background: Light gray (
#F4F6F9,#F8FCFF) - Charts: Various colors for data visualization
- Font: Manrope (Google Fonts)
- Weights: 300, 400, 500, 700
- Sizes: Responsive text sizing with Tailwind classes
Modify the theme in src/App.jsx:
const theme = createTheme({
typography: {
fontFamily: "Manrope, Arial, sans-serif",
},
palette: {
primary: {
main: "#3B82F6",
},
// ... more theme options
},
});npm run build- Install Vercel CLI:
npm i -g vercel - Deploy:
vercel
- Build the project:
npm run build - Upload the
distfolder to Netlify
-
Charts not rendering
- Check if Recharts is properly installed
- Verify data structure matches chart requirements
-
Layout not saving
- Check browser localStorage support
- Verify localStorage permissions
-
Performance issues
- Reduce chart data points
- Implement virtualization for large datasets
- Use React.memo() for expensive components
Enable debug logging in the browser console:
// Add to Dashboard.jsx
console.log("Layout changed:", newLayout);
console.log("Elements:", elements);- React: UI library
- react-grid-layout: Drag-and-drop grid system
- Recharts: Chart library
- Tailwind CSS: Utility-first CSS framework
- Material-UI: Component library
- Lucide React: Icon library
- Vite: Build tool and dev server
- ESLint: Code linting
- TypeScript: Type checking (optional)
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License.
For support and questions:
- Check the troubleshooting section
- Review the component documentation
- Open an issue on GitHub
- Contact the development team
Happy Dashboard Building! 🎉