Build in Public

Next.js 14 + Tailwind CSS: Building a Dark-Theme Financial Dashboard

ClawDUX TeamApril 9, 20267 min read0 views

Next.js 14 + Tailwind CSS: Building a Dark-Theme Financial Dashboard

Here's how we built ClawDUX's dashboard — a production financial UI that handles real-time data, complex layouts, and looks good doing it.

Project Setup

bash
npx create-next-app@14 dashboard --typescript --tailwind --app

The Design System

Every financial UI needs three things: data density, visual hierarchy, and color that communicates.

javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        surface: {
          DEFAULT: '#0f1117',
          card: '#1a1d27',
          elevated: '#232733',
          border: '#2a2e3a',
        },
        primary: {
          50: '#eff6ff',
          400: '#60a5fa',
          500: '#3b82f6',
          600: '#2563eb',
        },
        profit: '#22c55e',
        loss: '#ef4444',
      },
      fontFamily: {
        mono: ['SF Mono', 'Fira Code', 'monospace'],
      },
    },
  },
};

Component: Data Table

Financial data needs monospace numbers for alignment:

tsx
interface Column<T> {
  key: keyof T;
  label: string;
  align?: 'left' | 'right';
  render?: (value: any, row: T) => React.ReactNode;
}

function DataTable<T extends Record<string, any>>({
  data,
  columns,
}: {
  data: T[];
  columns: Column<T>[];
}) {
  return (
    <div className="bg-surface-card border border-surface-border
                    rounded-2xl overflow-hidden">
      <table className="w-full">
        <thead>
          <tr className="border-b border-surface-border">
            {columns.map((col) => (
              <th
                key={String(col.key)}
                className={`px-4 py-3 text-xs font-semibold
                           text-gray-500 uppercase tracking-wider
                           text-${col.align || 'left'}`}
              >
                {col.label}
              </th>
            ))}
          </tr>
        </thead>
        <tbody className="divide-y divide-surface-border">
          {data.map((row, i) => (
            <tr
              key={i}
              className="hover:bg-surface-elevated/50
                         transition-colors"
            >
              {columns.map((col) => (
                <td
                  key={String(col.key)}
                  className={`px-4 py-3 text-sm font-mono
                             text-${col.align || 'left'}`}
                >
                  {col.render
                    ? col.render(row[col.key], row)
                    : row[col.key]}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// Usage
<DataTable
  data={strategies}
  columns={[
    { key: 'title', label: 'Strategy', align: 'left' },
    { key: 'returnPct', label: 'Return', align: 'right',
      render: (v) => (
        <span className={v > 0 ? 'text-profit' : 'text-loss'}>
          {v > 0 ? '+' : ''}{v.toFixed(1)}%
        </span>
      )
    },
    { key: 'sharpeRatio', label: 'Sharpe', align: 'right',
      render: (v) => v.toFixed(2)
    },
    { key: 'price', label: 'Price', align: 'right',
      render: (v) => `$${(Number(v) / 1e6).toFixed(2)}`
    },
  ]}
/>

Performance: ISR for Dashboard

tsx
// app/dashboard/page.tsx
export const revalidate = 60; // Revalidate every 60 seconds

export default async function DashboardPage() {
  const data = await fetchDashboardData();

  return (
    <div className="grid grid-cols-1 lg:grid-cols-3 gap-4 p-6">
      <StatCard title="Total Volume" value={data.volume} />
      <StatCard title="Active Strategies" value={data.strategies} />
      <StatCard title="Avg Sharpe" value={data.avgSharpe} />

      <div className="lg:col-span-2">
        <DataTable data={data.topStrategies} columns={...} />
      </div>

      <div>
        <RecentActivity activities={data.recent} />
      </div>
    </div>
  );
}

This entire architecture is running in production on ClawDUX, serving real-time strategy data to traders and AI agents.

The core logic discussed in this article has been integrated into the ClawDUX API. Access ClawDUX-core for full permissions, or browse the marketplace to discover verified trading strategies.

#nextjs#tailwind#dashboard#dark-theme#react

Related Articles