From aed26082871dc75513b5521b0fce36444d492e57 Mon Sep 17 00:00:00 2001 From: Kylie Lallak <140771878+Kylie-Lallak@users.noreply.github.com> Date: Tue, 6 May 2025 18:12:02 -0700 Subject: [PATCH 1/5] inital product detail page --- .../ProductPage/ProductPage.module.scss | 144 ++++++++++++-- .../_components/ProductPage/ProductPage.tsx | 69 ++++++- app/(pages)/products/_data/products.ts | 26 ++- package-lock.json | 180 +++++++++--------- package.json | 2 +- 5 files changed, 297 insertions(+), 124 deletions(-) diff --git a/app/(pages)/product/_components/ProductPage/ProductPage.module.scss b/app/(pages)/product/_components/ProductPage/ProductPage.module.scss index b311d3e..24ef481 100644 --- a/app/(pages)/product/_components/ProductPage/ProductPage.module.scss +++ b/app/(pages)/product/_components/ProductPage/ProductPage.module.scss @@ -1,31 +1,139 @@ $mid-gap: var(--spacer); .container { - display: flex; - flex-direction: row; - padding: var(--medium-spacer); - gap: $mid-gap; - background-color: var(--light-foreground); - justify-content: center; + display: flex; + flex-direction: row; + padding: var(--medium-spacer); + gap: $mid-gap; + background-color: var(--light-foreground); + justify-content: center; } .main_img_container { - width: calc(calc(100% - $mid-gap) / 2); - aspect-ratio: calc(5/4); - position: relative; + width: calc(50% - $mid-gap); + aspect-ratio: 5 / 4; + position: relative; + + .main_image { + object-fit: cover; + } +} - .main_image { - object-fit: cover; - } +.name { + font-size: 32px; + color: #3a2779; } .prod_information { - width: calc(calc(100% - $mid-gap) / 2); - display: flex; - flex-direction: column; - gap: var(--spacer); + width: calc(50% - $mid-gap); + display: flex; + flex-direction: column; + gap: var(--spacer); +} + +.description { + color: #7a7a7a; + font-size: 16px; + line-height: 1.5; + max-width: 80%; + margin-bottom: 10px; +} + +.price { + color: #3a2779; + font-size: 32px; +} + +.line { + height: 0.8px; + background-color: #e0e0e0; + width: 80%; + margin: 1em 0; } .add_to_cart_button { - max-width: 400px; -} \ No newline at end of file + max-width: 150px; + padding: 15px; + font-size: 1rem; + background: #3a2779; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + transition: transform 0.2s ease, background 0.2s ease; + + &:active { + transform: scale(0.95); + } + + &:hover { + background-color: #7a39d0; + } + + &.added { + background: #3a2779; + animation: pop 0.3s ease; + } +} + +@keyframes pop { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } +} + +.option_buttons { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} + +.option_button { + padding: 0.5rem 1rem; + border: 1.5px solid rgb(188, 188, 188); + color: grey; + background: white; + cursor: pointer; + border-radius: 4px; + transition: all 0.2s ease; + + &:hover { + background: #f7f7f7; + } + + &.selected { + + color: #3a2779; + border: 2px solid #3a2779; + font-weight: 500; + + + } +} + +@media (max-width: 750px) { + .container { + flex-direction: column; + justify-content: center; + align-items: center; + } + + .main_img_container { + width: 80%; + } + + .prod_information { + width: 80%; + } + + + + + +} diff --git a/app/(pages)/product/_components/ProductPage/ProductPage.tsx b/app/(pages)/product/_components/ProductPage/ProductPage.tsx index 254a259..c3dafb8 100644 --- a/app/(pages)/product/_components/ProductPage/ProductPage.tsx +++ b/app/(pages)/product/_components/ProductPage/ProductPage.tsx @@ -1,8 +1,8 @@ 'use client'; +import { useState } from 'react'; import styles from './ProductPage.module.scss'; import Image from 'next/image'; - import { useShoppingCart } from '@hooks/useShoppingCart'; interface Product { @@ -11,23 +11,78 @@ interface Product { alt: string; name: string; price: number; + description: string; + options?: string[]; } -export default function ProductPage({ id, src, alt, name, price }: Product) { +export default function ProductPage({ + id, + src, + alt, + name, + price, + description, + options = [], +}: Product) { const { add_to_cart } = useShoppingCart(); + const [added, setAdded] = useState(false); + const [selectedOption, setSelectedOption] = useState(''); + + const handleAdd = () => { + if (options.length && !selectedOption) { + alert('Please select a size!'); + return; + } + + add_to_cart(id, selectedOption); + setAdded(true); + setTimeout(() => setAdded(false), 1500); + }; + return (
${price}
+{description}
+ +${price}
+ + {options.length > 0 && ( +{description}
-${price}
++ {discountedPrice ? ( + <> + ${price.toFixed(2)} + ${discountedPrice} + > + ) : ( + <>${price.toFixed(2)}> + )} +
- {options.length > 0 && ( -{category}