From ce44dba74fd55bba3e7430d833e0a86c3a9e898b Mon Sep 17 00:00:00 2001 From: Amit Roy Date: Wed, 7 Aug 2024 16:38:56 +0530 Subject: [PATCH 1/4] Styles: header added --- src/app/(auth)/log-in/loginPage.module.scss | 2 +- src/app/(dashboard)/home/page.tsx | 14 +++-- src/app/globals.scss | 2 +- src/components/titleHeader/titleHeader.tsx | 63 +++++++++++++++++++ .../wrapper/DashboardWrapper.module.scss | 1 + src/theme.ts | 11 ++++ src/utilities/svgConstant.tsx | 2 +- 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 src/components/titleHeader/titleHeader.tsx diff --git a/src/app/(auth)/log-in/loginPage.module.scss b/src/app/(auth)/log-in/loginPage.module.scss index e4722a7..2890075 100644 --- a/src/app/(auth)/log-in/loginPage.module.scss +++ b/src/app/(auth)/log-in/loginPage.module.scss @@ -1,6 +1,6 @@ .loginPage { width: 100%; - height: 100%; + height: 100vh; .images { width: 100%; max-width: 500px; diff --git a/src/app/(dashboard)/home/page.tsx b/src/app/(dashboard)/home/page.tsx index eabb77b..a3ac932 100644 --- a/src/app/(dashboard)/home/page.tsx +++ b/src/app/(dashboard)/home/page.tsx @@ -3,14 +3,20 @@ import { Box, Card, Typography } from "@mui/material"; import React from "react"; import CardHeader from "@mui/material/CardHeader"; import CardContent from "@mui/material/CardContent"; +import TitleHeader from "@/components/titleHeader/titleHeader"; const HomePage = () => { return ( - - - Projects - + + + diff --git a/src/app/globals.scss b/src/app/globals.scss index 9f16bd8..f6d7345 100644 --- a/src/app/globals.scss +++ b/src/app/globals.scss @@ -73,7 +73,7 @@ /* Body */ html, body { - height: 100%; + min-height: 100vh; padding: 0; margin: 0; } diff --git a/src/components/titleHeader/titleHeader.tsx b/src/components/titleHeader/titleHeader.tsx new file mode 100644 index 0000000..1789ec8 --- /dev/null +++ b/src/components/titleHeader/titleHeader.tsx @@ -0,0 +1,63 @@ +import { Box, Card, CardContent, Typography } from "@mui/material"; +import React from "react"; +import Breadcrumbs from "@mui/material/Breadcrumbs"; +import Link from "@mui/material/Link"; +import HomeIcon from "@mui/icons-material/Home"; + +// function handleClick(event: React.MouseEvent) { +// event.preventDefault(); +// console.info('You clicked a breadcrumb.'); +// } + +const TitleHeader = () => { + return ( + + + + + Projects + + + + + Page + + + Project Table + + + + + + ); +}; + +export default TitleHeader; diff --git a/src/components/wrapper/DashboardWrapper.module.scss b/src/components/wrapper/DashboardWrapper.module.scss index 6af4ba5..7b46415 100644 --- a/src/components/wrapper/DashboardWrapper.module.scss +++ b/src/components/wrapper/DashboardWrapper.module.scss @@ -7,4 +7,5 @@ } .dashboard_main { background: var(--dashboard-bg); + min-height: 100vh; } diff --git a/src/theme.ts b/src/theme.ts index db32bd5..4a2659d 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -22,6 +22,17 @@ const theme = createTheme({ light: getCssVariableValue("--primary_light").trim() || "#dae7f9", // Fallback to default color }, }, + components: { + MuiCardContent: { + styleOverrides: { + root: { + "&:last-child": { + paddingBottom: "16px", // Override the padding for the last child + }, + }, + }, + }, + }, }); export default theme; diff --git a/src/utilities/svgConstant.tsx b/src/utilities/svgConstant.tsx index bebba19..469d070 100644 --- a/src/utilities/svgConstant.tsx +++ b/src/utilities/svgConstant.tsx @@ -1,6 +1,6 @@ // Import necessary functions and types +import { createSvgIcon } from "@mui/material"; import React from "react"; -import { createSvgIcon } from "@mui/material/utils"; // Define the SVG component using createSvgIcon export const BUILDING = createSvgIcon( From e2bad1ebcc13fad289415e70f0f330b091ffbe42 Mon Sep 17 00:00:00 2001 From: Sourya Banerjee Date: Wed, 7 Aug 2024 16:39:57 +0530 Subject: [PATCH 2/4] Server side data fetch --- README.md | 64 +++++++++++++++++++------- src/app/(dashboard)/home/page.tsx | 6 ++- src/components/table/TanStackTable.tsx | 15 +++--- src/services/home.services.ts | 17 +++++++ 4 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 src/services/home.services.ts diff --git a/README.md b/README.md index c403366..8762566 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,33 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +# Project Name + +TEST DEMO + +This is a Demo project Developed in NextJS with Tanstack React Table. + +## Features + +1. **Login**: User authentication functionality. +2. **Signup**: User registration functionality. +3. **Table Data**: Data loaded from [Dummy JSON](https://dummyjson.com/products) and displayed on the home page. +4. **Review Modal**: A modal that opens from the "View Reviews" button in each table row to display product reviews. ## Getting Started -First, run the development server: +### Installation + +First, install the dependencies: + +```bash +npm install +# or +yarn install +# or +pnpm install +# or +bun install +``` + +### Running the Development Server: ```bash npm run dev @@ -14,23 +39,30 @@ pnpm dev bun dev ``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +Open http://localhost:3000 with your browser to see the result. -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. +You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file. -## Learn More +Project Structure +Login: Navigate to the login page to authenticate users. +Signup: Navigate to the signup page to register new users. +Table Data: The home page fetches and displays product data from Dummy JSON. +Review Modal: Click the "View Reviews" button in any table row to open a modal displaying the product reviews. +API +This project uses the Dummy JSON API to fetch product data. The data is displayed in a table on the home page. -To learn more about Next.js, take a look at the following resources: +Components +Login Component: Handles user login functionality. +Signup Component: Handles user registration functionality. +Table Component: Displays product data in a table format. +Review Modal Component: Displays product reviews in a modal when the "View Reviews" button is clicked. +Contributing +If you would like to contribute to this project, please fork the repository and submit a pull request. -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +License +This project is licensed under the MIT License. -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. +``` -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +This README includes more details about the project structure, components, and API usage. +``` diff --git a/src/app/(dashboard)/home/page.tsx b/src/app/(dashboard)/home/page.tsx index eabb77b..a293cb1 100644 --- a/src/app/(dashboard)/home/page.tsx +++ b/src/app/(dashboard)/home/page.tsx @@ -3,8 +3,10 @@ import { Box, Card, Typography } from "@mui/material"; import React from "react"; import CardHeader from "@mui/material/CardHeader"; import CardContent from "@mui/material/CardContent"; +import homeServices from "@/services/home.services"; -const HomePage = () => { +const HomePage = async () => { + const data = await homeServices.getProducts(); return ( @@ -12,7 +14,7 @@ const HomePage = () => { Projects - + diff --git a/src/components/table/TanStackTable.tsx b/src/components/table/TanStackTable.tsx index 7e5f24e..6955e09 100644 --- a/src/components/table/TanStackTable.tsx +++ b/src/components/table/TanStackTable.tsx @@ -6,16 +6,17 @@ import { flexRender, } from "@tanstack/react-table"; import styles from "./TanStackTable.module.scss"; -import axios from "axios"; import { useEffect, useState } from "react"; import ReviewModal from "../reviewModal/ReviewModal"; -const TanStackTable = () => { +const TanStackTable = ({ data }: any) => { const [tableData, setTableData] = useState([]); const [open, setOpen] = useState(false); const [reviewModalData, setReviewModalData] = useState([]); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); + + /** Set Title and api data object key for the Table title and data */ const columns: any = [ { header: "ID", @@ -71,6 +72,7 @@ const TanStackTable = () => { }, ]; + /** Send Review array to Review Modal before openning */ const handleButtonClick = (rowData: any) => { setReviewModalData(rowData?.reviews); handleOpen(); @@ -84,12 +86,9 @@ const TanStackTable = () => { }); useEffect(() => { - (async () => { - const tableData = await axios.get("https://dummyjson.com/products"); - console.log("tableData", tableData); - setTableData(tableData?.data?.products); - })(); - }, []); + setTableData(data?.products); + console.log("Server data", data); + }, [data]); return ( <> diff --git a/src/services/home.services.ts b/src/services/home.services.ts new file mode 100644 index 0000000..70be01f --- /dev/null +++ b/src/services/home.services.ts @@ -0,0 +1,17 @@ +import axios, { isAxiosError } from "axios"; + +const homeServices = { + getProducts: async () => { + try { + const res = await axios.get("https://dummyjson.com/products"); + return res.data; + } catch (error: any) { + if (isAxiosError(error)) { + throw new Error(error.response?.data.message); + } + throw new Error("Something went wrong. Please try again."); + } + }, +}; + +export default homeServices; From 61479620a3ffe971a102ed2ed038c0ed3d3c02e6 Mon Sep 17 00:00:00 2001 From: Sourya Banerjee Date: Wed, 7 Aug 2024 16:55:14 +0530 Subject: [PATCH 3/4] sorting added for id --- src/components/table/TanStackTable.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/components/table/TanStackTable.tsx b/src/components/table/TanStackTable.tsx index 6955e09..1c8cf0a 100644 --- a/src/components/table/TanStackTable.tsx +++ b/src/components/table/TanStackTable.tsx @@ -13,13 +13,30 @@ const TanStackTable = ({ data }: any) => { const [tableData, setTableData] = useState([]); const [open, setOpen] = useState(false); const [reviewModalData, setReviewModalData] = useState([]); + const [sortOrder, setSortOrder] = useState<"asc" | "desc" | null>(null); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); + const handleSort = (key: string) => { + let sortedData; + if (sortOrder === "asc") { + sortedData = [...tableData].sort((a, b) => (a[key] > b[key] ? -1 : 1)); + setSortOrder("desc"); + } else { + sortedData = [...tableData].sort((a, b) => (a[key] > b[key] ? 1 : -1)); + setSortOrder("asc"); + } + setTableData(sortedData); + }; + /** Set Title and api data object key for the Table title and data */ const columns: any = [ { - header: "ID", + header: ( +
handleSort("id")}> + ID {sortOrder === "asc" ? "↑" : sortOrder === "desc" ? "↓" : ""} +
+ ), accessorKey: "id", }, { From 56064a32a201bf6bcf09f42483be70b8783304d5 Mon Sep 17 00:00:00 2001 From: Amit Roy Date: Wed, 7 Aug 2024 16:55:45 +0530 Subject: [PATCH 4/4] style: update --- .../table/TanStackTable.module.scss | 27 +++++++++++++++++++ src/components/table/TanStackTable.tsx | 7 ++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/components/table/TanStackTable.module.scss b/src/components/table/TanStackTable.module.scss index e69de29..b677d47 100644 --- a/src/components/table/TanStackTable.module.scss +++ b/src/components/table/TanStackTable.module.scss @@ -0,0 +1,27 @@ +@use "@/theme/sass/helper" as *; +.responsive_table { + width: 100%; + .table { + width: 100%; + thead { + tr { + th { + text-align: start; + padding-inline: rem(10); + padding-block: rem(4); + min-height: rem(40); + } + } + } + tbody { + tr { + td { + text-align: start; + padding-inline: rem(10); + padding-block: rem(4); + min-height: rem(40); + } + } + } + } +} diff --git a/src/components/table/TanStackTable.tsx b/src/components/table/TanStackTable.tsx index 6955e09..2b6e297 100644 --- a/src/components/table/TanStackTable.tsx +++ b/src/components/table/TanStackTable.tsx @@ -5,6 +5,7 @@ import { getCoreRowModel, flexRender, } from "@tanstack/react-table"; +import global from "../../../src/theme/global/global.module.scss"; import styles from "./TanStackTable.module.scss"; import { useEffect, useState } from "react"; import ReviewModal from "../reviewModal/ReviewModal"; @@ -92,13 +93,13 @@ const TanStackTable = ({ data }: any) => { return ( <> -
- +
+
{table.getHeaderGroups().map((headerGroup: any) => ( {headerGroup.headers.map((header: any) => ( -
+ {flexRender( header.column.columnDef.header, header.getContext()