hihi ne

mail@pastecode.io avatar
unknown
typescript
20 days ago
3.3 kB
3
Indexable
Never
import { faker } from "@faker-js/faker";
import {
  Column,
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  useReactTable,
} from "@tanstack/react-table";
import { DatePicker } from "antd";
import dayjs from "dayjs";
import { range } from "lodash-es";

type Person = {
  id: string;
  firstName: string;
  lastName: string;
  dob: string;
};

const PERSONS: Person[] = range(30).map(() => ({
  id: faker.string.uuid(),
  firstName: faker.person.firstName(),
  lastName: faker.person.lastName(),
  dob: faker.date
    .between({
      from: "2024-10-01T00:00:00",
      to: "2024-12-31T00:00:00",
    })
    .toISOString(),
}));

console.table(PERSONS);

const columnHelper = createColumnHelper<Person>();

const columns = [
  columnHelper.accessor("id", {
    header: "ID",
    cell: (info) => <span className="line-clamp-1">{info.getValue()}</span>,
  }),
  columnHelper.accessor("firstName", {
    header: "First Name",
  }),
  columnHelper.accessor("lastName", {
    header: "Last Name",
  }),
  columnHelper.accessor("dob", {
    header: "DOB",
    cell: (info) => (
      <span className="line-clamp-1">{dayjs(info.getValue()).format("DD/MM/YYYY")}</span>
    ),
    filterFn: (row, id, [from, to]) => {
      if (!from || !to) return true;

      const value = row.getValue(id) as string;

      return dayjs(from).isBefore(value) && dayjs(to).isAfter(value);
    },
  }),
];

function ColumnDateRangeFilter({ column }: { column: Column<Person, string> }) {
  return (
    <DatePicker.RangePicker
      className="font-normal"
      format={{ format: "DD/MM/YYYY" }}
      onChange={(dates) => {
        const from = dates?.[0];
        const to = dates?.[1];

        column.setFilterValue([from?.toISOString(), to?.toISOString()]);
      }}
    />
  );
}

export default function HomePage() {
  const table = useReactTable({
    data: PERSONS,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
  });

  return (
    <div className="prose max-w-full h-full flex flex-col">
      <div className="grow overflow-auto">
        <table>
          <thead className="sticky top-0 bg-white shadow">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id}>
                {headerGroup.headers.map((header, idx) => (
                  <th key={header.id}>
                    <div>{header.column.columnDef.header?.toString()}</div>

                    {idx === 3 ? (
                      <ColumnDateRangeFilter column={header.column as Column<Person, string>} />
                    ) : (
                      <div className="h-8" />
                    )}
                  </th>
                ))}
              </tr>
            ))}
          </thead>

          <tbody className="overflow-auto">
            {table.getRowModel().rows.map((row) => (
              <tr key={row.id}>
                {row.getVisibleCells().map((cell) => (
                  <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <pre className="shrink-0">
        <code>{JSON.stringify(table.getState().columnFilters)}</code>
      </pre>
    </div>
  );
}
Leave a Comment