← Components/Dashboard & App UI

DataTable

datatable-1779383784229.tsx
'use client';

import React, { useState, useMemo } from 'react';

interface DataTableProps {
  category: string;
}

interface RowData {
  id: number;
  name: string;
  status: 'active' | 'inactive';
  date: string;
}

const DataTable: React.FC<DataTableProps> = () => {
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
  const [sortedColumn, setSortedColumn] = useState<string | null>(null);
  const [pageNumber, setPageNumber] = useState(0);
  const rowsPerPage = 10;

  const data: RowData[] = useMemo(() => {
    return Array(100)
      .fill(0)
      .map((_, index) => ({
        id: index + 1,
        name: `Row ${index + 1}`,
        status: index % 2 === 0 ? 'active' : 'inactive',
        date: `2022-01-${index + 1}`,
      }));
  }, []);

  const sortedData = useMemo(() => {
    if (!sortedColumn) return data;
    return data.slice().sort((a, b) => {
      if (a[sortedColumn as keyof RowData] < b[sortedColumn as keyof RowData]) {
        return sortOrder === 'asc' ? -1 : 1;
      }
      if (a[sortedColumn as keyof RowData] > b[sortedColumn as keyof RowData]) {
        return sortOrder === 'asc' ? 1 : -1;
      }
      return 0;
    });
  }, [data, sortedColumn, sortOrder]);

  const paginatedData = sortedData.slice(pageNumber * rowsPerPage, (pageNumber + 1) * rowsPerPage);

  const handleSort = (column: string) => {
    if (sortedColumn === column) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      setSortedColumn(column);
      setSortOrder('asc');
    }
  };

  return (
    <div className="max-w-7xl mx-auto p-4 bg-zinc-950">
      <table className="w-full text-left text-xs sm:text-sm">
        <thead className="bg-zinc-800">
          <tr>
            <th
              className="px-4 py-2 cursor-pointer"
              onClick={() => handleSort('id')}
            >
              ID {sortedColumn === 'id' && (sortOrder === 'asc' ? '↑' : '↓')}
            </th>
            <th
              className="px-4 py-2 cursor-pointer"
              onClick={() => handleSort('name')}
            >
              Name {sortedColumn === 'name' && (sortOrder === 'asc' ? '↑' : '↓')}
            </th>
            <th
              className="px-4 py-2 cursor-pointer"
              onClick={() => handleSort('status')}
            >
              Status {sortedColumn === 'status' && (sortOrder === 'asc' ? '↑' : '↓')}
            </th>
            <th
              className="px-4 py-2 cursor-pointer"
              onClick={() => handleSort('date')}
            >
              Date {sortedColumn === 'date' && (sortOrder === 'asc' ? '↑' : '↓')}
            </th>
          </tr>
        </thead>
        <tbody>
          {paginatedData.map((row) => (
            <tr
              key={row.id}
              className="bg-zinc-900 hover:bg-zinc-800 transition duration-200"
            >
              <td className="px-4 py-2">{row.id}</td>
              <td className="px-4 py-2">{row.name}</td>
              <td className="px-4 py-2">
                <span
                  className={`py-1 px-2 rounded ${
                    row.status === 'active' ? 'bg-green-500 text-white' : 'bg-red-500 text-white'
                  }`}
                >
                  {row.status}
                </span>
              </td>
              <td className="px-4 py-2">{row.date}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <div className="flex justify-between mt-4">
        <button
          className="px-4 py-2 bg-c9a84c text-zinc-950 hover:bg-c9a84c/80 transition duration-200"
          onClick={() => setPageNumber(pageNumber - 1)}
          disabled={pageNumber === 0}
        >
          Prev
        </button>
        <span className="text-xs sm:text-sm">
          Page {pageNumber + 1} of {Math.ceil(data.length / rowsPerPage)}
        </span>
        <button
          className="px-4 py-2 bg-c9a84c text-zinc-950 hover:bg-c9a84c/80 transition duration-200"
          onClick={() => setPageNumber(pageNumber + 1)}
          disabled={pageNumber >= Math.ceil(data.length / rowsPerPage) - 1}
        >
          Next
        </button>
      </div>
    </div>
  );
};

export default DataTable;

Component info

CategoryDashboard & App UI
Frameworkreact
TierFREE
Views0
Copies0

About

Sortable data table with pagination

More from Dashboard & App UI

'use client'
import { useState, useEffect, useRef } from 'react'

const METRICS = [
  { label: 'Monthly Revenue', value: 48320, prev: 41200, prefix: '$', suffix: '', color: '#C9A84C', data: [22,28,24,32,28,38,35,42,40,48] },
  { label: 'Active Users'
KPICards
Dashboard & App UI
'use client'
import { useState, useEffect } from 'react'

type EventType = 'component_added' | 'user_signup' | 'purchase' | 'api_call' | 'review'

const EVENTS: { id: number; type: EventType; user: string; detail: string; time: number; color: string;
ActivityFeed
Dashboard & App UI
import React from 'react';

interface MetricCardProps {
  value: number;
  trend: 'up' | 'down';
  sparklineData: number[];
}

const MetricCard: React.FC<MetricCardProps> = ({ value, trend, sparklineData }) => {
  return (
    <div style={{ backgroun
MetricCard
Dashboard & App UI
import React from 'react';
import './ProgressRing.css';
interface ProgressRingProps {
  percentage: number;
}
const ProgressRing: React.FC<ProgressRingProps> = ({ percentage }) => {
  const circleDashArray = 2 * Math.PI * 50;
  const circleDashOffset
ProgressRing
Dashboard & App UI