Skip to content

Instantly share code, notes, and snippets.

@Aakash1103Jha
Created July 21, 2023 14:41
Show Gist options
  • Save Aakash1103Jha/9d486f095de4af403bf7220db053d1e7 to your computer and use it in GitHub Desktop.
Save Aakash1103Jha/9d486f095de4af403bf7220db053d1e7 to your computer and use it in GitHub Desktop.
GenericTable
/* /src/components/Generics/GenericTable/GenericTable.tsx */
.genericTable {
width: 100%;
}
.genericTable td,
.genericTable th {
padding: 0.5rem;
outline: 1px solid;
}
.genericTable td[id="description"] {
max-width: 30rem;
}
.paginationContainer {
display: flex;
align-items: center;
gap: 2rem;
}
.paginationRowsPerPage {
gap: 0.5rem;
display: flex;
align-items: center;
}
.paginationButtonContainer {
gap: 1rem;
display: flex;
align-items: center;
}
.paginationButton {
padding: 0.5rem;
}
<!-- /src/components/Generics/GenericTable/GenericTable.tsx -->
import { ChangeEventHandler, ComponentPropsWithRef, useEffect, useState } from "react";
import styles from "./genericTable.module.css";
export interface GenericTableProps<T = unknown, K extends keyof T = keyof T> extends ComponentPropsWithRef<"table"> {
data: T[];
columns: { id: keyof T; header: string }[];
pagination?: boolean;
rows?: number;
defaultPage?: number;
}
function GenericTable<T = unknown, K extends keyof T = keyof T>({
data,
columns,
pagination = false,
style,
className,
rows = 5,
defaultPage = 1,
...rest
}: GenericTableProps<T, K>) {
const [page, setPage] = useState(defaultPage);
const [rowsPerPage, setRowsPerPage] = useState(rows);
const startIndex = (page - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
const tableData = pagination ? data.slice(startIndex, endIndex) : data;
const NextButton = () => (
<button
className={`${styles.paginationButton}`}
disabled={endIndex >= data.length}
onClick={() => setPage((current) => current + 1)}>
Next
</button>
);
const BackButton = () => (
<button
className={`${styles.paginationButton}`}
disabled={page === 1}
onClick={() => setPage((current) => current - 1)}>
Back
</button>
);
const onRowCountChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
return setRowsPerPage(Number(e.target.value));
};
useEffect(() => {
setPage(defaultPage);
}, [defaultPage]);
useEffect(() => {
setRowsPerPage(rowsPerPage);
}, [rowsPerPage]);
return (
<>
<table
className={`${styles.genericTable} ${className}`}
style={style}
{...rest}>
<thead>
<tr>
{columns.map((col) => (
<th key={col.id as string}>{col.header.toUpperCase()}</th>
))}
</tr>
</thead>
<tbody>
{tableData.map((item, index) => (
<tr key={index}>
{columns.map((col) => (
<td
key={col.id as string}
id={col.id as string}>
<>{item[col.id]}</>
</td>
))}
</tr>
))}
</tbody>
</table>
<div className={`${styles.paginationContainer}`}>
<div className={`${styles.paginationRowsPerPage}`}>
<label>Rows per page</label>
<select
onChange={onRowCountChange}
value={rowsPerPage}>
{[5, 10, 15].map((num) => (
<option
value={num}
key={num}>
{num}
</option>
))}
</select>
</div>
<div className={`${styles.paginationButtonContainer}`}>
<BackButton />
<p>{page}</p>
<NextButton />
</div>
</div>
</>
);
}
export default GenericTable;
<!-- /pages/index.tsx -->
import dynamic from "next/dynamic";
<!-- other imports -->
const GenericTable = dynamic<
GenericTableProps<
{
id: number;
title: string;
description: string;
price: number;
discountPercentage: number;
rating: number;
stock: number;
brand: string;
category: string;
},
keyof {}
>
>(() => import("@/components").then((mod) => mod.GenericTable), { ssr: false });
<!-- other imports -->
export default function App() {
return <GenericTable
pagination
rows={10}
data={DATA.products}
columns={[
{ id: "id", header: "id" },
{ id: "title", header: "title" },
{ id: "description", header: "description" },
{ id: "price", header: "price" },
{ id: "discountPercentage", header: "discount (%)" },
{ id: "rating", header: "rating" },
{ id: "stock", header: "stock" },
{ id: "brand", header: "brand" },
{ id: "category", header: "category" },
// { id: "thumbnail", header: "thumbnail" },
// { id: "images", header: "images" },
]}
/>
}
{
"products": [
{
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/1/1.jpg",
"https://i.dummyjson.com/data/products/1/2.jpg",
"https://i.dummyjson.com/data/products/1/3.jpg",
"https://i.dummyjson.com/data/products/1/4.jpg",
"https://i.dummyjson.com/data/products/1/thumbnail.jpg"
]
},
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 17.94,
"rating": 4.44,
"stock": 34,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/2/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/2/1.jpg",
"https://i.dummyjson.com/data/products/2/2.jpg",
"https://i.dummyjson.com/data/products/2/3.jpg",
"https://i.dummyjson.com/data/products/2/thumbnail.jpg"
]
},
{
"id": 3,
"title": "Samsung Universe 9",
"description": "Samsung's new variant which goes beyond Galaxy to the Universe",
"price": 1249,
"discountPercentage": 15.46,
"rating": 4.09,
"stock": 36,
"brand": "Samsung",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/3/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/3/1.jpg"
]
},
{
"id": 4,
"title": "OPPOF19",
"description": "OPPO F19 is officially announced on April 2021.",
"price": 280,
"discountPercentage": 17.91,
"rating": 4.3,
"stock": 123,
"brand": "OPPO",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/4/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/4/1.jpg",
"https://i.dummyjson.com/data/products/4/2.jpg",
"https://i.dummyjson.com/data/products/4/3.jpg",
"https://i.dummyjson.com/data/products/4/4.jpg",
"https://i.dummyjson.com/data/products/4/thumbnail.jpg"
]
},
{
"id": 5,
"title": "Huawei P30",
"description": "Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.",
"price": 499,
"discountPercentage": 10.58,
"rating": 4.09,
"stock": 32,
"brand": "Huawei",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/5/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/5/1.jpg",
"https://i.dummyjson.com/data/products/5/2.jpg",
"https://i.dummyjson.com/data/products/5/3.jpg"
]
},
{
"id": 6,
"title": "MacBook Pro",
"description": "MacBook Pro 2021 with mini-LED display may launch between September, November",
"price": 1749,
"discountPercentage": 11.02,
"rating": 4.57,
"stock": 83,
"brand": "Apple",
"category": "laptops",
"thumbnail": "https://i.dummyjson.com/data/products/6/thumbnail.png",
"images": [
"https://i.dummyjson.com/data/products/6/1.png",
"https://i.dummyjson.com/data/products/6/2.jpg",
"https://i.dummyjson.com/data/products/6/3.png",
"https://i.dummyjson.com/data/products/6/4.jpg"
]
},
{
"id": 7,
"title": "Samsung Galaxy Book",
"description": "Samsung Galaxy Book S (2020) Laptop With Intel Lakefield Chip, 8GB of RAM Launched",
"price": 1499,
"discountPercentage": 4.15,
"rating": 4.25,
"stock": 50,
"brand": "Samsung",
"category": "laptops",
"thumbnail": "https://i.dummyjson.com/data/products/7/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/7/1.jpg",
"https://i.dummyjson.com/data/products/7/2.jpg",
"https://i.dummyjson.com/data/products/7/3.jpg",
"https://i.dummyjson.com/data/products/7/thumbnail.jpg"
]
},
{
"id": 8,
"title": "Microsoft Surface Laptop 4",
"description": "Style and speed. Stand out on HD video calls backed by Studio Mics. Capture ideas on the vibrant touchscreen.",
"price": 1499,
"discountPercentage": 10.23,
"rating": 4.43,
"stock": 68,
"brand": "Microsoft Surface",
"category": "laptops",
"thumbnail": "https://i.dummyjson.com/data/products/8/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/8/1.jpg",
"https://i.dummyjson.com/data/products/8/2.jpg",
"https://i.dummyjson.com/data/products/8/3.jpg",
"https://i.dummyjson.com/data/products/8/4.jpg",
"https://i.dummyjson.com/data/products/8/thumbnail.jpg"
]
},
{
"id": 9,
"title": "Infinix INBOOK",
"description": "Infinix Inbook X1 Ci3 10th 8GB 256GB 14 Win10 Grey – 1 Year Warranty",
"price": 1099,
"discountPercentage": 11.83,
"rating": 4.54,
"stock": 96,
"brand": "Infinix",
"category": "laptops",
"thumbnail": "https://i.dummyjson.com/data/products/9/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/9/1.jpg",
"https://i.dummyjson.com/data/products/9/2.png",
"https://i.dummyjson.com/data/products/9/3.png",
"https://i.dummyjson.com/data/products/9/4.jpg",
"https://i.dummyjson.com/data/products/9/thumbnail.jpg"
]
},
{
"id": 10,
"title": "HP Pavilion 15-DK1056WM",
"description": "HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10",
"price": 1099,
"discountPercentage": 6.18,
"rating": 4.43,
"stock": 89,
"brand": "HP Pavilion",
"category": "laptops",
"thumbnail": "https://i.dummyjson.com/data/products/10/thumbnail.jpeg",
"images": [
"https://i.dummyjson.com/data/products/10/1.jpg",
"https://i.dummyjson.com/data/products/10/2.jpg",
"https://i.dummyjson.com/data/products/10/3.jpg",
"https://i.dummyjson.com/data/products/10/thumbnail.jpeg"
]
},
{
"id": 11,
"title": "perfume Oil",
"description": "Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil",
"price": 13,
"discountPercentage": 8.4,
"rating": 4.26,
"stock": 65,
"brand": "Impression of Acqua Di Gio",
"category": "fragrances",
"thumbnail": "https://i.dummyjson.com/data/products/11/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/11/1.jpg",
"https://i.dummyjson.com/data/products/11/2.jpg",
"https://i.dummyjson.com/data/products/11/3.jpg",
"https://i.dummyjson.com/data/products/11/thumbnail.jpg"
]
},
{
"id": 12,
"title": "Brown Perfume",
"description": "Royal_Mirage Sport Brown Perfume for Men & Women - 120ml",
"price": 40,
"discountPercentage": 15.66,
"rating": 4,
"stock": 52,
"brand": "Royal_Mirage",
"category": "fragrances",
"thumbnail": "https://i.dummyjson.com/data/products/12/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/12/1.jpg",
"https://i.dummyjson.com/data/products/12/2.jpg",
"https://i.dummyjson.com/data/products/12/3.png",
"https://i.dummyjson.com/data/products/12/4.jpg",
"https://i.dummyjson.com/data/products/12/thumbnail.jpg"
]
},
{
"id": 13,
"title": "Fog Scent Xpressio Perfume",
"description": "Product details of Best Fog Scent Xpressio Perfume 100ml For Men cool long lasting perfumes for Men",
"price": 13,
"discountPercentage": 8.14,
"rating": 4.59,
"stock": 61,
"brand": "Fog Scent Xpressio",
"category": "fragrances",
"thumbnail": "https://i.dummyjson.com/data/products/13/thumbnail.webp",
"images": [
"https://i.dummyjson.com/data/products/13/1.jpg",
"https://i.dummyjson.com/data/products/13/2.png",
"https://i.dummyjson.com/data/products/13/3.jpg",
"https://i.dummyjson.com/data/products/13/4.jpg",
"https://i.dummyjson.com/data/products/13/thumbnail.webp"
]
},
{
"id": 14,
"title": "Non-Alcoholic Concentrated Perfume Oil",
"description": "Original Al Munakh® by Mahal Al Musk | Our Impression of Climate | 6ml Non-Alcoholic Concentrated Perfume Oil",
"price": 120,
"discountPercentage": 15.6,
"rating": 4.21,
"stock": 114,
"brand": "Al Munakh",
"category": "fragrances",
"thumbnail": "https://i.dummyjson.com/data/products/14/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/14/1.jpg",
"https://i.dummyjson.com/data/products/14/2.jpg",
"https://i.dummyjson.com/data/products/14/3.jpg",
"https://i.dummyjson.com/data/products/14/thumbnail.jpg"
]
},
{
"id": 15,
"title": "Eau De Perfume Spray",
"description": "Genuine Al-Rehab spray perfume from UAE/Saudi Arabia/Yemen High Quality",
"price": 30,
"discountPercentage": 10.99,
"rating": 4.7,
"stock": 105,
"brand": "Lord - Al-Rehab",
"category": "fragrances",
"thumbnail": "https://i.dummyjson.com/data/products/15/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/15/1.jpg",
"https://i.dummyjson.com/data/products/15/2.jpg",
"https://i.dummyjson.com/data/products/15/3.jpg",
"https://i.dummyjson.com/data/products/15/4.jpg",
"https://i.dummyjson.com/data/products/15/thumbnail.jpg"
]
},
{
"id": 16,
"title": "Hyaluronic Acid Serum",
"description": "L'Oréal Paris introduces Hyaluron Expert Replumping Serum formulated with 1.5% Hyaluronic Acid",
"price": 19,
"discountPercentage": 13.31,
"rating": 4.83,
"stock": 110,
"brand": "L'Oreal Paris",
"category": "skincare",
"thumbnail": "https://i.dummyjson.com/data/products/16/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/16/1.png",
"https://i.dummyjson.com/data/products/16/2.webp",
"https://i.dummyjson.com/data/products/16/3.jpg",
"https://i.dummyjson.com/data/products/16/4.jpg",
"https://i.dummyjson.com/data/products/16/thumbnail.jpg"
]
},
{
"id": 17,
"title": "Tree Oil 30ml",
"description": "Tea tree oil contains a number of compounds, including terpinen-4-ol, that have been shown to kill certain bacteria,",
"price": 12,
"discountPercentage": 4.09,
"rating": 4.52,
"stock": 78,
"brand": "Hemani Tea",
"category": "skincare",
"thumbnail": "https://i.dummyjson.com/data/products/17/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/17/1.jpg",
"https://i.dummyjson.com/data/products/17/2.jpg",
"https://i.dummyjson.com/data/products/17/3.jpg",
"https://i.dummyjson.com/data/products/17/thumbnail.jpg"
]
},
{
"id": 18,
"title": "Oil Free Moisturizer 100ml",
"description": "Dermive Oil Free Moisturizer with SPF 20 is specifically formulated with ceramides, hyaluronic acid & sunscreen.",
"price": 40,
"discountPercentage": 13.1,
"rating": 4.56,
"stock": 88,
"brand": "Dermive",
"category": "skincare",
"thumbnail": "https://i.dummyjson.com/data/products/18/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/18/1.jpg",
"https://i.dummyjson.com/data/products/18/2.jpg",
"https://i.dummyjson.com/data/products/18/3.jpg",
"https://i.dummyjson.com/data/products/18/4.jpg",
"https://i.dummyjson.com/data/products/18/thumbnail.jpg"
]
},
{
"id": 19,
"title": "Skin Beauty Serum.",
"description": "Product name: rorec collagen hyaluronic acid white face serum riceNet weight: 15 m",
"price": 46,
"discountPercentage": 10.68,
"rating": 4.42,
"stock": 54,
"brand": "ROREC White Rice",
"category": "skincare",
"thumbnail": "https://i.dummyjson.com/data/products/19/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/19/1.jpg",
"https://i.dummyjson.com/data/products/19/2.jpg",
"https://i.dummyjson.com/data/products/19/3.png",
"https://i.dummyjson.com/data/products/19/thumbnail.jpg"
]
},
{
"id": 20,
"title": "Freckle Treatment Cream- 15gm",
"description": "Fair & Clear is Pakistan's only pure Freckle cream which helpsfade Freckles, Darkspots and pigments. Mercury level is 0%, so there are no side effects.",
"price": 70,
"discountPercentage": 16.99,
"rating": 4.06,
"stock": 140,
"brand": "Fair & Clear",
"category": "skincare",
"thumbnail": "https://i.dummyjson.com/data/products/20/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/20/1.jpg",
"https://i.dummyjson.com/data/products/20/2.jpg",
"https://i.dummyjson.com/data/products/20/3.jpg",
"https://i.dummyjson.com/data/products/20/4.jpg",
"https://i.dummyjson.com/data/products/20/thumbnail.jpg"
]
}
],
"total": 100,
"skip": 0,
"limit": 20
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment