Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
innovatixhub authored Nov 26, 2024
1 parent c477d2b commit 54a42df
Show file tree
Hide file tree
Showing 18 changed files with 1,027 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/componants/shared/productcard/CategoryCard/CategoryCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { camelCase } from "src/Functions/helper";
import SvgIcon from "../../MiniComponents/SvgIcon";
import s from "./CategoryCard.module.scss";

const CategoryCard = ({ categoryData }) => {
const { iconName, title } = categoryData;
const categoryType = title.toLowerCase();
const navigateTo = useNavigate();
const { t } = useTranslation();
const categoryTitleTrans = t(`categoriesData.${camelCase(title)}`);

function navigateToCategory() {
navigateTo(`/category?type=${categoryType}`);
}

return (
<Link
className={s.card}
title={categoryTitleTrans}
onClick={navigateToCategory}
>
<SvgIcon name={iconName} />
<span>{categoryTitleTrans}</span>
</Link>
);
};
export default CategoryCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@import "src/Styles/mixins";

.card {
-webkit-tap-highlight-color: transparent;
scroll-snap-align: start;
border-radius: 4px;
border: solid 1px #0000004D;
outline: 2px solid transparent;
outline-offset: -2px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
transition: background-color .2s;

&:not(:focus-visible):hover {
background-color: var(--tomato);
border-color: var(--tomato);
}

&:focus-visible {
background-color: #db444407;
outline-color: var(--tomato);
}
}

.card svg {
width: 56px;
height: 56px;
transition: fill .2s .1s;

& :where(path, line) {
stroke: var(--black);
}
}

.card svg:where([data-fill-hover], [data-stroke-hover]) {
transition: fill .2s, stroke .2s;
}

.card:not(:focus-visible):hover svg[data-fill-hover] {
& :where(path, line) {
fill: var(--white);
}
}

.card:not(:focus-visible):hover svg[data-stroke-hover] {
& :where(path, line) {
stroke: var(--white);
}
}

.card:focus-visible svg[data-fill-hover] {
& :where(path, line) {
fill: var(--tomato);
}
}

.card:focus-visible svg[data-stroke-hover] {
& :where(path, line) {
stroke: var(--tomato);
}
}

.card span {
margin-top: 26px;
color: var(--black);
}

.card:not(:focus-visible):hover span {
color: var(--white);
}

