diff --git a/src/componants/shared/productcard/CategoryCard/CategoryCard.jsx b/src/componants/shared/productcard/CategoryCard/CategoryCard.jsx
new file mode 100644
index 0000000..6a01baf
--- /dev/null
+++ b/src/componants/shared/productcard/CategoryCard/CategoryCard.jsx
@@ -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 (
+
+
+ {categoryTitleTrans}
+
+ );
+};
+export default CategoryCard;
diff --git a/src/componants/shared/productcard/CategoryCard/CategoryCard.module.scss b/src/componants/shared/productcard/CategoryCard/CategoryCard.module.scss
new file mode 100644
index 0000000..790d73b
--- /dev/null
+++ b/src/componants/shared/productcard/CategoryCard/CategoryCard.module.scss
@@ -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);
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.jsx b/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.jsx
new file mode 100644
index 0000000..b1d0e65
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.jsx
@@ -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 (
+
+ );
+};
+export default AddToCartButton;
diff --git a/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.module.scss b/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.module.scss
new file mode 100644
index 0000000..dd81cd4
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/AddToCartButton/AddToCartButton.module.scss
@@ -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);
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCard.jsx b/src/componants/shared/productcard/ProductCard/ProductCard.jsx
new file mode 100644
index 0000000..794d883
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCard.jsx
@@ -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 (
+
+
+
+
+
+
+
+ {hideNewClass && (
+
+ -{discount}%
+
+ )}
+
+
New
+
+
+
+
+
+
+
+
+ );
+};
+export default ProductCard;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCard.module.scss b/src/componants/shared/productcard/ProductCard/ProductCard.module.scss
new file mode 100644
index 0000000..d046884
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCard.module.scss
@@ -0,0 +1,124 @@
+@import "src/Styles/mixins";
+
+.card {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+ min-width: 256px;
+ scroll-snap-align: start;
+}
+
+.productImg {
+ border-radius: 4px;
+ background: var(--very-light-gray2);
+ width: 100%;
+ height: 250px;
+ @include center-x-y;
+ user-select: none;
+ position: relative;
+}
+
+.imgHolder {
+ position: relative;
+ z-index: 6;
+ transition: .4s scale;
+}
+
+.productImg:hover .imgHolder {
+ scale: 1.1;
+}
+
+.imgHolder img {
+ width: 172px;
+ height: 152px;
+ object-fit: contain;
+ cursor: pointer;
+}
+
+.layerContent {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ padding: 14px;
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ overflow: hidden;
+}
+
+.layerContent .discount {
+ background: var(--dark-tomato);
+ color: var(--secondary-white);
+ width: fit-content;
+ padding: 4px 12px;
+ @include center-x-y;
+ gap: 10px;
+ border-radius: 4px;
+ user-select: none;
+ font-size: .75rem;
+}
+
+.layerContent .new {
+ background-color: var(--green);
+ color: var(--white);
+ width: 51px;
+ height: 26px;
+ padding: 4px 12px;
+ border-radius: 4px;
+ user-select: none;
+ font-size: .75rem;
+
+ &.hide {
+ display: none;
+ }
+}
+
+.layerContent .discount.hide {
+ opacity: 0;
+ pointer-events: none;
+ z-index: -1;
+}
+
+.card:hover [data-product-icons-hover],
+.card.noHover [data-product-icons-hover] {
+ opacity: 1;
+ transform: translateX(0);
+ transition: transform .4s .1s, opacity .2s .2s;
+}
+
+@include small {
+ .card [data-product-icons-hover] {
+ opacity: 1;
+ transform: translateX(0);
+ transition: transform .4s .1s, opacity .2s .2s;
+ }
+}
+
+.card:has(:focus-visible) [data-product-icons-hover] {
+ opacity: 1;
+ transform: translateX(0);
+ transition: transform 0, opacity 0;
+}
+
+.card:hover [data-add-to-cart-button],
+.card.noHover [data-add-to-cart-button] {
+ transform: translateY(0);
+}
+
+@include small {
+ .card [data-add-to-cart-button] {
+ transform: translateY(0);
+ }
+}
+
+// Arabic styles
+[lang=ar] .card {
+ direction: rtl;
+}
+
+[lang=ar] .layerContent {
+ direction: ltr;
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.jsx b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.jsx
new file mode 100644
index 0000000..d98bd6f
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.jsx
@@ -0,0 +1,27 @@
+import { useTranslation } from "react-i18next";
+import { Link } from "react-router-dom";
+import { detailsIconToolTipLeftPos } from "src/Functions/componentsFunctions";
+import SvgIcon from "../../../MiniComponents/SvgIcon";
+import ToolTip from "../../../MiniComponents/ToolTip";
+import s from "./ProductCardDetailsIcon.module.scss";
+
+const ProductCardDetailsIcon = ({ navigateToProductDetails }) => {
+ const { t, i18n } = useTranslation();
+ const detailsIconLeftToolTipPos = detailsIconToolTipLeftPos(i18n.language);
+
+ return (
+
+
+
+
+ );
+};
+export default ProductCardDetailsIcon;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.module.scss
new file mode 100644
index 0000000..4162686
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardDetailsIcon.module.scss
@@ -0,0 +1,37 @@
+.iconHolder {
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ border: none;
+ width: 34px;
+ height: 34px;
+ background: var(--white);
+ color: var(--black);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ position: relative;
+
+ &:focus-visible {
+ background-color: #303030;
+ transition: opacity .3s, var(--outline-transition), background .2s, transform 0;
+ outline: 2px solid var(--yellow);
+ outline-offset: -2px;
+ }
+}
+
+.iconHolder svg {
+ font-size: .9rem;
+ transition: fill .2s;
+ width: 16px;
+ height: 16px;
+}
+
+.iconHolder:focus-visible svg {
+ fill: var(--yellow);
+}
+
+.detailsIcon:not(:focus-visible):hover svg {
+ fill: #6f6f6f;
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.jsx b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.jsx
new file mode 100644
index 0000000..015b9c6
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.jsx
@@ -0,0 +1,72 @@
+import { useTranslation } from "react-i18next";
+import { useDispatch, useSelector } from "react-redux";
+import { showAlert } from "src/Features/alertsSlice";
+import { addToArray, removeById } from "src/Features/productsSlice";
+import { favIconToolTipLeftPos } from "src/Functions/componentsFunctions";
+import { isItemFound } from "src/Functions/helper";
+import SvgIcon from "../../../MiniComponents/SvgIcon";
+import ToolTip from "../../../MiniComponents/ToolTip";
+import s from "./ProductCardFavIcon.module.scss";
+
+const ProductCardFavIcon = ({ product, productId }) => {
+ const {
+ loginInfo: { isSignIn },
+ } = useSelector((state) => state.user);
+ const { favoritesProducts } = useSelector((state) => state.products);
+ const { t, i18n } = useTranslation();
+ const dispatch = useDispatch();
+ const favIconLeftToolTipPos = favIconToolTipLeftPos(i18n.language);
+ const isAddedToFavorites = favoritesProducts?.find(
+ (favProduct) => favProduct.id === productId
+ );
+ const activeClass = isAddedToFavorites ? s.active : "";
+
+ function addProductToFavorite() {
+ if (!isSignIn) {
+ dispatch(
+ showAlert({
+ alertText: t("toastAlert.addToFavorite"),
+ alertState: "warning",
+ alertType: "alert",
+ })
+ );
+ return;
+ }
+
+ const isProductAlreadyExist = isItemFound(favoritesProducts, product, "id");
+
+ if (isProductAlreadyExist) {
+ removeProduct();
+ return;
+ }
+
+ addProduct();
+ }
+
+ function removeProduct() {
+ dispatch(removeById({ key: "favoritesProducts", id: product.id }));
+ }
+
+ function addProduct() {
+ dispatch(addToArray({ key: "favoritesProducts", value: product }));
+ }
+
+ return (
+
+ );
+};
+export default ProductCardFavIcon;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.module.scss
new file mode 100644
index 0000000..7b880a4
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardFavIcon.module.scss
@@ -0,0 +1,81 @@
+.iconHolder {
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ border: none;
+ width: 34px;
+ height: 34px;
+ background: var(--white);
+ color: var(--black);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ position: relative;
+
+ &:focus-visible {
+ background-color: #303030;
+ transition: opacity .3s, var(--outline-transition), background .2s, transform 0;
+ outline: 2px solid var(--yellow);
+ outline-offset: -2px;
+ }
+}
+
+.iconHolder svg {
+ font-size: .9rem;
+ transition: fill .2s;
+ width: 16px;
+ height: 16px;
+}
+
+.iconHolder:focus-visible svg {
+ fill: var(--yellow);
+}
+
+.favIcon {
+ --heart-color: var(--tomato);
+
+ &:focus-visible {
+ --heart-color: var(--yellow);
+ }
+}
+
+.favIcon.active {
+ fill: var(--tomato);
+
+ & .heartBackground {
+ opacity: 1;
+ }
+}
+
+.favIcon .heartBackground {
+ position: absolute;
+ top: 17px;
+ right: calc(50% + -0.4px);
+ translate: 50% 0;
+ border-style: solid;
+ border-color: var(--heart-color) transparent transparent transparent;
+ border-width: 7px;
+ opacity: 0;
+ pointer-events: none;
+ scale: 1.03;
+}
+
+.favIcon .heartBackground::before,
+.favIcon .heartBackground::after {
+ content: '';
+ position: absolute;
+ top: -12px;
+ background-color: var(--heart-color);
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+}
+
+.favIcon .heartBackground::before {
+ left: -7.5px;
+}
+
+.favIcon .heartBackground::after {
+ right: -7px;
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.jsx b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.jsx
new file mode 100644
index 0000000..5799aa1
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.jsx
@@ -0,0 +1,36 @@
+import ProductCardDetailsIcon from "./ProductCardDetailsIcon";
+import ProductCardFavIcon from "./ProductCardFavIcon";
+import s from "./ProductCardIcons.module.scss";
+import ProductCardRemoveIcon from "./ProductCardRemoveIcon";
+import ProductCardWishListIcon from "./ProductCardWishListIcon";
+
+const ProductCardIcons = ({
+ iconsData: { showFavIcon, showDetailsIcon, showRemoveIcon, showWishList },
+ productId,
+ navigateToProductDetails,
+ product,
+ removeFrom,
+}) => {
+ return (
+
+ {showFavIcon && (
+
+ )}
+
+ {showDetailsIcon && (
+
+ )}
+
+ {showRemoveIcon && (
+
+ )}
+
+ {showWishList && (
+
+ )}
+
+ );
+};
+export default ProductCardIcons;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.module.scss
new file mode 100644
index 0000000..e18ac16
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardIcons.module.scss
@@ -0,0 +1,11 @@
+@import "src/Styles/mixins.scss";
+
+.icons {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ position: relative;
+ z-index: 10;
+ opacity: 0;
+ transform: translateX(50px);
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.jsx b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.jsx
new file mode 100644
index 0000000..a3e69fa
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.jsx
@@ -0,0 +1,34 @@
+import { useTranslation } from "react-i18next";
+import { useDispatch } from "react-redux";
+import { removeById } from "src/Features/productsSlice";
+import { trashcanIconToolTipLeftPos } from "src/Functions/componentsFunctions";
+import SvgIcon from "../../../MiniComponents/SvgIcon";
+import ToolTip from "../../../MiniComponents/ToolTip";
+import s from "./ProductCardRemoveIcon.module.scss";
+
+const ProductCardRemoveIcon = ({ removeFrom, productId }) => {
+ const { t, i18n } = useTranslation();
+ const dispatch = useDispatch();
+ const trashcanIconLeftToolTipPos = trashcanIconToolTipLeftPos(i18n.language);
+
+ function removeProduct() {
+ dispatch(removeById({ key: removeFrom, id: productId }));
+ }
+
+ return (
+
+ );
+};
+export default ProductCardRemoveIcon;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.module.scss
new file mode 100644
index 0000000..9fee8e5
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardRemoveIcon.module.scss
@@ -0,0 +1,37 @@
+.iconHolder {
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ border: none;
+ width: 34px;
+ height: 34px;
+ background: var(--white);
+ color: var(--black);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ position: relative;
+
+ &:focus-visible {
+ background-color: #303030;
+ transition: opacity .3s, var(--outline-transition), background .2s, transform 0;
+ outline: 2px solid var(--yellow);
+ outline-offset: -2px;
+ }
+}
+
+.iconHolder svg {
+ font-size: .9rem;
+ transition: fill .2s;
+ width: 16px;
+ height: 16px;
+}
+
+.iconHolder:focus-visible svg {
+ fill: var(--yellow);
+}
+
+.removeIcon:hover svg {
+ fill: var(--tomato);
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.jsx b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.jsx
new file mode 100644
index 0000000..738bbd2
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.jsx
@@ -0,0 +1,70 @@
+import { useTranslation } from "react-i18next";
+import { useDispatch, useSelector } from "react-redux";
+import { showAlert } from "src/Features/alertsSlice";
+import { addToArray, removeById } from "src/Features/productsSlice";
+import { wishlistIconToolTipLeftPos } from "src/Functions/componentsFunctions";
+import { isItemFound } from "src/Functions/helper";
+import SvgIcon from "../../../MiniComponents/SvgIcon";
+import ToolTip from "../../../MiniComponents/ToolTip";
+import s from "./ProductCardWishListIcon.module.scss";
+
+const ProductCardWishListIcon = ({ product, productId }) => {
+ const {
+ loginInfo: { isSignIn },
+ } = useSelector((state) => state.user);
+ const { wishList } = useSelector((state) => state.products);
+ const { t, i18n } = useTranslation();
+ const dispatch = useDispatch();
+ const wishlistIconLeftToolTipPos = wishlistIconToolTipLeftPos(i18n.language);
+ const isAddedToWishList = wishList?.find(
+ (wishProduct) => wishProduct.id === productId
+ );
+ const activeClass = isAddedToWishList ? s.active : "";
+
+ function addProductToWishList() {
+ if (!isSignIn) {
+ dispatch(
+ showAlert({
+ alertText: t("toastAlert.addToWishList"),
+ alertState: "warning",
+ alertType: "alert",
+ })
+ );
+ return;
+ }
+
+ const isProductAlreadyExist = isItemFound(wishList, product, "id");
+
+ if (isProductAlreadyExist) {
+ removeProduct();
+ return;
+ }
+
+ addProduct();
+ }
+
+ function removeProduct() {
+ dispatch(removeById({ key: "wishList", id: product.id }));
+ }
+
+ function addProduct() {
+ dispatch(addToArray({ key: "wishList", value: product }));
+ }
+
+ return (
+
+ );
+};
+export default ProductCardWishListIcon;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.module.scss
new file mode 100644
index 0000000..799022a
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardIcons/ProductCardWishListIcon.module.scss
@@ -0,0 +1,45 @@
+.iconHolder {
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ border: none;
+ width: 34px;
+ height: 34px;
+ background: var(--white);
+ color: var(--black);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ position: relative;
+
+ &:focus-visible {
+ background-color: #303030;
+ transition: opacity .3s, var(--outline-transition), background .2s, transform 0;
+ outline: 2px solid var(--yellow);
+ outline-offset: -2px;
+ }
+}
+
+.iconHolder svg {
+ font-size: .9rem;
+ transition: fill .2s;
+ width: 16px;
+ height: 16px;
+}
+
+.iconHolder:focus-visible svg {
+ fill: var(--yellow);
+}
+
+.wishListIcon svg {
+ fill: var(--black);
+}
+
+.wishListIcon:not(:focus-visible):hover svg {
+ fill: #6f6f6f;
+}
+
+.wishListIcon.active svg path {
+ fill-rule: nonzero;
+}
\ No newline at end of file
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.jsx b/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.jsx
new file mode 100644
index 0000000..3be50ee
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.jsx
@@ -0,0 +1,44 @@
+import { useTranslation } from "react-i18next";
+import { translateProduct } from "../../../../Cart/CartProducts/CartProduct";
+import RateStars from "../../../MidComponents/RateStars/RateStars";
+import ProductColors from "../../../MiniComponents/ProductColors/ProductColors";
+import s from "./ProductCardInfo.module.scss";
+
+const ProductCardInfo = ({ product, showColors, navigateToProductDetails }) => {
+ const { shortName, price, discount, afterDiscount, rate, votes, colors } =
+ product;
+ const { t } = useTranslation();
+
+ const translatedProductName = translateProduct({
+ productName: shortName,
+ translateMethod: t,
+ translateKey: "shortName",
+ });
+
+ return (
+
+ );
+};
+export default ProductCardInfo;
diff --git a/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.module.scss b/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.module.scss
new file mode 100644
index 0000000..8d4626a
--- /dev/null
+++ b/src/componants/shared/productcard/ProductCard/ProductCardInfo/ProductCardInfo.module.scss
@@ -0,0 +1,63 @@
+@import "src/Styles/mixins";
+
+.productInfo {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.productInfo .productName a {
+ outline: none;
+ border-bottom: solid 2px var(--website-bg);
+ font-weight: 500;
+ color: var(--black);
+ transition: color .2s;
+
+ &:hover {
+ color: var(--brown);
+ }
+
+ &:focus {
+ border-bottom: solid 2px var(--orange-degree2);
+ color: var(--orange-degree2);
+ }
+}
+
+.productInfo .price {
+ color: var(--dark-tomato);
+ font-weight: 500;
+}
+
+.productInfo .price .afterDiscount {
+ // margin-inline-start: 16px;
+ margin-left: 16px;
+ color: var(--primary);
+ font-weight: 500;
+}
+
+.productInfo .rateContainer {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ user-select: none;
+}
+
+.productInfo .rateContainer .numOfVotes {
+ font-weight: 600;
+ font-size: .875rem;
+ color: var(--primary);
+}
+
+.productInfo .colors {
+ display: flex;
+ align-items: center;
+ margin-bottom: 18px;
+ gap: 15px;
+ margin-top: 10px;
+ margin-inline-start: 3px;
+}
+
+// Arabic styles
+[lang=ar] .productInfo {
+ direction: rtl;
+}
\ No newline at end of file