From d23949901a2add8f3310819114626d37d04a7bf9 Mon Sep 17 00:00:00 2001 From: Tin Pham <72054441+tinpham5614@users.noreply.github.com> Date: Thu, 22 Feb 2024 19:41:08 -0800 Subject: [PATCH] belinda-nextjs-03-231-modify-add-components-product-page (#232) * refactor and add buttons * add store jwt and update buttons --- app/auth/sign-in/page.tsx | 1 + .../[categoryId]/page.module.css | 54 ------- app/category-page/[categoryId]/page.tsx | 81 +++++++---- components/ProductCard.tsx | 135 ++++++++++++++---- 4 files changed, 162 insertions(+), 109 deletions(-) delete mode 100644 app/category-page/[categoryId]/page.module.css diff --git a/app/auth/sign-in/page.tsx b/app/auth/sign-in/page.tsx index 2e8cbd22..5fbd4e08 100644 --- a/app/auth/sign-in/page.tsx +++ b/app/auth/sign-in/page.tsx @@ -41,6 +41,7 @@ const Signin = () => { throw new Error(await res.text()); } const { token } = await res.json(); + localStorage.setItem("token", token); // store token in local storage const userRole = JSON.parse(atob(token.split(".")[1])).role; // decode token to get user role // Redirect to user page if (userRole === "admin") { diff --git a/app/category-page/[categoryId]/page.module.css b/app/category-page/[categoryId]/page.module.css deleted file mode 100644 index af082809..00000000 --- a/app/category-page/[categoryId]/page.module.css +++ /dev/null @@ -1,54 +0,0 @@ -.container { - background-color: #12202d; - display: flex; - justify-content: center; - align-items: top; - height: 100vh; -} - -.displaySection { - background-color: #293745; - justify-content: top; - padding: 2rem; - border-radius: 15px; - width: 800px; - flex-grow: 1; /* Take up remaining space */ -} - -.displaySection h1 { - display: flex; - justify-content: center; - color: #f5f5f5; - margin-bottom: 1rem; -} - -.productContainer { - display: flex; - flex-wrap: wrap; - gap: 1.5rem; - justify-content: flex-start; - align-items: center; - padding-inline-start: 7rem; -} - -.product { - margin: 1rem; - padding: 1rem; - background-color: #1e2b37; - border-radius: 15px; - width: 300px; - height: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.product p.description { - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 3; - -webkit-box-orient: vertical; -} - -/* Add additional styling as needed */ diff --git a/app/category-page/[categoryId]/page.tsx b/app/category-page/[categoryId]/page.tsx index 2913bb39..8139b9da 100644 --- a/app/category-page/[categoryId]/page.tsx +++ b/app/category-page/[categoryId]/page.tsx @@ -1,31 +1,35 @@ "use client"; -import styles from './page.module.css'; -import React, { useState, useEffect, Dispatch, SetStateAction, createContext, Context } from "react"; -import Link from 'next/link'; +import React, { useState, useEffect, Dispatch, SetStateAction } from "react"; import ProductCard from "@/components/ProductCard"; -import google_play from "../../google_play.png"; -; - -const placeholderImg = google_play +import logo from "../../logo.png"; +import { Container, Grid, Typography } from "@mui/material"; +const placeholderImg = logo; interface Product { _id: string; productImage: typeof placeholderImg; productType: string[]; + productGender: string; + productSizeShoe: string; + productSize: string; + productSizePantsWaist: string; + productSizePantsInseam: string; productDescription: string; - // more product fields can be added } -async function fetchData(categoryId: string, setProducts: Dispatch>) { - const apiUrl = 'http://localhost:3000/api/products/findByType/'; +async function fetchData( + categoryId: string, + setProducts: Dispatch> +) { + const apiUrl = "http://localhost:3000/api/products/findByType/"; const queryParam = encodeURIComponent(categoryId); const fetchUrl = `${apiUrl}${queryParam}`; try { const res = await fetch(fetchUrl, { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, }); if (!res.ok) { @@ -36,7 +40,7 @@ async function fetchData(categoryId: string, setProducts: Dispatch { useEffect(() => { fetchData(categoryId, setProducts); // Pass categoryId to fetchData - }, [categoryId]); + }, [categoryId]); return ( -
-

Found {products.length} products in {categoryId}

-
+ + + Found {products.length} products in {categoryId} + + {products.map((product, index) => ( - + + + ))} -
-
+ + ); }; -export default function ProductList({ params }: { params: { categoryId: string } }) { +export default function ProductList({ + params, +}: { + params: { categoryId: string }; +}) { const decodedCategoryId = decodeURIComponent(params.categoryId); return ( -
+ -
+ ); -} \ No newline at end of file +} diff --git a/components/ProductCard.tsx b/components/ProductCard.tsx index 811c6440..3edbbb70 100644 --- a/components/ProductCard.tsx +++ b/components/ProductCard.tsx @@ -1,30 +1,115 @@ -import React from "react"; -import Image from "next/image"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import ButtonBase from "@mui/material/ButtonBase"; import { StaticImageData } from "next/image"; -import Link from 'next/link'; -import styles from '../app/category-page/[categoryId]/page.module.css'; // Import style from category page +import { Stack, Button, Link } from "@mui/material"; +import Image from "next/image"; +import DeleteIcon from "@mui/icons-material/Delete"; +import ArchiveIcon from "@mui/icons-material/Archive"; type ProductCardProps = { - image: StaticImageData; - categories: string[]; - description: string; - href: string; -}; - -const ProductCard: React.FC = ({ image, categories, description, href }) => { - return ( - -
- {`Image -
-

{categories.join(', ')}

-

- {description} -

-
-
- - ); + image: StaticImageData; + categories: string[]; + gender: string; + sizeShoe: string; + sizePantsWaist: string; + sizePantsInseam: string; + size: string; + description: string; + href: string; }; +export default function ProductCard({ + image, + categories, + gender, + sizeShoe, + size, + sizePantsWaist, + sizePantsInseam, + description, + href, +}: ProductCardProps) { + const [userRole, setUserRole] = React.useState(""); -export default ProductCard; \ No newline at end of file + // Get user role from token + React.useEffect(() => { + const token = localStorage.getItem("token"); + if (token) { + const role = JSON.parse(atob(token.split(".")[1])).role; + setUserRole(role); + } + }, []); + return ( + + theme.palette.mode === "dark" ? "#1A2027" : "#fff", + }} + > + + + + + product image + + + + + + + + {categories} + + + {gender} + + + {sizeShoe} + + + {size} + + + {sizePantsWaist} + + + {sizePantsInseam} + + + {description} + + + + + + + + {userRole === "admin" || + (userRole === "creator" && ( + + {/* TODO: Add delete function to this button */} + + {/* TODO: Add archive function to this button */} + + + ))} + + + ); +}