DEV Community

Software Solutions
Software Solutions

Posted on

Building a Modern CRM Dashboard with React, Tailwind CSS, and Recharts

Building a modern Customer Relationship Management (CRM) platform requires more than just displaying raw database records. Users expect interactive analytics, clear data visualization, responsive layouts, and lightning-fast UI updates.

In this guide, we'll walk through architecting a sleek, responsive CRM analytics dashboard using React, Tailwind CSS, and Recharts.


1. Dashboard Architecture & Component Hierarchy

To keep our CRM modular and easy to maintain, we break down the UI into specialized components:

src/
├── components/
│   ├── layout/
│   │   ├── Sidebar.jsx
│   │   └── Header.jsx
│   ├── dashboard/
│   │   ├── MetricCard.jsx
│   │   ├── RevenueChart.jsx
│   │   └── RecentDealsTable.jsx
└── pages/
└── Dashboard.jsx
Enter fullscreen mode Exit fullscreen mode

2. Key Performance Metric Cards

KPI cards sit at the top of the dashboard to give team leaders instant insight into active pipeline value, customer acquisition, and conversion rates.

Here is a clean, reusable MetricCard component built with Tailwind CSS:

import React from 'react';
import { TrendingUp, TrendingDown } from 'lucide-react';

export const MetricCard = ({ title, value, change, isPositive, icon: Icon }) => {
  return (
    <div className="bg-white dark:bg-slate-900 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm transition-all hover:shadow-md">
      <div className="flex items-center justify-between">
        <span className="text-sm font-medium text-slate-500 dark:text-slate-400">{title}</span>
        <div className="p-2.5 rounded-xl bg-indigo-50 text-indigo-600 dark:bg-indigo-950/50 dark:text-indigo-400">
          <Icon className="w-5 h-5"/>
        </div>
      </div>

      <div className="mt-4 flex items-baseline justify-between">
        <h3 className="text-2xl font-bold text-slate-900 dark:text-white">{value}</h3>
        <span className={`inline-flex items-center text-xs font-semibold px-2 py-0.5 rounded-full ${
          isPositive 
            ? 'bg-emerald-50 text-emerald-600 dark:bg-emerald-950/50 dark:text-emerald-400' 
            : 'bg-rose-50 text-rose-600 dark:bg-rose-950/50 dark:text-rose-400'
        }`}>
          {isPositive ? <TrendingUp className="w-3 h-3 mr-1"/> : <TrendingDown className="w-3 h-3 mr-1"/>}
          {change}
        </span>
      </div>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

3. Visualizing Pipeline Revenue with Recharts

A CRM without charts is just a spreadsheet. We'll use Recharts to render a responsive, dynamic area chart showing monthly recurring revenue (MRR) trends.

Bash

npm install recharts lucide-react

Enter fullscreen mode Exit fullscreen mode

JavaScript


import React from 'react';
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';

const data = [
  { month: 'Jan', revenue: 32000 },
  { month: 'Feb', revenue: 41000 },
  { month: 'Mar', revenue: 38000 },
  { month: 'Apr', revenue: 52000 },
  { month: 'May', revenue: 61000 },
  { month: 'Jun', revenue: 75000 },
];

export const RevenueChart = () => {
  return (
    <div className="bg-white dark:bg-slate-900 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm">
      <div className="flex items-center justify-between mb-6">
        <div>
          <h2 className="text-lg font-bold text-slate-900 dark:text-white">Revenue Pipeline</h2>
          <p className="text-xs text-slate-500">Monthly recurring revenue growth</p>
        </div>
      </div>

      <div className="h-72 w-full">
        <ResponsiveContainer height="100%" width="100%">
          <AreaChart data="{data}">
            <defs>
              <linearGradient id="colorRevenue" x1="0" y1="0" x2="0" y2="1">
                <stop offset="5%" stopColor="#6366f1" stopOpacity={0.3}/>
                <stop offset="95%" stopColor="#6366f1" stopOpacity={0}/>
              </linearGradient>
            </defs>
            <XAxis dataKey="month" fontSize="{12}" stroke="#94a3b8" tickLine="{false}"/>
            <YAxis fontSize="{12}" stroke="#94a3b8" tickFormatter="{(val)" tickLine="{false}"> `$${val / 1000}k`} />
            <Tooltip '#0f172a', '#fff', '8px', 'none' backgroundColor: border: borderRadius: color: contentStyle="{{" formatter="{(value)" }}> [`$${value.toLocaleString()}`, 'Revenue']}
            />
            <Area dataKey="revenue" fill="url(#colorRevenue)" fillOpacity="{1}" stroke="#6366f1" strokeWidth="{3}" type="monotone"/>
          </AreaChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

