From 18592a0ad91e17b3393223671da1b5f129f1f757 Mon Sep 17 00:00:00 2001 From: Kate Marchuk Date: Sun, 22 Sep 2024 19:18:34 +0300 Subject: [PATCH] Added Variants and Action layout. Changed Buttons components --- .../Buttons/Button/Button.module.scss | 38 +++++++ src/components/Buttons/Button/Button.tsx | 36 +++++++ src/components/Buttons/Button/index.ts | 1 + .../ButtonWithColor.module.scss | 19 ++++ .../ButtonWithColor/ButtonWithColor.tsx | 36 +++++++ .../Buttons/ButtonWithColor/index.ts | 1 + .../ButtonWithImage.module.scss | 16 +++ .../ButtonWithImage/ButtonWithImage.tsx | 31 ++++++ .../Buttons/ButtonWithImage/index.ts | 1 + .../ButtonWithText/ButtonWithText.module.scss | 14 +++ .../Buttons/ButtonWithText/ButtonWithText.tsx | 35 +++++++ .../Buttons/ButtonWithText/index.ts | 1 + src/components/Buttons/Buttons.module.scss | 66 ------------- .../Buttons/FavoriteButton/FavoriteButton.tsx | 25 +++++ .../Buttons/FavoriteButton/index.ts | 1 + .../Buttons/MainButton/MainButton.module.scss | 29 ++++++ .../Buttons/MainButton/MainButton.tsx | 28 ++++++ src/components/Buttons/MainButton/index.ts | 1 + src/components/Buttons/RoundButton.tsx | 46 --------- src/components/Buttons/WideButton.tsx | 26 ----- src/components/Main/Main.scss | 17 ++-- .../MainBannerSlider/MainBannerSlider.scss | 4 +- src/components/Main/PhoneCard/PhoneCard.tsx | 7 +- .../ProductActions/ProductActions.module.scss | 4 + .../ProductActions/ProductActions.tsx | 20 ++++ src/components/ProductActions/index.ts | 1 + .../VariantsActions.module.scss | 27 ++++- .../VariantsActions/VariantsActions.tsx | 66 ++++++++++++- .../VariantsBlock/VariantsBlock.module.scss | 16 +++ .../VariantsBlock/VariantsBlock.tsx | 16 +++ .../components/VariantsBlock/index.ts | 1 + .../ProductDetailsPage/ProductDetailsPage.tsx | 2 +- src/styles/base/_reset.scss | 6 ++ src/styles/base/_typography.scss | 98 +++++++++---------- src/styles/utils/_mixins.scss | 14 --- src/styles/utils/_variables.scss | 37 ++++--- src/utils/constants/colorsMap.json | 22 +++++ src/utils/types/Accessory.ts | 5 +- src/utils/types/ButtonShape.ts | 4 + src/utils/types/ButtonSize.ts | 5 + src/utils/types/Phone.ts | 5 +- src/utils/types/ProductColor.ts | 3 + src/utils/types/Tablet.ts | 5 +- 43 files changed, 587 insertions(+), 249 deletions(-) create mode 100644 src/components/Buttons/Button/Button.module.scss create mode 100644 src/components/Buttons/Button/Button.tsx create mode 100644 src/components/Buttons/Button/index.ts create mode 100644 src/components/Buttons/ButtonWithColor/ButtonWithColor.module.scss create mode 100644 src/components/Buttons/ButtonWithColor/ButtonWithColor.tsx create mode 100644 src/components/Buttons/ButtonWithColor/index.ts create mode 100644 src/components/Buttons/ButtonWithImage/ButtonWithImage.module.scss create mode 100644 src/components/Buttons/ButtonWithImage/ButtonWithImage.tsx create mode 100644 src/components/Buttons/ButtonWithImage/index.ts create mode 100644 src/components/Buttons/ButtonWithText/ButtonWithText.module.scss create mode 100644 src/components/Buttons/ButtonWithText/ButtonWithText.tsx create mode 100644 src/components/Buttons/ButtonWithText/index.ts delete mode 100644 src/components/Buttons/Buttons.module.scss create mode 100644 src/components/Buttons/FavoriteButton/FavoriteButton.tsx create mode 100644 src/components/Buttons/FavoriteButton/index.ts create mode 100644 src/components/Buttons/MainButton/MainButton.module.scss create mode 100644 src/components/Buttons/MainButton/MainButton.tsx create mode 100644 src/components/Buttons/MainButton/index.ts delete mode 100644 src/components/Buttons/RoundButton.tsx delete mode 100644 src/components/Buttons/WideButton.tsx create mode 100644 src/components/ProductActions/ProductActions.module.scss create mode 100644 src/components/ProductActions/ProductActions.tsx create mode 100644 src/components/ProductActions/index.ts create mode 100644 src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.module.scss create mode 100644 src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.tsx create mode 100644 src/components/ProductDetails/VariantsActions/components/VariantsBlock/index.ts create mode 100644 src/utils/constants/colorsMap.json create mode 100644 src/utils/types/ButtonShape.ts create mode 100644 src/utils/types/ButtonSize.ts create mode 100644 src/utils/types/ProductColor.ts diff --git a/src/components/Buttons/Button/Button.module.scss b/src/components/Buttons/Button/Button.module.scss new file mode 100644 index 0000000..3244e75 --- /dev/null +++ b/src/components/Buttons/Button/Button.module.scss @@ -0,0 +1,38 @@ +.button { + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &__size { + &--small { + height: 32px; + width: 32px; + min-width: 32px; + } + + &--default { + height: 40px; + width: 40px; + min-width: 40px; + } + + &--large { + height: 48px; + width: 48px; + min-width: 48px; + } + } + + &__shape { + &--circle { + border-radius: 48px; + } + + &--rectangle { + border-radius: 4px; + width: auto; + padding: 8px; + } + } +} diff --git a/src/components/Buttons/Button/Button.tsx b/src/components/Buttons/Button/Button.tsx new file mode 100644 index 0000000..4c45a38 --- /dev/null +++ b/src/components/Buttons/Button/Button.tsx @@ -0,0 +1,36 @@ +import React, { ReactNode } from 'react'; +import styles from './Button.module.scss'; +import classNames from 'classnames'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; +import { ButtonShape } from '../../../utils/types/ButtonShape'; + +type Props = { + children: ReactNode; + className: string; + onClick?: () => void; + size?: ButtonSize; + shape?: ButtonShape; +}; + +export const Button: React.FC = ({ + children, + className, + size = ButtonSize.Default, + shape = ButtonShape.Circle, + onClick = () => {}, +}) => { + return ( + + ); +}; diff --git a/src/components/Buttons/Button/index.ts b/src/components/Buttons/Button/index.ts new file mode 100644 index 0000000..8b166a8 --- /dev/null +++ b/src/components/Buttons/Button/index.ts @@ -0,0 +1 @@ +export * from './Button'; diff --git a/src/components/Buttons/ButtonWithColor/ButtonWithColor.module.scss b/src/components/Buttons/ButtonWithColor/ButtonWithColor.module.scss new file mode 100644 index 0000000..a2e95ac --- /dev/null +++ b/src/components/Buttons/ButtonWithColor/ButtonWithColor.module.scss @@ -0,0 +1,19 @@ +.button-with-color { + border: $button-with-color-border; + overflow: hidden; + padding: 3px; + + &__element { + width: 100%; + height: 100%; + border-radius: 50%; + + &--selected { + border-color: $primary-color; + } + } + + &:hover { + border-color: $icons-color; + } +} diff --git a/src/components/Buttons/ButtonWithColor/ButtonWithColor.tsx b/src/components/Buttons/ButtonWithColor/ButtonWithColor.tsx new file mode 100644 index 0000000..f4d38a2 --- /dev/null +++ b/src/components/Buttons/ButtonWithColor/ButtonWithColor.tsx @@ -0,0 +1,36 @@ +import classNames from 'classnames'; +import { Button } from '../Button'; +import styles from './ButtonWithColor.module.scss'; +import colorsMap from '../../../utils/constants/colorsMap.json'; +import { ProductColor } from '../../../utils/types/ProductColor'; +import React from 'react'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; + +type Props = { + isSelected: boolean; + color: ProductColor; + onClick?: () => void; + size: ButtonSize; +}; + +export const ButtonWithColor: React.FC = ({ + isSelected, + color, + onClick, + size, +}) => { + return ( + + ); +}; diff --git a/src/components/Buttons/ButtonWithColor/index.ts b/src/components/Buttons/ButtonWithColor/index.ts new file mode 100644 index 0000000..43c8179 --- /dev/null +++ b/src/components/Buttons/ButtonWithColor/index.ts @@ -0,0 +1 @@ +export * from './ButtonWithColor'; diff --git a/src/components/Buttons/ButtonWithImage/ButtonWithImage.module.scss b/src/components/Buttons/ButtonWithImage/ButtonWithImage.module.scss new file mode 100644 index 0000000..28409af --- /dev/null +++ b/src/components/Buttons/ButtonWithImage/ButtonWithImage.module.scss @@ -0,0 +1,16 @@ +.button-with-image { + border: $button-border-default; + + &__image { + width: 16px; + height: 16px; + } + + &--selected { + border-color: $elemnts-color; + } + + &:hover { + border-color: $primary-color; + } +} diff --git a/src/components/Buttons/ButtonWithImage/ButtonWithImage.tsx b/src/components/Buttons/ButtonWithImage/ButtonWithImage.tsx new file mode 100644 index 0000000..36e0a3a --- /dev/null +++ b/src/components/Buttons/ButtonWithImage/ButtonWithImage.tsx @@ -0,0 +1,31 @@ +import classNames from 'classnames'; +import { Button } from '../Button'; +import styles from './ButtonWithImage.module.scss'; +import React from 'react'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; + +type Props = { + isSelected: boolean; + path: string; + onClick?: () => void; + size: ButtonSize; +}; + +export const ButtonWithImage: React.FC = ({ + path, + size, + onClick, + isSelected, +}) => { + return ( + + ); +}; diff --git a/src/components/Buttons/ButtonWithImage/index.ts b/src/components/Buttons/ButtonWithImage/index.ts new file mode 100644 index 0000000..be081ef --- /dev/null +++ b/src/components/Buttons/ButtonWithImage/index.ts @@ -0,0 +1 @@ +export * from './ButtonWithImage'; diff --git a/src/components/Buttons/ButtonWithText/ButtonWithText.module.scss b/src/components/Buttons/ButtonWithText/ButtonWithText.module.scss new file mode 100644 index 0000000..423f202 --- /dev/null +++ b/src/components/Buttons/ButtonWithText/ButtonWithText.module.scss @@ -0,0 +1,14 @@ +.button-with-text { + border: $button-with-color-border; + font-weight: 600; + + &--selected { + border-color: $primary-color; + background-color: $primary-color; + color: $white-color; + } + + &:hover { + border-color: $primary-color; + } +} diff --git a/src/components/Buttons/ButtonWithText/ButtonWithText.tsx b/src/components/Buttons/ButtonWithText/ButtonWithText.tsx new file mode 100644 index 0000000..34829bb --- /dev/null +++ b/src/components/Buttons/ButtonWithText/ButtonWithText.tsx @@ -0,0 +1,35 @@ +import classNames from 'classnames'; +import { Button } from '../Button'; +import styles from './ButtonWithText.module.scss'; +import React from 'react'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; +import { ButtonShape } from '../../../utils/types/ButtonShape'; + +type Props = { + isSelected: boolean; + shape: ButtonShape; + label: string; + onClick?: () => void; + size: ButtonSize; +}; + +export const ButtonWithText: React.FC = ({ + shape, + label, + isSelected, + size, + onClick, +}) => { + return ( + + ); +}; diff --git a/src/components/Buttons/ButtonWithText/index.ts b/src/components/Buttons/ButtonWithText/index.ts new file mode 100644 index 0000000..7c6a374 --- /dev/null +++ b/src/components/Buttons/ButtonWithText/index.ts @@ -0,0 +1 @@ +export * from './ButtonWithText'; diff --git a/src/components/Buttons/Buttons.module.scss b/src/components/Buttons/Buttons.module.scss deleted file mode 100644 index edddd9a..0000000 --- a/src/components/Buttons/Buttons.module.scss +++ /dev/null @@ -1,66 +0,0 @@ -.round_button { - height: 32px; - width: 32px; - cursor: pointer; - font-size: 16px; - border-radius: 48px; - border: $button-border-default; - background-color: $button-bg-color; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - border: $button-border-on-hover; - } - - &:active { - color: $button-content-color-on-click; - background-color: $button-bg-color-on-click; - border: $button-border-default; - } - - &__picture { - height: 16px; - width: 16px; - } -} - -.heart_button { - background-color: $button-bg-color; - height: 40px; - width: 40px; - - &:active { - color: $button-content-color-on-click; - background-color: $heart-button-bg-color-on-click; - border: $button-border-default; - } - - &__is_active { - border: $heart-button-border-when-active; - } -} - -.wide_button { - @include wideButtonSizes; - - background-color: $wide-button-bg-color-default; - font-size: 14px; - font-weight: 700; - color: $wide-button-text-color-default; - border-radius: 48px; - border: none; - transition: box-shadow, background-color, 0.1s; - - &:hover { - box-shadow: $wide-button-box-shadow-on-hover; - } - - &:active { - color: $wide-button-text-color-on-click; - border: $wide-button-border-on-click; - background-color: $wide-button-bg-color-on-click; - box-shadow: none; - } -} diff --git a/src/components/Buttons/FavoriteButton/FavoriteButton.tsx b/src/components/Buttons/FavoriteButton/FavoriteButton.tsx new file mode 100644 index 0000000..3f98dc6 --- /dev/null +++ b/src/components/Buttons/FavoriteButton/FavoriteButton.tsx @@ -0,0 +1,25 @@ +import heart from '../../../img/headerIcon/like.png'; +import heartSelected from '../../../img/heartOnClick.png'; +import React, { useState } from 'react'; +import { ButtonWithImage } from '../ButtonWithImage'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; + +type Props = { + size: ButtonSize; +}; + +export const FavoriteButton: React.FC = ({ size }) => { + const isDefaultSelected = false; + const [isSelected, setIsSelected] = useState(isDefaultSelected); + + return ( + { + setIsSelected(!isSelected); + }} + size={size} + path={isSelected ? heartSelected : heart} + isSelected={isSelected} + /> + ); +}; diff --git a/src/components/Buttons/FavoriteButton/index.ts b/src/components/Buttons/FavoriteButton/index.ts new file mode 100644 index 0000000..69ab929 --- /dev/null +++ b/src/components/Buttons/FavoriteButton/index.ts @@ -0,0 +1 @@ +export * from './FavoriteButton'; diff --git a/src/components/Buttons/MainButton/MainButton.module.scss b/src/components/Buttons/MainButton/MainButton.module.scss new file mode 100644 index 0000000..8aecacd --- /dev/null +++ b/src/components/Buttons/MainButton/MainButton.module.scss @@ -0,0 +1,29 @@ +.main-button { + background-color: $wide-button-bg-color-default; + color: $wide-button-text-color-default; + width: 100%; + border-radius: 48px; + border: none; + transition: box-shadow, background-color, 0.1s; + + &__size { + &--default { + height: 40px; + } + + &--large { + height: 48px; + } + } + + &:hover { + box-shadow: $wide-button-box-shadow-on-hover; + } + + &:active { + color: $wide-button-text-color-on-click; + border: $wide-button-border-on-click; + background-color: $wide-button-bg-color-on-click; + box-shadow: none; + } +} diff --git a/src/components/Buttons/MainButton/MainButton.tsx b/src/components/Buttons/MainButton/MainButton.tsx new file mode 100644 index 0000000..5f46652 --- /dev/null +++ b/src/components/Buttons/MainButton/MainButton.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import styles from './MainButton.module.scss'; +import classNames from 'classnames'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; + +type Props = { + onClick?: () => void; + label: string; + size: Exclude; +}; + +export const MainButton: React.FC = ({ + label, + onClick = () => {}, + size, +}) => { + return ( + + ); +}; diff --git a/src/components/Buttons/MainButton/index.ts b/src/components/Buttons/MainButton/index.ts new file mode 100644 index 0000000..5427802 --- /dev/null +++ b/src/components/Buttons/MainButton/index.ts @@ -0,0 +1 @@ +export * from './MainButton'; diff --git a/src/components/Buttons/RoundButton.tsx b/src/components/Buttons/RoundButton.tsx deleted file mode 100644 index 0291382..0000000 --- a/src/components/Buttons/RoundButton.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { useState } from 'react'; -import styles from './Buttons.module.scss'; -import classNames from 'classnames'; -import heartImgOnClick from '../../img/heartOnClick.png'; - -type Props = { - onClick?: () => void; -} & ( - | { buttonName: string; buttonImgPath?: string } - | { buttonImgPath: string; buttonName?: string } -); - -export const RoundButton: React.FC = ({ - buttonName, - buttonImgPath, - onClick = () => {}, -}) => { - const [isClicked, setIsClicked] = useState(false); - - const handleClick = () => { - setIsClicked(!isClicked); - onClick(); - }; - - return ( - - ); -}; diff --git a/src/components/Buttons/WideButton.tsx b/src/components/Buttons/WideButton.tsx deleted file mode 100644 index 0a31ad9..0000000 --- a/src/components/Buttons/WideButton.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import styles from './Buttons.module.scss'; - -type Props = { - onClick?: () => void; - buttonTitle: string; - width?: number; - height?: number; -}; - -export const WideButton: React.FC = ({ - buttonTitle, - height, - width, - onClick = () => {}, -}) => { - return ( - - ); -}; diff --git a/src/components/Main/Main.scss b/src/components/Main/Main.scss index 7cada0a..02d814c 100644 --- a/src/components/Main/Main.scss +++ b/src/components/Main/Main.scss @@ -98,6 +98,9 @@ &__button { height: 32px; width: 32px; + display: flex; + justify-content: center; + align-items: center; cursor: pointer; font-size: 16px; border-radius: 48px; @@ -165,7 +168,9 @@ &:hover { cursor: pointer; - transition: box-shadow 1.6s, transform 0.6s; + transition: + box-shadow 1.6s, + transform 0.6s; transform: scale(101%); } } @@ -219,16 +224,6 @@ } } - &__interactive-part { - margin-top: auto; - display: flex; - justify-content: space-between; - - & :nth-child(n) { - margin: 0; - padding: 0; - } - } &__inform { margin-top: auto; } diff --git a/src/components/Main/MainBannerSlider/MainBannerSlider.scss b/src/components/Main/MainBannerSlider/MainBannerSlider.scss index 82d8cdf..2de9a1d 100644 --- a/src/components/Main/MainBannerSlider/MainBannerSlider.scss +++ b/src/components/Main/MainBannerSlider/MainBannerSlider.scss @@ -74,7 +74,9 @@ // background-color: $button-bg-color-on-click; // } @include onTablet { - display: block; + display: flex; + justify-content: center; + align-items: center; } } diff --git a/src/components/Main/PhoneCard/PhoneCard.tsx b/src/components/Main/PhoneCard/PhoneCard.tsx index 33a2996..8163156 100644 --- a/src/components/Main/PhoneCard/PhoneCard.tsx +++ b/src/components/Main/PhoneCard/PhoneCard.tsx @@ -1,10 +1,8 @@ import React from 'react'; -import { RoundButton } from '../../Buttons/RoundButton'; -import { WideButton } from '../../Buttons/WideButton'; -import heartImgDefault from '../../../img/headerIcon/like.png'; import { useLocation, useNavigate } from 'react-router-dom'; import { BASE_URL } from '../../../api/api'; import { UnionProduct } from '../../../utils/types/UnionProduct'; +import { ProductActions } from '../../ProductActions'; type Props = { item: UnionProduct; @@ -48,8 +46,7 @@ export const PhoneCard: React.FC = ({ item }) => {
- - +
diff --git a/src/components/ProductActions/ProductActions.module.scss b/src/components/ProductActions/ProductActions.module.scss new file mode 100644 index 0000000..efd6b9a --- /dev/null +++ b/src/components/ProductActions/ProductActions.module.scss @@ -0,0 +1,4 @@ +.product-actions-block { + display: flex; + gap: 8px; +} diff --git a/src/components/ProductActions/ProductActions.tsx b/src/components/ProductActions/ProductActions.tsx new file mode 100644 index 0000000..007f251 --- /dev/null +++ b/src/components/ProductActions/ProductActions.tsx @@ -0,0 +1,20 @@ +import { MainButton } from '../Buttons/MainButton'; +import styles from './ProductActions.module.scss'; +import React from 'react'; +import { FavoriteButton } from '../Buttons/FavoriteButton'; +import { ButtonSize } from '../../utils/types/ButtonSize'; + +type Props = { + size?: Exclude; +}; + +export const ProductActions: React.FC = ({ + size = ButtonSize.Default, +}) => { + return ( +
+ + +
+ ); +}; diff --git a/src/components/ProductActions/index.ts b/src/components/ProductActions/index.ts new file mode 100644 index 0000000..4ae950d --- /dev/null +++ b/src/components/ProductActions/index.ts @@ -0,0 +1 @@ +export * from './ProductActions'; diff --git a/src/components/ProductDetails/VariantsActions/VariantsActions.module.scss b/src/components/ProductDetails/VariantsActions/VariantsActions.module.scss index fa14f50..e99b93b 100644 --- a/src/components/ProductDetails/VariantsActions/VariantsActions.module.scss +++ b/src/components/ProductDetails/VariantsActions/VariantsActions.module.scss @@ -1,4 +1,27 @@ .variants-block { - background-color: yellow; - height: 464px; + max-width: 320px; + + &__price { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 16px; + + h2 { + font-size: pxToRem(32); + } + + p { + color: $secondary-color; + text-decoration: line-through; + font-size: pxToRem(22); + } + } + + &__line { + height: 1px; + background-color: $elemnts-color; + margin-top: 24px; + margin-bottom: 24px; + } } diff --git a/src/components/ProductDetails/VariantsActions/VariantsActions.tsx b/src/components/ProductDetails/VariantsActions/VariantsActions.tsx index bf05623..149c835 100644 --- a/src/components/ProductDetails/VariantsActions/VariantsActions.tsx +++ b/src/components/ProductDetails/VariantsActions/VariantsActions.tsx @@ -1,5 +1,13 @@ import React from 'react'; import styles from './VariantsActions.module.scss'; +import { Link } from 'react-router-dom'; +import { ProductActions } from '../../ProductActions'; +import { VariantsBlock } from './components/VariantsBlock'; +import { ButtonWithColor } from '../../Buttons/ButtonWithColor'; +import { ButtonWithText } from '../../Buttons/ButtonWithText'; +import { ProductColor } from '../../../utils/types/ProductColor'; +import { ButtonSize } from '../../../utils/types/ButtonSize'; +import { ButtonShape } from '../../../utils/types/ButtonShape'; type Props = { capacityAvailable: string[]; @@ -15,6 +23,60 @@ type Props = { namespaceId: string; }; -export const VariantsActions: React.FC = () => { - return
Variants Actions
; +export const VariantsActions: React.FC = ({ + colorsAvailable, + color, + namespaceId, + capacity, + capacityAvailable, + priceRegular, + priceDiscount, +}) => { + return ( +
+ + {colorsAvailable.map(colorItem => { + return ( + + + + ); + })} + +
+ + {capacityAvailable.map(capacityItem => { + return ( + + + + ); + })} + +
+
+

${priceRegular}

+

${priceDiscount}

+
+
+ +
+
+
+ ); }; diff --git a/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.module.scss b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.module.scss new file mode 100644 index 0000000..65efda8 --- /dev/null +++ b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.module.scss @@ -0,0 +1,16 @@ +.variants-block { + color: $secondary-color; + font-size: pxToRem(12); + font-weight: 600; + line-height: 15px; + + &__title { + margin-bottom: 8px; + } + + &__items { + display: flex; + gap: 8px; + margin-bottom: 24px; + } +} diff --git a/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.tsx b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.tsx new file mode 100644 index 0000000..c13b8ad --- /dev/null +++ b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/VariantsBlock.tsx @@ -0,0 +1,16 @@ +import React, { ReactNode } from 'react'; +import styles from './VariantsBlock.module.scss'; + +type Props = { + title: string; + children: ReactNode; +}; + +export const VariantsBlock: React.FC = ({ title, children }) => { + return ( +
+

{title}

+
{children}
+
+ ); +}; diff --git a/src/components/ProductDetails/VariantsActions/components/VariantsBlock/index.ts b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/index.ts new file mode 100644 index 0000000..cfc3942 --- /dev/null +++ b/src/components/ProductDetails/VariantsActions/components/VariantsBlock/index.ts @@ -0,0 +1 @@ +export * from './VariantsBlock'; diff --git a/src/pages/ProductDetailsPage/ProductDetailsPage.tsx b/src/pages/ProductDetailsPage/ProductDetailsPage.tsx index a97254b..7bc2ae6 100644 --- a/src/pages/ProductDetailsPage/ProductDetailsPage.tsx +++ b/src/pages/ProductDetailsPage/ProductDetailsPage.tsx @@ -55,7 +55,7 @@ export const ProductDetailsPage = () => { .finally(() => { setIsLoading(false); }); - }, [setIsLoading, setProduct]); + }, [setIsLoading, setProduct, productId]); if (isLoading) { return ( diff --git a/src/styles/base/_reset.scss b/src/styles/base/_reset.scss index 012e78e..16b8a58 100644 --- a/src/styles/base/_reset.scss +++ b/src/styles/base/_reset.scss @@ -1,4 +1,6 @@ body, +hr, +button, h1, h2, h3, @@ -19,3 +21,7 @@ a { padding-inline-start: 0; padding-inline-end: 0; } + +button { + background-color: transparent; +} diff --git a/src/styles/base/_typography.scss b/src/styles/base/_typography.scss index 2e43733..9900645 100644 --- a/src/styles/base/_typography.scss +++ b/src/styles/base/_typography.scss @@ -5,86 +5,84 @@ html { font-family: $font-family; } -h1, -h2 { - letter-spacing: -0.01em; +button { + font-family: $font-family; } -h1, -h2, -h3 { +p { + font-size: pxToRem(14); + font-weight: 600; + line-height: 21px; +} + +.small { + font-size: pxToRem(12); + font-weight: 700; + line-height: 15px; +} + +.uppercase { + font-size: pxToRem(12); font-weight: 800; + line-height: 11px; + letter-spacing: 0.04em; + text-transform: uppercase; } -h1 { - font-size: pxToRem(48); - line-height: 56px; +.button { + font-size: pxToRem(14); + font-weight: 700; } -h2 { +h1 { font-size: pxToRem(32); line-height: 41px; + letter-spacing: -0.01em; + font-weight: 800; } -h3 { +h2 { font-size: pxToRem(22); - line-height: 30px; + line-height: 31px; + letter-spacing: 0; + font-weight: 800; } -h4 { +h3 { font-size: pxToRem(20); + line-height: 26px; + letter-spacing: 0; font-weight: 700; - line-height: 25px; } -p { - font-size: pxToRem(14); - font-weight: 600; - line-height: 21px; - - &.small { - font-size: pxToRem(12); - font-weight: 700; - line-height: 15px; - } - - &.uppercase { - font-size: pxToRem(12); - font-weight: 800; - line-height: 11px; - letter-spacing: 0.04em; - text-transform: uppercase; - } -} - -.button { - font-size: pxToRem(14); +h4 { + font-size: pxToRem(16); + line-height: 20px; + letter-spacing: 0; font-weight: 700; } -@include onMobile { +@include onTablet { h1 { - font-size: pxToRem(32); - line-height: 41px; + font-size: pxToRem(48); + line-height: 56px; } h2 { - font-size: pxToRem(22); - line-height: 30px; - } - - h3, - h4 { - font-weight: 700; + font-size: pxToRem(32); + line-height: 41px; + letter-spacing: -0.01em; } h3 { - font-size: pxToRem(20); - line-height: 25px; + font-size: pxToRem(22); + line-height: 31px; + letter-spacing: 0; + font-weight: 800; } h4 { - font-size: pxToRem(16); - line-height: 20px; + font-size: pxToRem(20); + line-height: 26px; } } diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss index b56b158..076a531 100644 --- a/src/styles/utils/_mixins.scss +++ b/src/styles/utils/_mixins.scss @@ -80,20 +80,6 @@ // } } -@mixin wideButtonSizes() { - @include onMobile { - width: 100px; - } - - @include onTablet { - width: 125px; - } - - @include onDesktop { - width: 160px; - } -} - @mixin swiperSizes() { @include onMobile { width: 288px; diff --git a/src/styles/utils/_variables.scss b/src/styles/utils/_variables.scss index 9d9f4bd..cd5cd1c 100644 --- a/src/styles/utils/_variables.scss +++ b/src/styles/utils/_variables.scss @@ -1,24 +1,5 @@ @import './mixins.scss'; -$button-bg-color: #fff; -$button-border-default: 1px solid #b4bdc3; -$button-border-on-hover: 1px solid #0f0f11; -$button-content-color-on-click: #fff; -$button-bg-color-on-click: #0f0f11; - -$wide-button-bg-color-default: #4219d0; -$wide-button-bg-color-on-click: #fff; -$wide-button-text-color-default: #fff; -$wide-button-text-color-on-click: #4219d0; -$wide-button-box-shadow-on-hover: 0px 3px 13px 0px #17203166; -$wide-button-border-on-click: 1px solid #e2e6e9; - -$heart-button-bg-color-on-click: #fff; -$heart-button-border-when-active: 1px solid #e2e6e9; - -$slide-preview-default-border: 1px solid #E2E6E9; -$slide-preview-active-hover-border: 1px solid #0F0F11; - $accent-color: #4219d0; $secondary-accent-color: #f4ba47; $primary-color: #0f0f11; @@ -33,6 +14,24 @@ $button-hover-shadow: 0px 1px 13px 0px #17203166; $font-family: 'Montserrat', sans-serif; $base-font-size: 14; +$button-bg-color: #fff; +$button-border-default: 1px solid #b4bdc3; +$button-border-on-hover: 1px solid #0f0f11; +$button-content-color-on-click: #fff; +$button-bg-color-on-click: #0f0f11; + +$button-with-color-border: 1px solid $elemnts-color; + +$wide-button-bg-color-default: #4219d0; +$wide-button-bg-color-on-click: #fff; +$wide-button-text-color-default: #fff; +$wide-button-text-color-on-click: #4219d0; +$wide-button-box-shadow-on-hover: 0px 3px 13px 0px #17203166; +$wide-button-border-on-click: 1px solid #e2e6e9; + +$slide-preview-default-border: 1px solid #e2e6e9; +$slide-preview-active-hover-border: 1px solid #0f0f11; + $header-height: 48px; @include onDesktop { diff --git a/src/utils/constants/colorsMap.json b/src/utils/constants/colorsMap.json new file mode 100644 index 0000000..88e72ee --- /dev/null +++ b/src/utils/constants/colorsMap.json @@ -0,0 +1,22 @@ +{ + "black": "#000000", + "green": "#A5D6A7", + "yellow": "#F9E75B", + "white": "#FFFFFF", + "purple": "#A57CC5", + "red": "#FF3B30", + "spacegray": "#3A3A3C", + "midnightgreen": "#003A3E", + "gold": "#D8C29D", + "silver": "#C7C7CC", + "rosegold": "#FBB1C1", + "coral": "#FF6F61", + "midnight": "#1C1C1E", + "spaceblack": "#1C1C1E", + "blue": "#007AFF", + "pink": "#FFC0CB", + "graphite": "#4E5452", + "sierrablue": "#A4C8E1", + "skyblue": "#A5D6A7", + "starlight": "#E5E4E2" +} diff --git a/src/utils/types/Accessory.ts b/src/utils/types/Accessory.ts index 3c9bef5..3ce34e8 100644 --- a/src/utils/types/Accessory.ts +++ b/src/utils/types/Accessory.ts @@ -1,5 +1,6 @@ import { DeviceDescription } from './DeviceDescription'; import { ProductCategory } from './ProductCategory'; +import { ProductColor } from './ProductColor'; export interface Accessory { id: string; @@ -10,8 +11,8 @@ export interface Accessory { capacity: string; priceRegular: number; priceDiscount: number; - colorsAvailable: string[]; - color: string; + colorsAvailable: ProductColor[]; + color: ProductColor; images: string[]; description: DeviceDescription[]; screen: string; diff --git a/src/utils/types/ButtonShape.ts b/src/utils/types/ButtonShape.ts new file mode 100644 index 0000000..fed82bc --- /dev/null +++ b/src/utils/types/ButtonShape.ts @@ -0,0 +1,4 @@ +export enum ButtonShape { + Circle = 'circle', + Rectangle = 'rectangle', +} diff --git a/src/utils/types/ButtonSize.ts b/src/utils/types/ButtonSize.ts new file mode 100644 index 0000000..aeb2da3 --- /dev/null +++ b/src/utils/types/ButtonSize.ts @@ -0,0 +1,5 @@ +export enum ButtonSize { + Small = 'small', + Default = 'default', + Large = 'large', +} diff --git a/src/utils/types/Phone.ts b/src/utils/types/Phone.ts index 48b4ff5..f7756c0 100644 --- a/src/utils/types/Phone.ts +++ b/src/utils/types/Phone.ts @@ -1,5 +1,6 @@ import { DeviceDescription } from './DeviceDescription'; import { ProductCategory } from './ProductCategory'; +import { ProductColor } from './ProductColor'; export interface Phone { id: string; @@ -10,8 +11,8 @@ export interface Phone { capacity: string; priceRegular: number; priceDiscount: number; - colorsAvailable: string[]; - color: string; + colorsAvailable: ProductColor[]; + color: ProductColor; images: string[]; description: DeviceDescription[]; screen: string; diff --git a/src/utils/types/ProductColor.ts b/src/utils/types/ProductColor.ts new file mode 100644 index 0000000..6b9bc2e --- /dev/null +++ b/src/utils/types/ProductColor.ts @@ -0,0 +1,3 @@ +import colorsMap from './../constants/colorsMap.json'; + +export type ProductColor = keyof typeof colorsMap; diff --git a/src/utils/types/Tablet.ts b/src/utils/types/Tablet.ts index 6c39cfe..43206fe 100644 --- a/src/utils/types/Tablet.ts +++ b/src/utils/types/Tablet.ts @@ -1,5 +1,6 @@ import { DeviceDescription } from './DeviceDescription'; import { ProductCategory } from './ProductCategory'; +import { ProductColor } from './ProductColor'; export interface Tablet { id: string; @@ -10,8 +11,8 @@ export interface Tablet { capacity: string; priceRegular: number; priceDiscount: number; - colorsAvailable: string[]; - color: string; + colorsAvailable: ProductColor[]; + color: ProductColor; images: string[]; description: DeviceDescription[]; screen: string;