first commit

This commit is contained in:
mukesh13
2025-07-30 13:44:47 +05:30
commit 6c0c0e3d1d
494 changed files with 57695 additions and 0 deletions

472
components/shop/Shop.jsx Normal file
View File

@ -0,0 +1,472 @@
"use client";
import { products } from "@/data/products";
import React, { useEffect, useReducer } from "react";
import Image from "next/image";
import FilteringOptions from "./FilteringOptions";
import Link from "next/link";
import { initialState, reducer } from "@/reducer/FilterReducer";
import { useContextElement } from "@/context/Context";
export default function Shop() {
const { addProductToCart, isAddedToCartProducts } = useContextElement();
const [state, dispatch] = useReducer(reducer, initialState);
const {
price,
brands,
filtered,
sortingOption,
sorted,
currentPage,
itemPerPage,
} = state;
const allProps = {
...state,
setPrice: (value) => dispatch({ type: "SET_PRICE", payload: value }),
setBrands: (newBrand) => {
let newBrands = [...brands];
if (newBrands.includes(newBrand)) {
newBrands = newBrands.filter((brand) => brand != newBrand);
} else {
newBrands = [...newBrands, newBrand];
}
console.log(newBrands);
dispatch({ type: "SET_BRANDS", payload: newBrands });
},
setSortingOption: (value) =>
dispatch({ type: "SET_SORTING_OPTION", payload: value }),
setCurrentPage: (value) =>
dispatch({ type: "SET_CURRENT_PAGE", payload: value }),
setItemPerPage: (value) => {
dispatch({ type: "SET_CURRENT_PAGE", payload: 1 }),
dispatch({ type: "SET_ITEM_PER_PAGE", payload: value });
},
clearFilter: () => {
dispatch({ type: "CLEAR_FILTER" });
},
};
useEffect(() => {
let filteredArrays = [];
if (brands.length) {
const filteredByBrands = [...products].filter((elm) =>
brands.every((brand) => elm.filterBrands.includes(brand))
);
filteredArrays = [...filteredArrays, filteredByBrands];
}
const filteredByPrice = [...products].filter(
(elm) => elm.price >= price[0] && elm.price <= price[1]
);
filteredArrays = [...filteredArrays, filteredByPrice];
const commonItems = [...products].filter((item) =>
filteredArrays.every((array) => array.includes(item))
);
dispatch({ type: "SET_FILTERED", payload: commonItems });
}, [price, brands]);
useEffect(() => {
if (sortingOption === "Price Ascending") {
dispatch({
type: "SET_SORTED",
payload: [...filtered].sort((a, b) => a.price - b.price),
});
} else if (sortingOption === "Price Descending") {
dispatch({
type: "SET_SORTED",
payload: [...filtered].sort((a, b) => b.price - a.price),
});
} else if (sortingOption === "Title Ascending") {
dispatch({
type: "SET_SORTED",
payload: [...filtered].sort((a, b) => a.title.localeCompare(b.title)),
});
} else if (sortingOption === "Title Descending") {
dispatch({
type: "SET_SORTED",
payload: [...filtered].sort((a, b) => b.title.localeCompare(a.title)),
});
} else {
dispatch({ type: "SET_SORTED", payload: filtered });
}
dispatch({ type: "SET_CURRENT_PAGE", payload: 1 });
}, [filtered, sortingOption]);
return (
<div className="tf-spacing-41">
<div className="tf-container">
<div className="wrap-shop">
<div className="row">
<div className="col-xl-8">
<div className="left">
<div className="top mb_92">
<div className="text_mono-gray-8 text-body-1 result-count">
Showing 16 of 8 results
</div>
<div className="wrap d-flex">
<div className="wrap-sort">
<div className="text_mono-gray-8 text-body-1">
Sort by
</div>
<div
className="tf-dropdown-sort"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<div className="btn-select">
<span className="text-body-3 text-sort-value">
{sortingOption}
</span>
<span className="icon icon-angle-down-solid" />
</div>
<div className="dropdown-menu">
{[
"Sort by (Default)",
"Title Ascending",
"Title Descending",
"Price Ascending",
"Price Descending",
].map((elm, i) => (
<div
key={i}
className={`select-item ${
sortingOption == elm ? "active" : ""
}`}
onClick={() => allProps.setSortingOption(elm)}
data-sort-value="best-selling"
>
<span className="text-body-3 text-value-item">
{elm}
</span>
</div>
))}
</div>
</div>
</div>
<div className="wrap-layout">
<ul
className="nav-tab-filter group-layout"
role="tablist"
>
<li className="nav-tab-item" role="presentation">
<a
href="#gridLayout"
className="btn-layout grid nav-link-item active"
data-bs-toggle="tab"
>
<svg
width={22}
height={22}
viewBox="0 0 22 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.611328 7.94444H21.3891M21.3891 14.6667H0.611328"
stroke="black"
/>
<rect
x="0.5"
y="0.5"
width={21}
height={21}
stroke="black"
/>
<path d="M7.33398 0V20.7778" stroke="black" />
<path d="M14.666 0V20.7778" stroke="black" />
</svg>
</a>
</li>
<li className="nav-tab-item" role="presentation">
<a
href="#listLayout"
className="nav-link-item btn-layout list"
data-bs-toggle="tab"
>
<svg
width={22}
height={22}
viewBox="0 0 22 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4.88867 4.8889H21.3887"
stroke="black"
/>
<circle
cx="1.22222"
cy="4.88889"
r="0.722222"
fill="#D9D9D9"
stroke="black"
/>
<path d="M4.88867 11H21.3887" stroke="black" />
<path
d="M1.94444 11C1.94444 11.3989 1.62109 11.7222 1.22222 11.7222C0.82335 11.7222 0.5 11.3989 0.5 11C0.5 10.6011 0.82335 10.2778 1.22222 10.2778C1.62109 10.2778 1.94444 10.6011 1.94444 11Z"
fill="#D9D9D9"
stroke="black"
/>
<path
d="M4.88867 17.1111H21.3887"
stroke="black"
/>
<path
d="M1.94444 17.1111C1.94444 17.51 1.62109 17.8333 1.22222 17.8333C0.82335 17.8333 0.5 17.51 0.5 17.1111C0.5 16.7122 0.82335 16.3889 1.22222 16.3889C1.62109 16.3889 1.94444 16.7122 1.94444 17.1111Z"
fill="#D9D9D9"
stroke="black"
/>
</svg>
</a>
</li>
</ul>
</div>
</div>
</div>
<div className="flat-animate-tab">
<div className="tab-content">
<div
className="tab-pane active show"
id="gridLayout"
role="tabpanel"
>
<div className="tf-grid-layout-2 md-col-3">
{sorted.map((product) => (
<div
className="product-item hover-image"
key={product.id}
>
<Link
href={`/product-details/${product.id}`}
className="img-style"
>
<Image
className="lazyload"
data-src={product.imgSrc}
alt="item"
src={product.imgSrc}
width={product.width}
height={product.height}
/>
</Link>
<div className="content">
<div className="info">
<div className="text-body-1 product-name mb_8">
<Link
href={`/product-details/${product.id}`}
className="link"
>
{product.title}
</Link>
</div>
<div className="h6 price d-flex gap_10">
{product.oldPrice ? (
<>
<span className="new-price">
$
{product.price.toFixed(
product.price % 1 === 0 ? 0 : 2
)}
</span>
<span className="old-price sub-heading">
$
{product.oldPrice.toFixed(
product.oldPrice % 1 === 0 ? 0 : 2
)}
</span>
</>
) : (
`$${product.price.toFixed(
product.price % 1 === 0 ? 0 : 2
)}`
)}
</div>
</div>
<a
href="#"
onClick={(e) => {
e.preventDefault();
addProductToCart(product.id);
}}
className={`add-cart ${
isAddedToCartProducts(product.id)
? "cart-added"
: ""
}`}
>
<i className="icon-shopping-cart-solid" />
</a>
</div>
</div>
))}
</div>
<ul className="wg-pagination d-flex justify-content-center gap_12 mt_58">
<li>
<a href="#">
<i className="icon-angle-left-solid" />
</a>
</li>
<li>
<a href="#" className="active">
1
</a>
</li>
<li>
<a href="#">...</a>
</li>
<li>
<a href="#">4</a>
</li>
<li>
<a href="#">
<i className="icon-angle-right-solid" />
</a>
</li>
</ul>
</div>
<div className="tab-pane" id="listLayout" role="tabpanel">
<div className="wrap-list d-flex gap-16 flex-direction-column">
{sorted.map((product, i) => (
<div
key={i}
className="product-item hover-image style-list"
>
<Link
href={`/product-details/${product.id}`}
className="img-style"
>
<Image
className="lazyload"
alt="item"
src={product.imgSrc}
width={product.width}
height={product.height}
/>
</Link>
<div className="content">
<div className="info">
<div className="text-body-1 product-name mb_8">
<Link
href={`/product-details/${product.id}`}
className="link"
>
{product.title}
</Link>
</div>
<div className="h6 price d-flex gap_10">
{product.oldPrice ? (
<>
<span className="new-price">
$
{product.price.toFixed(
product.price % 1 === 0 ? 0 : 2
)}
</span>
<span className="old-price sub-heading">
$
{product.oldPrice.toFixed(
product.oldPrice % 1 === 0 ? 0 : 2
)}
</span>
</>
) : (
`$${product.price.toFixed(
product.price % 1 === 0 ? 0 : 2
)}`
)}
</div>
</div>
<div className="list-product-btn">
<a
onClick={(e) => {
e.preventDefault();
addProductToCart(product.id);
}}
className="add-cart"
href="#"
>
{isAddedToCartProducts(product.id)
? "Already Added"
: "Add to Cart"}
</a>
<a
href="#"
className="box-icon wishlist btn-icon-action"
>
<span className="icon icon-heart" />
<span className="tooltip">Wishlist</span>
</a>
<a
href="#"
className="box-icon quickview tf-btn-loading"
>
<span className="icon icon-eye" />
<span className="tooltip">Quick View</span>
</a>
</div>
</div>
</div>
))}
</div>
<ul className="wg-pagination d-flex justify-content-center gap_12 mt_58">
<li>
<a href="#">
<i className="icon-angle-left-solid" />
</a>
</li>
<li>
<a href="#" className="active">
1
</a>
</li>
<li>
<a href="#">...</a>
</li>
<li>
<a href="#">4</a>
</li>
<li>
<a href="#">
<i className="icon-angle-right-solid" />
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div className="col-xl-4">
<div className="right">
<div className="sildebar-fiiler canvas-filter">
<div className="canvas-wrapper">
<div className="canvas-header d-flex d-xl-none">
<h5 className="">
<span className="icon icon-filter" />
Filters
</h5>
<div className="close-filter">
<span className="icon-times-solid" />
</div>
</div>
<div className="canvas-body">
<FilteringOptions allProps={allProps} />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}