4. Building an Actionable Data Table for Recent Deals

Data tables in CRMs need clear status badges and quick action triggers.

import React from 'react';

const deals = [
  { id: 1, company: 'Acme Corp', contact: 'Sarah Jenkins', value: '$24,000', status: 'Won', stage: 'Contract Signed' },
  { id: 2, company: 'TechStart Inc', contact: 'Michael Chen', value: '$12,500', status: 'In Progress', stage: 'Proposal Sent' },
  { id: 3, company: 'Global Logistics', contact: 'Elena Rostova', value: '$45,000', status: 'In Progress', stage: 'Negotiation' },
];

export const RecentDealsTable = () => {
  return (
    <div className="bg-white dark:bg-slate-900 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm overflow-hidden">
      <div className="p-6 border-b border-slate-200 dark:border-slate-800">
        <h2 className="text-lg font-bold text-slate-900 dark:text-white">Active Pipeline Deals</h2>
      </div>

      <div className="overflow-x-auto">
        <table className="w-full text-left text-sm text-slate-600 dark:text-slate-400">
          <thead className="bg-slate-50 dark:bg-slate-800/50 text-xs uppercase text-slate-500 font-semibold">
            <tr>
              <th className="px-6 py-3">Company</th>
              <th className="px-6 py-3">Contact</th>
              <th className="px-6 py-3">Deal Value</th>
              <th className="px-6 py-3">Stage</th>
              <th className="px-6 py-3">Status</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-200 dark:divide-slate-800">
            {deals.map((deal) => (
              <tr key={deal.id} className="hover:bg-slate-50/50 dark:hover:bg-slate-800/30 transition-colors">
                <td className="px-6 py-4 font-semibold text-slate-900 dark:text-white">{deal.company}</td>
                <td className="px-6 py-4">{deal.contact}</td>
                <td className="px-6 py-4 font-mono font-medium text-slate-900 dark:text-white">{deal.value}</td>
                <td className="px-6 py-4">{deal.stage}</td>
                <td className="px-6 py-4">
                  <span className={`inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold ${
                    deal.status === 'Won' 
                      ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-950/60 dark:text-emerald-400' 
                      : 'bg-amber-100 text-amber-700 dark:bg-amber-950/60 dark:text-amber-400'
                  }`}>
                    {deal.status}
                  </span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode
  1. Performance Optimization Tips for React Dashboards
  • Memoize Complex Calculations: Wrap heavy data-transforming routines inside useMemo so chart rerenders don't block main-thread interaction.
  • Paginate & Virtualize Long Tables: If your table renders thousands of customer interactions, use @tanstack/react-virtual to DOM-render only visible rows.
  • Optimistic UI Updates: When updating lead status or closing a deal, update the local state immediately before waiting for backend API responses to keep the frontend snappy.

Summary

Building a modern CRM dashboard requires combining functional UI architecture, data visualizers, and responsive layout styling. With React, Tailwind CSS, and Recharts, you can deliver a high-performing user interface that simplifies complex sales operations.
Need Custom SaaS or Enterprise Software Architecture?

Whether you're building a bespoke CRM system, custom multi-tenant platform, or enterprise dashboard, getting the frontend and backend architecture right is crucial for scaling.

👉 Partner with Software Solutions for custom web application development, full-stack enterprise solutions, cloud architectures, and dedicated software engineering support.

Top comments (0)