Skip to content

Commit

Permalink
Variants \ actions block (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
mpohorenyi authored Dec 20, 2023
1 parent 7e5de88 commit 2d0629e
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 9 deletions.
50 changes: 41 additions & 9 deletions src/modules/ProductDetailsPage/ProductDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import styles from './ProductDetailsPage.module.scss';

import { getRecommendedProducts } from '../../api/service';
import { useAppSelector } from '../../store/hooks';
import { Detail, Product } from '../../types/Product';
import {
Detail, PreparedInfo, Product, ProductDetail,
} from '../../types/Product';
import { EndPoints } from '../../types/Enums';

import { Breadcrumbs } from '../shared/Breadcrumbs';
Expand All @@ -16,11 +18,7 @@ import { ColorCapacityComponent } from './components/ColorCapacityComponent';
import { ProductAbout } from './components/ProductAbout/ProductAbout';
import { ProductTechSpec } from './components/ProductTechSpec/ProductTechSpec';
import { ProductSlider } from '../shared/ProductSlider/ProductSlider';

type Props = {
loadData: (endPoint: EndPoints, itemId: string) => Promise<Detail>;
endPoint: EndPoints;
};
import { InfoAndPurchase } from './components/InfoAndPurchase';

function getDetails(
productDetail: Detail,
Expand All @@ -31,26 +29,51 @@ function getDetails(
if (color && capacity) {
return productDetail.additional.find(
(product) => product.color === color && product.capacity === capacity,
);
) || null;
}

if (color) {
return productDetail.additional.find(
(product) => product.color === color
&& product.capacity === productDetail.current.capacity,
);
) || null;
}

if (capacity) {
return productDetail.additional.find(
(product) => product.capacity === capacity
&& product.color === productDetail.current.color,
);
) || null;
}

return productDetail.current;
}

function prepareInfo(
productDetail: Detail | null,
details: ProductDetail | null,
): PreparedInfo | null {
if (productDetail && details) {
return {
fullPrice: details.priceRegular,
price: details.priceDiscount,
specs: {
screen: details.screen,
resolution: details.resolution,
processor: details.processor,
ram: details.ram,
},
};
}

return null;
}

type Props = {
loadData: (endPoint: EndPoints, itemId: string) => Promise<Detail>;
endPoint: EndPoints;
};

export const ProductDetailsPage: React.FC<Props> = ({ loadData, endPoint }) => {
const { isDarkTheme } = useAppSelector((state) => state.theme);
const [productDetail, setProductDetail] = useState<Detail | null>(null);
Expand All @@ -65,6 +88,11 @@ export const ProductDetailsPage: React.FC<Props> = ({ loadData, endPoint }) => {
? getDetails(productDetail, { color, capacity })
: null;

const preparedInfo = prepareInfo(productDetail, details);
const product = productDetail?.products.find(
(prod) => prod.itemId === details?.id,
) || null;

const changeUrl = (id: string) => {
navigate(`/${endPoint}/${id}`, {
replace: true,
Expand Down Expand Up @@ -107,6 +135,10 @@ export const ProductDetailsPage: React.FC<Props> = ({ loadData, endPoint }) => {
setCapacity={setCapacity}
/>

{preparedInfo && (
<InfoAndPurchase product={product} info={preparedInfo} />
)}

<ProductAbout
isDarkTheme={isDarkTheme}
description={details.description}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@import '../../../../styles/utils/mixins/mixin-media';
@import '../../../../styles/utils/mixins/mixin-typography';
@import '../../../../styles/utils/variables/colors';

.infoAndPurchase {
display: flex;
flex-direction: column;
grid-column: span 4;

@include onTablet {
grid-column: 8 / 12;
}

@include onDesktop {
grid-column: 14 / 20;
}

&__price {
display: flex;
gap: 8px;
margin-bottom: 16px;
@include h2-typography;
}

&__fullPrice {
font-size: 22px;
font-weight: 500;
text-decoration-line: line-through;
color: $color__secondary;
}

&__specs {
display: flex;
flex-direction: column;
gap: 8px;
}

&__spec {
display: flex;
justify-content: space-between;
font-size: 12px;
color: $color__primary;

&__title {
font-weight: 600;
color: $color__secondary;
}

&__text {
font-weight: 700;
}
}

&__buttons {
display: flex;
justify-content: space-between;
margin-bottom: 32px;
}
}

.infoAndPurchase__DARK {
.infoAndPurchase {
&__price {
@include typography-dark;
}

&__fullPrice {
color: $color__dark-theme__secondary;
}

&__spec {
color: $color__dark-theme__white;

&__title {
color: $color__dark-theme__secondary;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import cn from 'classnames';

import styles from './InfoAndPurchase.module.scss';

import { useAppSelector } from '../../../../store/hooks';
import { PreparedInfo, Product } from '../../../../types/Product';

import { AddToCart } from '../../../shared/AddToCart';
import { AddToFavourites } from '../../../shared/AddToFavourites';

type Props = {
product: Product | null;
info: PreparedInfo;
};

export const InfoAndPurchase: React.FC<Props> = ({ product, info }) => {
const { isDarkTheme } = useAppSelector((state) => state.theme);
const { fullPrice, price, specs } = info; // eslint-disable-line object-curly-newline

return (
<div
className={cn(styles.infoAndPurchase, {
[styles.infoAndPurchase__DARK]: isDarkTheme,
})}
>
<div className={styles.infoAndPurchase__price}>
<p>{`$${price}`}</p>
<p className={styles.infoAndPurchase__fullPrice}>{`$${fullPrice}`}</p>
</div>

<div className={styles.infoAndPurchase__buttons}>
{product && (
<>
<AddToCart productItem={product} />
<AddToFavourites productItem={product} />
</>
)}
</div>

<div className={styles.infoAndPurchase__specs}>
{Object.entries(specs).map(([key, value]) => (
<div key={key} className={styles.infoAndPurchase__spec}>
<p className={styles.infoAndPurchase__spec__title}>{key}</p>
<p className={styles.infoAndPurchase__spec__text}>{value}</p>
</div>
))}
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './InfoAndPurchase';
12 changes: 12 additions & 0 deletions src/types/Product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,16 @@ export interface ProductWithAmount extends Product {
export interface Detail {
current: ProductDetail;
additional: ProductDetail[];
products: Product[],
}

export interface PreparedInfo {
fullPrice: number;
price: number;
specs: {
screen: string;
resolution: string;
processor: string;
ram: string;
};
}

0 comments on commit 2d0629e

Please sign in to comment.