Table

mail@pastecode.io avatar
unknown
tsx
21 days ago
4.8 kB
3
Indexable
Never
import {
    createColumnHelper,
    getCoreRowModel,
    getFilteredRowModel,
    getSortedRowModel,
    useReactTable,
} from "@tanstack/react-table";
import {
    formatClientName,
    formatCurrency,
    formatDate,
    fuzzyFilter,
} from "../utils";
import Header from "./Header";
import Pagination from "./Pagination";
import Row from "./Row";
import { Bill } from "../types";
import { PulseLoader } from "react-spinners";
import { useData } from "../hooks/data/useData";
import { useState } from "react";
import sortIcon from "../assets/sort.svg";
import editIcon from "../assets/editarIcon.svg";
import delIcon from "../assets/delIcon.svg";

const columnHelper = createColumnHelper<Bill>();

const columns = [
    columnHelper.accessor("nome", {
        header: (info) => (
            <div className="flex items-center">
                <button onClick={info.column.getToggleSortingHandler()}>
                    <img src={sortIcon} alt="sort client name" />
                </button>
                <span>Cliente</span>
            </div>
        ),
        cell: (info) => formatClientName(info.getValue()),
    }),
    columnHelper.accessor("id_cob", {
        header: (info) => (
            <div className="flex items-center">
                <button onClick={info.column.getToggleSortingHandler()}>
                    <img src={sortIcon} alt="sort bill ID" />
                </button>
                <span>ID da cob.</span>
            </div>
        ),
        cell: (info) => info.getValue().slice(0, 8),
    }),
    columnHelper.accessor("valor", {
        header: () => "Valor",
        cell: (info) => formatCurrency(info.getValue()),
    }),
    columnHelper.accessor("data_venc", {
        header: () => "Data de venc.",
        cell: (info) => formatDate(new Date(info.getValue())),
    }),
    columnHelper.accessor("status", {
        header: () => "Status",
        cell: (info) => {
            const status = info.getValue();
            const statusClasses = {
                Vencida: "bg-[#FFEFEF] text-[#971D1D]",
                Pendente: "bg-[#FCF6DC] text-[#C5A605]",
                Paga: "bg-[#EEF6F6] text-[#1FA7AF]",
            };
            return (
                <div
                    className={`${
                        statusClasses[status] || ""
                    } flex justify-center items-center rounded-[8px]`}
                >
                    <span>{status}</span>
                </div>
            );
        },
    }),
    columnHelper.accessor("descricao", {
        header: () => "Descrição",
        cell: (info) => info.getValue(),
        size: 400,
    }),
    columnHelper.accessor("actions", {
        header: () => "Ações",
        cell: (info) => (
            <div className="flex space-x-2 justify-center items-center">
                <button className="text-blue-600">
                    <img src={editIcon} alt="edit bill" />
                    Editar
                </button>
                <button className="text-red-600">
                    <img src={delIcon} alt="delete bill" />
                    Deletar
                </button>
            </div>
        ),
    }),
];

const Tables = () => {
    const [filterInput, setFilterInput] = useState("");
    const { data } = useData<Bill[]>("allCharges");

    const table = useReactTable({
        data: data as Bill[],
        columns,
        getCoreRowModel: getCoreRowModel(),
        getSortedRowModel: getSortedRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        filterFns: {
            fuzzy: fuzzyFilter,
        },
    });

    const handleFilterChange = (e) => {
        const value = e.target.value;
        setFilterInput(value);
        table.setGlobalFilter(value);
    };

    if (!data) {
        return (
            <div className="flex justify-center items-center">
                <PulseLoader />
            </div>
        );
    }

    return (
        <div className="flex flex-col justify-center items-center">
            <div className="flex justify-end items-center w-5/6">
                <input
                    type="text"
                    value={filterInput}
                    onChange={handleFilterChange}
                    placeholder="Search..."
                    className="mb-4 p-2 border rounded"
                />
            </div>
            <div className="bg-white rounded-[30px] mb-[30px] w-5/6">
                <table className="w-full border-collapse">
                    <thead>
                        <Header table={table} />
                    </thead>
                    <tbody>
                        <Row table={table} />
                    </tbody>
                </table>
            </div>
            <Pagination table={table} />
        </div>
    );
};

export default Tables;
Leave a Comment