-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a0f3b7d
commit 28edbdd
Showing
6 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { useTranslation } from "react-i18next"; | ||
import { Link } from "react-router-dom"; | ||
import CustomNumberInput from "../../Shared/MiniComponents/CustomNumberInput/CustomNumberInput"; | ||
import s from "./CartProduct.module.scss"; | ||
import RemoveCartProductBtn from "./RemoveCartProductBtn"; | ||
|
||
const CartProduct = ({ data }) => { | ||
const { img, name, shortName, afterDiscount, quantity, id } = data; | ||
const priceAfterDiscount = afterDiscount.replaceAll(",", ""); | ||
const subTotal = (quantity * priceAfterDiscount).toFixed(2); | ||
const { t } = useTranslation(); | ||
|
||
const translatedProductName = translateProduct({ | ||
productName: shortName, | ||
translateMethod: t, | ||
translateKey: "shortName", | ||
}); | ||
|
||
return ( | ||
<tr className={s.productContainer}> | ||
<td className={s.product}> | ||
<div className={s.imgHolder}> | ||
<img src={img} alt={`${shortName} product`} /> | ||
<RemoveCartProductBtn productId={id} /> | ||
</div> | ||
|
||
<Link to={`/details?product=${name}`}>{translatedProductName}</Link> | ||
</td> | ||
|
||
<td className={s.price}>${afterDiscount}</td> | ||
|
||
<td> | ||
<CustomNumberInput product={data} quantity={quantity} /> | ||
</td> | ||
|
||
<td>${subTotal}</td> | ||
</tr> | ||
); | ||
}; | ||
export default CartProduct; | ||
|
||
export function translateProduct({ | ||
productName, | ||
translateMethod, | ||
translateKey, | ||
uppercase = false, | ||
dynamicData = {}, | ||
}) { | ||
const shortNameKey = productName?.replaceAll(" ", ""); | ||
const productTrans = `products.${shortNameKey}`; | ||
const translateText = translateMethod( | ||
`${productTrans}.${translateKey}`, | ||
dynamicData | ||
); | ||
return uppercase ? translateText.toUpperCase() : translateText; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
@import "src/Styles/mixins"; | ||
|
||
.productContainer { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
|
||
.product { | ||
display: flex; | ||
align-items: center; | ||
width: 260px !important; | ||
} | ||
|
||
@include very-small { | ||
.product { | ||
width: 100% !important; | ||
} | ||
} | ||
|
||
.imgHolder { | ||
width: fit-content; | ||
height: fit-content; | ||
user-select: none; | ||
position: relative; | ||
} | ||
|
||
.product a { | ||
outline: none; | ||
color: var(--black); | ||
transition: color .1s; | ||
text-wrap: balance; | ||
|
||
&:hover { | ||
color: var(--dark-gray); | ||
} | ||
|
||
&:focus-visible { | ||
color: var(--orange-degree2); | ||
} | ||
} | ||
|
||
.product img { | ||
width: 54px; | ||
margin-inline-end: 20px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { useTranslation } from "react-i18next"; | ||
import { useSelector } from "react-redux"; | ||
import CartProduct from "./CartProduct"; | ||
import s from "./CartProducts.module.scss"; | ||
|
||
const CartProducts = () => { | ||
const { t } = useTranslation(); | ||
const { cartProducts } = useSelector((state) => state.products); | ||
const productsTable = "cartPage.productsTable"; | ||
|
||
return ( | ||
<table className={s.cartProducts}> | ||
<thead> | ||
<tr> | ||
<th>{t(`${productsTable}.product`)}</th> | ||
<th>{t(`${productsTable}.price`)}</th> | ||
<th>{t(`${productsTable}.quantity`)}</th> | ||
<th>{t(`${productsTable}.subtotal`)}</th> | ||
</tr> | ||
</thead> | ||
|
||
<tbody> | ||
{cartProducts.map((product) => ( | ||
<CartProduct key={product.id} data={product} /> | ||
))} | ||
</tbody> | ||
</table> | ||
); | ||
}; | ||
export default CartProducts; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
@import "src/Styles/mixins"; | ||
|
||
.cartProducts { | ||
width: 100%; | ||
min-height: 370px; | ||
} | ||
|
||
@include small { | ||
.cartProducts { | ||
min-height: 270px; | ||
} | ||
} | ||
|
||
.cartProducts tr { | ||
box-shadow: 0 1px 13px 0 #0000000D; | ||
border-radius: 4px; | ||
padding: 24px 40px; | ||
} | ||
|
||
@include small { | ||
.cartProducts tr { | ||
padding: 20px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
width: fit-content; | ||
} | ||
} | ||
|
||
@include small { | ||
.cartProducts thead { | ||
display: none; | ||
} | ||
} | ||
|
||
.cartProducts thead tr { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
margin-bottom: 50px; | ||
} | ||
|
||
.cartProducts thead tr th { | ||
display: inline-block; | ||
width: 100px; | ||
text-align: start; | ||
|
||
&:first-child { | ||
width: 260px; | ||
} | ||
} | ||
|
||
.cartProducts tbody { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 40px; | ||
} | ||
|
||
@include small { | ||
.cartProducts tbody { | ||
display: flex; | ||
flex-direction: row; | ||
flex-wrap: wrap; | ||
} | ||
} | ||
|
||
@include small { | ||
.cartProducts tbody tr { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 20px; | ||
min-width: 310px; | ||
width: calc(50% - 20px); | ||
} | ||
} | ||
|
||
@media (max-width: 520px) { | ||
.cartProducts tbody tr { | ||
min-width: 100%; | ||
width: 100%; | ||
} | ||
} | ||
|
||
.cartProducts tbody>tr>td { | ||
width: 100px; | ||
} | ||
|
||
@include small { | ||
.cartProducts tbody tr td { | ||
@include center-x-y; | ||
} | ||
} | ||
|
||
@include very-small { | ||
.cartProducts tbody tr td { | ||
justify-content: flex-start; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { useEffect, useState } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { useDispatch } from "react-redux"; | ||
import { SCREEN_SIZES } from "src/Data/globalVariables"; | ||
import { removeById } from "src/Features/productsSlice"; | ||
import { cartProductToolTipPos } from "src/Functions/componentsFunctions"; | ||
import useGetResizeWindow from "src/Hooks/Helper/useGetResizeWindow"; | ||
import SvgIcon from "../../Shared/MiniComponents/SvgIcon"; | ||
import ToolTip from "../../Shared/MiniComponents/ToolTip"; | ||
import s from "./RemoveCartProductBtn.module.scss"; | ||
|
||
const RemoveCartProductBtn = ({ productId }) => { | ||
const dispatch = useDispatch(); | ||
const { t, i18n } = useTranslation(); | ||
const { windowWidth } = useGetResizeWindow(); | ||
|
||
const [toolTipLeftPos, setToolTipLeftPos] = useState(cartProductToolTipPos(i18n.language)); | ||
const [toolTipTopPos, setToolTipTopPos] = useState("50%"); | ||
|
||
function updateToolTipPositions() { | ||
if (windowWidth <= SCREEN_SIZES.laptop) { | ||
setToolTipLeftPos("50%"); | ||
setToolTipTopPos("-20px"); | ||
return; | ||
} | ||
|
||
setToolTipLeftPos(cartProductToolTipPos(i18n.language)); | ||
setToolTipTopPos("50%"); | ||
} | ||
|
||
useEffect(() => { | ||
updateToolTipPositions(); | ||
}, [windowWidth, i18n.language]); | ||
|
||
return ( | ||
<button | ||
type="button" | ||
className={s.removeButton} | ||
aria-label="Remove product from cart" | ||
onClick={() => removeProduct(dispatch, productId)} | ||
> | ||
<SvgIcon name="xMark" /> | ||
<ToolTip | ||
top={toolTipTopPos} | ||
left={toolTipLeftPos} | ||
content={t("tooltips.remove")} | ||
/> | ||
</button> | ||
); | ||
}; | ||
export default RemoveCartProductBtn; | ||
|
||
function removeProduct(dispatch, productId) { | ||
const removeAction = removeById({ key: "cartProducts", id: productId }); | ||
dispatch(removeAction); | ||
} |
32 changes: 32 additions & 0 deletions
32
src/componants/cart/cartproduct/RemoveCartProductBtn.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.removeButton { | ||
-webkit-tap-highlight-color: transparent; | ||
border: none; | ||
outline: none; | ||
background-color: var(--tomato); | ||
width: 18px; | ||
height: 18px; | ||
border-radius: 50%; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
cursor: pointer; | ||
|
||
&:focus-visible [data-is-tooltip=true] { | ||
opacity: 1; | ||
} | ||
} | ||
|
||
.removeButton>svg { | ||
width: 12px; | ||
height: 12px; | ||
fill: var(--white) | ||
} | ||
|
||
// Arabic styles | ||
[lang=ar] .removeButton { | ||
left: auto; | ||
right: 0; | ||
} |