.card:focus-visible span {
color: var(--tomato);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { showAlert } from "src/Features/alertsSlice";
import { addToArray, removeByKeyName } from "src/Features/productsSlice";
import { compareDataToObjValue, isItemFound } from "src/Functions/helper";
import SvgIcon from "../../../MiniComponents/SvgIcon";
import s from "./AddToCartButton.module.scss";

const AddToCartButton = ({ product }) => {
const { t } = useTranslation();
const { cartProducts, orderProducts } = useSelector(
(state) => state.products
);
const {
loginInfo: { isSignIn },
} = useSelector((state) => state.user);
const isProductAlreadyExist = isItemFound(cartProducts, product, "shortName");
const iconName = isProductAlreadyExist ? "trashCan" : "cart3";
const [iconNameState, setIconName] = useState(iconName);
const dispatch = useDispatch();
const buttonText = t(
`productCard.buttonText.${
isProductAlreadyExist ? "removeFromCart" : "addToCart"
}`
);

function handleCartButton() {
if (!isSignIn) {
showWarning("addToCart");
return;
}

const isAlreadyAddedToOrder = compareDataToObjValue(
orderProducts,
product,
"shortName"
);

if (isAlreadyAddedToOrder) {
showWarning("productAlreadyInOrder");
return;
}

isProductAlreadyExist ? removeFromCart() : addToCart();
}

function showWarning(translateKey) {
dispatch(
showAlert({
alertText: t(`toastAlert.${translateKey}`),
alertState: "warning",
alertType: "alert",
})
);
}

function addToCart() {
const addAction = addToArray({ key: "cartProducts", value: product });
dispatch(addAction);
setIconName("trashCan");
}

function removeFromCart() {
const removeAction = removeByKeyName({
dataKey: "cartProducts",
itemKey: "shortName",
keyValue: product.shortName,
});

dispatch(removeAction);
setIconName("cart3");
}

return (
<button
type="button"
className={`${s.addToCartBtn} ${s.addToCartButton}`}
onClick={handleCartButton}
aria-label={buttonText}
data-add-to-cart-button
>
<SvgIcon name={iconNameState} />
<span>{buttonText}</span>
</button>
);
};
export default AddToCartButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.addToCartBtn {
-webkit-tap-highlight-color: transparent;
border: none;
outline: none;
position: absolute;
left: 0;
bottom: 0;
border-radius: 0 0 4px 4px;
background: var(--black);
width: 100%;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transform: translateY(50px);
transition: background .2s, transform .4s .1s;

&:hover {
background-color: #303030;
}

&:focus-visible {
transform: translateY(0);
background-color: #303030;
transition: opacity .3s, var(--outline-transition), background .2s, transform 0;
outline: 2px solid var(--yellow);
outline-offset: -2px;
color: var(--yellow);
}
}

.addToCartBtn>svg {
fill: var(--white);
margin-inline-end: 6px;
width: 19px;
height: 19px;
transition: fill .2s .05s;
}

.addToCartBtn:hover>svg,
.addToCartBtn:focus-visible>svg {
fill: var(--yellow);
}

.addToCartBtn>span {
color: var(--white);
transition: color .2s .05s;
}

.addToCartBtn:hover>span,
.addToCartBtn:focus-visible>span {
color: var(--yellow);
}
99 changes: 99 additions & 0 deletions src/componants/shared/productcard/ProductCard/ProductCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { checkDateBeforeMonthToPresent } from "src/Functions/helper";
import AddToCartButton from "./AddToCartButton/AddToCartButton";
import s from "./ProductCard.module.scss";
import ProductCardIcons from "./ProductCardIcons/ProductCardIcons";
import ProductCardInfo from "./ProductCardInfo/ProductCardInfo";

const ProductCard = ({
product,
customization = {
stopHover: false,
showDiscount: true,
showFavIcon: true,
showDetailsIcon: true,
showRemoveIcon: false,
showNewText: false,
showWishList: true,
showColors: false,
},
removeFrom,
loading = "eager",
}) => {
const { name, discount, img, id, addedDate } = product;
const {
stopHover,
showDiscount,
showNewText,
showFavIcon,
showDetailsIcon,
showRemoveIcon,
showWishList,
showColors,
} = customization;
const noHoverClass = stopHover ? s.noHover : "";
const hideDiscountClass = discount <= 0 || !showDiscount ? s.hide : "";
const hideNewClass = shouldHideNewWord();
const { loadingProductDetails } = useSelector((state) => state.loading);
const navigateTo = useNavigate();
const iconsData = {
showFavIcon,
showDetailsIcon,
showRemoveIcon,
showWishList,
};

function shouldHideNewWord() {
return checkDateBeforeMonthToPresent(addedDate) || !showNewText
? s.hide
: "";
}

function navigateToProductDetails() {
if (loadingProductDetails) return;
navigateTo(`/details?product=${name.toLowerCase()}`);
}

return (
<div className={`${s.card} ${noHoverClass}`}>
<div className={s.productImg}>
<div className={s.imgHolder}>
<img
src={img}
alt={name}
aria-label={name}
loading={loading}
onClick={navigateToProductDetails}
/>
</div>

<div className={s.layerContent}>
{hideNewClass && (
<div className={`${s.discount} ${hideDiscountClass}`}>
-{discount}%
</div>
)}

<div className={`${s.new} ${hideNewClass}`}>New</div>

<ProductCardIcons
iconsData={iconsData}
productId={id}
navigateToProductDetails={navigateToProductDetails}
product={product}
removeFrom={removeFrom}
/>
<AddToCartButton hoverDataAttribute={true} product={product} />
</div>
</div>

<ProductCardInfo
product={product}
showColors={showColors}
navigateToProductDetails={navigateToProductDetails}
/>
</div>
);
};
export default ProductCard;
Loading

0 comments on commit 54a42df

Please sign in to comment.