Skip to content

Fixes #197: Redesign shop single item view #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b963f30
style: redesign PopularItemsSection
alvyynm Jun 21, 2024
778868c
chore: move the returned value immediately after the `=>`
alvyynm Jun 21, 2024
5a41edd
chore: refactor formatPrice function
alvyynm Jun 21, 2024
37c85ac
chore: refactor formatPrice function
alvyynm Jun 21, 2024
d8d7639
style: remove rounded-md from card image
alvyynm Jun 21, 2024
55d1b40
style: change padding in popular items depending on screen width
alvyynm Jun 21, 2024
b6a0fe9
style: make product card responsive
alvyynm Jun 21, 2024
01327a9
style: make product card responsive
alvyynm Jun 21, 2024
bfb83c6
style: make similar products section responsive
alvyynm Jun 21, 2024
3b6456f
style: add x-axis scroll to popular items section
alvyynm Jun 21, 2024
6e0ff61
style: display a max of three cards
alvyynm Jun 21, 2024
9c529b1
style: adjust product name color in card
alvyynm Jun 21, 2024
ac90f48
style: add max-w-fit to pill btns
alvyynm Jun 21, 2024
424f511
chore: remove unused code
alvyynm Jun 21, 2024
88e3be9
feat: display 'item' if stock is === 1
alvyynm Jun 21, 2024
3e614db
style: create hr-scrollbar class with custom styles
alvyynm Jun 21, 2024
8de48b9
style: replace scrollbar with hr-scrollbar class
alvyynm Jun 21, 2024
ec66d8c
chore: formatting
alvyynm Jun 22, 2024
59b4815
style: add p-10 to itemheader above sm screen
alvyynm Jun 24, 2024
855e258
style: replace breadcrumb with GoBackBtn
alvyynm Jun 24, 2024
b937e86
style: replace PiShoppingCartLight with MdOutlineAddShoppingCart
alvyynm Jun 24, 2024
9301abc
style: add a p-10 to Single Item display section
alvyynm Jun 24, 2024
204dac7
style: display font-medium by default and semibold on md screens
alvyynm Jun 24, 2024
ea38db3
style: update structure and style to match design
alvyynm Jun 24, 2024
0d891b4
style: update counter style
alvyynm Jun 25, 2024
77d2e2f
style: update styling for color selection options
alvyynm Jun 25, 2024
65cd36d
style: add min-w-full to all screen sizes
alvyynm Jun 25, 2024
e2c4851
style: add max width to similar products section
alvyynm Jun 25, 2024
b146aff
style: redesign cart drawer
alvyynm Jun 25, 2024
e21006c
style: cart drawer style adjustments
alvyynm Jun 25, 2024
9f65692
style: change currency shorthand from Ksh to KES
alvyynm Jun 25, 2024
b51eaa2
chore: remove unused code
alvyynm Jun 25, 2024
6d2db11
chore: remove unused code
alvyynm Jun 25, 2024
a5bd4f9
style: design adjustments
alvyynm Jun 25, 2024
66de115
style: design adjustments
alvyynm Jun 26, 2024
8fd2a88
style(fix): display different color selection circles
alvyynm Jun 26, 2024
25d0179
style(fix): improve responsiveness of add to cart btn
alvyynm Jun 26, 2024
11c1f6e
style(fix): add gradient background to add to cart btn
alvyynm Jun 26, 2024
79df40d
feat: fix accessibility issues
alvyynm Jun 26, 2024
f7526d9
chore: remove unused cart icon import
alvyynm Jun 26, 2024
0ef5ad1
chore: delete unsued cart icon
alvyynm Jun 26, 2024
0115b45
chore: fix seo issues
alvyynm Jun 26, 2024
4dc1a15
style: format product price appropriately in single item page
alvyynm Jun 27, 2024
d81e395
Merge branch 'Dev' into 197-redesign-shop-single-item-view
sonylomo Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 106 additions & 116 deletions src/APP/components/shop/CartDrawer.jsx

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/APP/components/shop/Counter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ function Counter({ className, setCount, count }) {
<button
type="button"
data-action="decrement"
className="cursor-pointer outline-none w-20 border-y border-l border-l-[#323433] border-y-[#323433] rounded-l-full "
className="cursor-pointer outline-none w-20 border-y border-l border-l-[#EAECF0] border-y-[#EAECF0] rounded-l-md border-r"
onClick={() => setCount(count > 1 ? count - 1 : 1)}
>
<span className=" text-base">−</span>
</button>
<p
className="outline-none focus:outline-none font-medium md:text-basecursor-default flex items-center justify-center border-y border-y-[#323433]"
className="outline-none focus:outline-none font-medium md:text-base cursor-default flex items-center justify-center border-y px-5 border-y-[#EAECF0]"
name="custom-input-number"
>
{count}
</p>
<button
type="button"
data-action="increment"
className="cursor-pointer outline-none w-20 border-y border-r border-r-[#323433] border-y-[#323433] rounded-r-full"
className="cursor-pointer outline-none w-20 border-y border-r border-r-[#EAECF0] border-y-[#EAECF0] rounded-r-md border-l"
onClick={() => setCount(count + 1)}
>
<span className="text-base">+</span>
Expand Down
141 changes: 98 additions & 43 deletions src/APP/pages/shop/SingleItemPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import NotificationModal from "../../components/auth/NotificationModal";
import CartDrawer from "../../components/shop/CartDrawer";
import Counter from "../../components/shop/Counter";
import ItemHeader from "./sections/ItemHeader";
import { FaRegStar, FaRegCircleDot } from "react-icons/fa6";
import { FaRegCircle } from "react-icons/fa";
import { MdOutlineAddShoppingCart } from "react-icons/md";
import { IoMdCheckmark } from "react-icons/io";
import SeoMetadata from "../../components/SeoMetadata";
import formatPrice from "../../../utilities/formatPrice";

const VariationData = [SmallSample1, SmallSample2, SmallSample1, SmallSample2];

Expand All @@ -25,13 +31,16 @@ export default function SingleItemPage() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [message, setMessage] = useState("");
const [selectedSize, setSelectedSize] = useState(null);
const [selectedColor, setSelectedColor] = useState(null);
const [Payload, setPayload] = useState({});

// const { data: singleOrder } = useSingleOrder(params.id);
const { data: singleSwag, isSuccess, refetch } = useSingleSwag(params.id);
const { mutate: addItemsToCart } = useAddSwagToCart();

const sizes = ["XS", "S", "M", "L", "XL", "XXL"];
const colors = ["BBD278", "BBC1F8", "FFD3F8", "AF674F"];

console.log("singleSwag: ", singleSwag);
useEffect(() => {
localStorage.setItem("swagList", []);
Expand Down Expand Up @@ -98,85 +107,131 @@ export default function SingleItemPage() {

return (
<>
<SeoMetadata
title={`${singleSwag?.name}`}
description="Elevate your style with SpaceYaTech's exclusive collection of merchandise."
type="website"
url="https://www.spaceyatech.com/shop"
ogImage="https://apis.spaceyatech.com/media/blog-images/syt.png"
ogImageAlt="SpaceYaTech logo, social media handles, website URL, email, and more on a muted background."
siteName="SpaceYaTech Shop"
/>
<ItemHeader show={() => setOpen((prev) => !prev)} />
{isSuccess ? (
<div className="px-8 sm:px-0 m-auto mb-10 max-w-screen-2xl flex flex-col md:flex-row justify-between w-full space-y-4 md:space-x-28 text-[#323433]">
<div className="px-8 sm:px-10 m-auto mb-10 max-w-screen-2xl flex flex-col md:flex-row justify-between w-full space-y-4 md:space-x-28 text-[#323433]">
<div className="md:pb-14 md:w-1/2 space-y-6">
<LazyLoadImage
<LazyLoadImage
src={singleSwag.image}
alt={singleSwag.name}
className="m-auto md:min-w-full "
className="m-auto min-w-full"
/>
<div className="flex justify-between">
{VariationData.map((pic) => (
<div key={crypto.randomUUID()} className="w-[70px] sm:w-auto">
<LazyLoadImage src={pic} alt="recommendation" />
<LazyLoadImage src={pic} alt="recommendation" />
</div>
))}
</div>
</div>

<div className="w-full md:w-1/2 space-y-5 sm:pr-16">
<h1 className="text-xl md:text-4xl font-semibold md:font-medium">
<h1 className="text-xl md:text-4xl font-medium md:font-semibold">
{singleSwag.name}
</h1>
<h3 className="text-base md:text-xl font-normal md:font-medium">
Product description
</h3>
<p className="text-sm md:text-base">{singleSwag.description}</p>
<p className="text-xl md:text-2xl font-semibold md:font-bold">
Ksh {singleSwag.price}
<p className="text-xl md:text-2xl font-semibold text-[#323433]">
KES {formatPrice(singleSwag.price)}
</p>
<p className="flex gap-2 items-center text-lg md:text-xl font-semibold text-[#656767]">
<span>4.5</span>
<span>
<FaRegStar className="h-5 w-5 fill-primary mb-1" />
</span>
</p>
<h4 className="text-base md:text-xl">Choose color</h4>
<hr />
<h4 className="text-base md:text-xl text-[#656767]">
Choose color
</h4>

<div className="flex justify-start space-x-6">
{VariationData.map((pic) => (
<div key={crypto.randomUUID()}>
<LazyLoadImage
src={pic}
alt=""
height="96px"
width="96px"
className="rounded-full"
/>
</div>
{colors.map((color) => (
<button
type="button"
key={crypto.randomUUID()}
onClick={() => setSelectedColor(color)}
>
{selectedColor === color ? (
<div
role="button"
aria-label="Color selection button"
className="w-12 h-12 border bg-white border-primary rounded-full flex items-center justify-center"
>
<div
className="w-9 h-9 rounded-full flex justify-center items-center"
style={{ backgroundColor: `#${color}` }}
>
<IoMdCheckmark className="text-white text-3xl font-bold" />
</div>
</div>
) : (
<div
aria-label="Color selection button"
role="button"
className="w-12 h-12 rounded-full"
style={{ backgroundColor: `#${color}` }}
/>
)}
</button>
))}
</div>

<h4 className="text-base md:text-xl">Choose size</h4>
<div className="flex justify-between sm:justify-start sm:space-x-4">
<h4 className="text-base md:text-xl text-[#656767]">
Choose a size
</h4>
<div className="flex flex-wrap justify-start sm:justify-start gap-2">
{sizes.map((size) => (
<button
key={size}
type="button"
className={`w-20 h-12 rounded-full border border-[#323433] text-2xl ${
className={`w-fit min-w-12 px-2 sm:px-3 h-8 sm:h-10 rounded-md border border-[#EAECF0] text-lg sm:text-xl font-light flex justify-between items-center gap-1 sm:gap-3 ${
selectedSize === size
? "bg-[#009975] text-white"
: "hover:bg-primary hover:border-[#009975] hover:text-white"
}`}
onClick={() => setSelectedSize(size)}
>
{selectedSize === size ? (
<FaRegCircleDot className="text-sm sm:text-lg" />
) : (
<FaRegCircle className="text-sm sm:text-lg" />
)}{" "}
{size}
</button>
))}
</div>

<Counter className="h-12 w-32" count={count} setCount={setCount} />

<button
type="button"
className="w-full h-[62px] bg-primary text-[#F7F7F7] text-sm font-medium rounded-lg"
onClick={handleBuyNow}
>
Buy Now
</button>
<button
type="button"
className="w-full h-[62px] bg-[#F5FFFD] text-primary text-sm font-medium rounded-lg outline outline-[#009975]"
onClick={handleAddToCart}
>
Add to cart
</button>
<hr />

<div className="flex justify-start gap-3 ">
<Counter
className="h-12 sm:h-14 w-32"
count={count}
setCount={setCount}
/>

<button
type="button"
className="w-32 h-12 sm:w-[179px] sm:h-14 flex justify-center items-center px-1 sm:px-2 py-4 gap-1 sm:gap-3 bg-gradient-to-b from-[#00664E] from-180% to-[#009975] to-90% text-white sm:font-bold text-sm sm:text-base font-medium rounded-lg"
onClick={handleAddToCart}
>
<MdOutlineAddShoppingCart className=" sm:h-8 sm:w-8 text-white" />{" "}
Add to cart
</button>
</div>
<hr />
<h3 className="text-base md:text-xl text-[#323433] font-medium">
Product description
</h3>
<p className="text-sm md:text-base text-[#323433] font-light">
{singleSwag.description}
</p>
</div>
</div>
) : (
Expand Down
40 changes: 11 additions & 29 deletions src/APP/pages/shop/sections/ItemHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { FaCheck } from "react-icons/fa";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { PiShoppingCartLight } from "react-icons/pi";
import { Combobox, Transition } from "@headlessui/react";
import { MdOutlineAddShoppingCart } from "react-icons/md";
import { Fragment, useState } from "react";
import { useLocation, useParams, Link } from "react-router-dom";
import CartIcon from "../../../../assets/images/icons/cart-icon.svg";
import { useSwagList } from "../../../../hooks/Queries/shop/useSwagList";
import GoBackBtn from "../../../components/GoBackBtn";

function ItemHeader({ show }) {
const { pathname } = useLocation();
Expand All @@ -31,37 +32,13 @@ function ItemHeader({ show }) {
);

return (
<div className="px-8 sm:px-0 m-auto max-w-screen-2xl flex justify-between md:space-x-48">
<div className="px-8 sm:px-10 m-auto max-w-screen-2xl flex justify-between md:space-x-48">
{/* Breadcrumb */}
<nav
aria-label="breadcrumb"
className="sm:w-1/2 hidden sm:flex items-center"
>
<ol className="flex space-x-2">
{pathnames.map((value, index) => {
const isLast = index === pathnames.length - 1;
const to = `/${pathnames.slice(0, index + 1).join("/")}`;

return isLast ? (
<li
className="text-primary capitalize"
aria-current="page"
key={to}
>
{value}
</li>
) : (
<li key={to}>
<a
href={to}
className="after:content-['>'] after:ml-2 text-[#656767] hover:text-primary capitalize"
>
{value}
</a>
</li>
);
})}
</ol>
<GoBackBtn />
</nav>

{/* Search box */}
Expand Down Expand Up @@ -145,8 +122,13 @@ function ItemHeader({ show }) {
</Combobox>
</div>
)}
<button type="button" className="ml-6 items-end" onClick={show}>
<PiShoppingCartLight className="h-9 w-9" />
<button
type="button"
aria-label="Shopping cart"
className="ml-6 items-end"
onClick={show}
>
<MdOutlineAddShoppingCart className="h-10 w-10 p-2 bg-green-header text-white border rounded-full" />
</button>
</div>
</div>
Expand Down
Loading