Skip to content

Commit

Permalink
Merge pull request #28 from web-Nearest-car-wash/feature/carwashPage
Browse files Browse the repository at this point in the history
feat(carwashpage): added car wash page, minor edits to components
  • Loading branch information
AliceHab authored Jan 30, 2024
2 parents 3fc0a6a + 2ded25c commit 417064b
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 90 deletions.
Binary file removed src/assets/carWashLogoDefault.jpg
Binary file not shown.
1 change: 0 additions & 1 deletion src/components/App/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import AboutPage from '../../pages/AboutPage/AboutPage';

import Footer from '../Sections/Footer/Footer';
import Header from '../Sections/Header/Header';
import Price from '../Price/Price';

function App() {
return (
Expand Down
1 change: 1 addition & 0 deletions src/components/CardCarWash/CardCarWash.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
align-items: center;
padding: 0;
margin: 0;
color: #252525;
}

.adress {
Expand Down
80 changes: 44 additions & 36 deletions src/components/HeaderCarWash/HeaderCarWash.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import styles from './HeaderCarWash.module.css';
import { selectcarWashesCard } from '../../store/cardCarWashes/cardCarWashes-slice';
import { BASE_URL, POPUP_TEXT } from '../../utils/constants';
import carWashLogoDefault from '../../assets/carWashLogoDefault.jpg';
import avatarPlaceholder from '../../assets/avatarPlaceholder.png';

function HeaderCarWash() {
function HeaderCarWash({ image, name, rating, schedule }) {
// идея рефакторинга: разнести по разным компонентам состояние с галереей и без

const { carWashesCard } = useSelector(selectcarWashesCard);
const imageSource =
carWashesCard.image?.length > 0
? `${BASE_URL}/${
carWashesCard.image.find((image) => image.avatar === true).image
}`
: carWashLogoDefault;
const hasMultipleImages = carWashesCard.image?.length > 1; // из-за отображения галлереи меняется структура шапки
const imageSource = `${BASE_URL}/${
image?.find((currentImage) => currentImage.avatar === true).image
}`;
const hasMultipleImages = image?.length > 1; // из-за отображения галлереи меняется структура шапки

return (
<div
Expand All @@ -27,38 +22,38 @@ function HeaderCarWash() {
<>
<div className={styles.about}>
<div className={styles.info}>
<h1 className={styles.title}>{carWashesCard.name}</h1>
<h1 className={styles.title}>{name}</h1>
<div className={styles.rating}>
<p className={styles.ratingCount}>
{carWashesCard.rating || 'Без оценок'}
</p>
<p className={styles.ratingCount}>{rating || 'Без оценок'}</p>
<div className={styles.ratingStar} />
</div>
<div className={styles.popup}>
<div className={styles.popupText}>{POPUP_TEXT}</div>
</div>
</div>
{carWashesCard.schedule?.open_until_list ? (
<p className={styles.hours}>
{carWashesCard.schedule.open_until_list}
</p>
{schedule?.open_until_list ? (
<p className={styles.hours}>{schedule.open_until_list}</p>
) : (
''
)}
</div>
<div className={styles.gallery}>
<img
src={imageSource}
alt={`Автомойка ${carWashesCard.name}`}
onError={(e) => {
e.currentTarget.src = avatarPlaceholder;
}}
alt={`Автомойка ${name}`}
className={styles.logo}
/>

{carWashesCard.image.map((imageObject, index) => {
{image.map((imageObject, index) => {
if (index === 1 || index === 2) {
return (
<img
key={imageObject.image}
src={`${BASE_URL}/${imageObject.image}`}
alt={`Автомойка ${carWashesCard.name}`}
alt={`Автомойка ${name}`}
className={styles.galleryImage}
/>
);
Expand All @@ -68,13 +63,13 @@ function HeaderCarWash() {
<div className={styles.doubleImageContainer}>
<img
src={`${BASE_URL}/${imageObject.image}`}
alt={`Автомойка ${carWashesCard.name}`}
alt={`Автомойка ${name}`}
className={styles.doubleImages}
/>
{carWashesCard.image[4] && (
{image[4] && (
<img
src={`${BASE_URL}/${carWashesCard.image[4].image}`}
alt={`Автомойка ${carWashesCard.name}`}
src={`${BASE_URL}/${image[4].image}`}
alt={`Автомойка ${name}`}
className={styles.doubleImages}
/>
)}
Expand All @@ -90,25 +85,24 @@ function HeaderCarWash() {
<>
<img
src={imageSource}
alt={`Автомойка ${carWashesCard.name}`}
alt={`Автомойка ${name}`}
className={styles.logo}
onError={(e) => {
e.currentTarget.src = avatarPlaceholder;
}}
/>
<div className={styles.info}>
<h1 className={styles.title}>{carWashesCard.name}</h1>
<h1 className={styles.title}>{name}</h1>
<div className={styles.rating}>
<p className={styles.ratingCount}>
{carWashesCard.rating || 'Без оценок'}
</p>
<p className={styles.ratingCount}>{rating || 'Без оценок'}</p>
<div className={styles.ratingStar} />
</div>
<div className={styles.popup}>
<div className={styles.popupText}>{POPUP_TEXT}</div>
</div>
</div>
{carWashesCard.schedule?.open_until_list ? (
<p className={styles.hours}>
{carWashesCard.schedule.open_until_list}
</p>
{schedule?.open_until_list ? (
<p className={styles.hours}>{schedule.open_until_list}</p>
) : (
''
)}
Expand All @@ -118,4 +112,18 @@ function HeaderCarWash() {
);
}

HeaderCarWash.propTypes = {
image: PropTypes.arrayOf(
PropTypes.shape({
avatar: PropTypes.bool,
image: PropTypes.string.isRequired,
})
),
name: PropTypes.string,
rating: PropTypes.number,
schedule: PropTypes.shape({
open_until_list: PropTypes.string,
}),
};

export default HeaderCarWash;
27 changes: 11 additions & 16 deletions src/components/Price/Price.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import PropTypes from 'prop-types';
import styles from './Price.module.css';
import api from '../../utils/api';

function Price() {
const [cardsService, setCardsService] = useState([]);
const { id } = useParams();

useEffect(() => {
api
.getCarWash(id)
.then((data) => {
setCardsService(data.services);
})
.catch((err) => alert(err));
}, [id]);

function Price({ cardsService }) {
return (
<div className={styles.priceContainer}>
<h2 className={styles.title}>Услуги и цены</h2>
Expand All @@ -32,4 +18,13 @@ function Price() {
);
}

Price.propTypes = {
cardsService: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
price: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
})
).isRequired,
};

export default Price;
2 changes: 1 addition & 1 deletion src/components/Price/Price.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
margin: 0;
padding: 32px 28px;
max-width: 806px;
min-height: 304px;
min-height: fit-content;
background-color: #ffffff;
border-radius: 20px;
}
Expand Down
19 changes: 15 additions & 4 deletions src/components/Sections/Header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import styles from './Header.module.css';
import logo from '../../../assets/logo.svg';

function Header() {
const location = useLocation();

return (
<header className={styles.header}>
<button className={styles.button}>Показать мойку рядом</button>
<img className={styles.logo} alt="logo" src={logo} />
<div className={styles.location}>
<p className={styles.city}>Москва</p>
<div className={styles.wrapper}>
{location.pathname === '/' ? (
<button className={styles.button}>Показать мойку рядом</button>
) : (
<div className={styles.buttonPlaceholder} />
)}
<a href="/">
<img className={styles.logo} alt="logo" src={logo} />
</a>
<div className={styles.location}>
<p className={styles.city}>Москва</p>
</div>
</div>
</header>
);
Expand Down
14 changes: 8 additions & 6 deletions src/components/Sections/Header/Header.module.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
.header {
/* max-width: 1440px; */
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 50px;
background-color: #ececec;
height: 104px;
align-items: center;
box-sizing: border-box;
font-family: 'Roboto';
}

.wrapper {
max-width: 1340px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}

.logo {
width: 345px;
}
Expand Down
25 changes: 16 additions & 9 deletions src/components/TheAdvancedSection/TheAdvancedSection.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import styles from './theAdvancedSection.module.css';
import creditcard from '../../assets/creditcard.svg';
import checkmark from '../../assets/checkmark.svg';
// import certificate from '../../assets/certificate.svg';
import couch from '../../assets/couch.svg';
import discount from '../../assets/discount.svg';
// import wifi from '../../assets/wifi.svg';
import { selectcarWashesCard } from '../../store/cardCarWashes/cardCarWashes-slice';

export default function TheAdvancedSection() {
const { carWashesCard } = useSelector(selectcarWashesCard);
function TheAdvancedSection({ payment, promotions, restRoom }) {
// закомментированы не реализованные на бэке поля

return (
<div className={styles.container}>
Expand All @@ -24,8 +23,8 @@ export default function TheAdvancedSection() {
<p className={styles.text}>Способы оплаты</p>
</div>
<div className={styles.right}>
{carWashesCard ? (
<p className={styles.text}>{carWashesCard.payment?.join('/')}</p>
{payment ? (
<p className={styles.text}>{payment?.join('/')}</p>
) : (
<p className={styles.text}>Услуг не найдено</p>
)}
Expand All @@ -42,8 +41,8 @@ export default function TheAdvancedSection() {
<p className={styles.text}>Акции</p>
</div>
<div className={styles.right}>
{carWashesCard.promotions?.length > 0 ? (
carWashesCard.promotions.map((promotion) => (
{promotions?.length > 0 ? (
promotions.map((promotion) => (
<p key={promotion} className={styles.text}>
{promotion}
</p>
Expand Down Expand Up @@ -80,7 +79,7 @@ export default function TheAdvancedSection() {
<p className={styles.text}>Комната отдыха</p>
</div>
<div className={styles.right}>
{carWashesCard?.rest_room ? (
{restRoom ? (
<img src={checkmark} className={styles.icon} alt="Галочка" />
) : (
<p className={styles.text}>Услуг не найдено</p>
Expand All @@ -103,3 +102,11 @@ export default function TheAdvancedSection() {
</div>
);
}

TheAdvancedSection.propTypes = {
payment: PropTypes.arrayOf(PropTypes.string),
promotions: PropTypes.arrayOf(PropTypes.string),
restRoom: PropTypes.bool,
};

export default TheAdvancedSection;
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
.container {
max-width: 807px;
width: 100%;
min-height: 653px;
height: 100%;
height: fit-content;
display: flex;
gap: 20px;
flex-direction: column;
Expand Down
Loading

0 comments on commit 417064b

Please sign in to comment.