Skip to content

Commit 5f41b59

Browse files
committed
optimise images, fix user avatar, add year search
1 parent c6093b6 commit 5f41b59

File tree

14 files changed

+141
-34
lines changed

14 files changed

+141
-34
lines changed

components/Cards/VehicleCard.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import React, { useState, useRef } from 'react'
22
import find from 'lodash/find'
3+
import head from 'lodash/head'
4+
import get from 'lodash/get'
35
import classNames from 'classnames'
6+
import { LazyLoadImage } from 'react-lazy-load-image-component'
47
import { useTranslation } from 'react-i18next'
5-
import Image from 'next/image'
68
import {
79
FiMapPin,
810
FiMoreVertical,
@@ -17,6 +19,8 @@ import {
1719
getVehicleTitle,
1820
formatVehicleMainLabel,
1921
formatPriceWithDiscount,
22+
parseCloudinaryUrl,
23+
placeholderImageUrl,
2024
} from '~utils/helpers'
2125
import VehicleCardScreen from './VehicleCardScreen/VehicleCardScreen'
2226
import HeartAnimation from '~public/animations/heart.json'
@@ -59,7 +63,7 @@ const VehicleCard = ({
5963
const [overlayActive, setOverlayActive] = useState(false)
6064
const { isMobile } = useViewport()
6165
useOutsideClick({ ref, isOpen: overlayActive, setOpen: setOverlayActive })
62-
const image = find(images, (image) => image.order === 0)
66+
const image = find(images, (image) => image.order === 0) || head(images)
6367
const { t } = useTranslation()
6468
const vehicleBodyYear = formatVehicleMainLabel(bodyType, regDate, t, isMobile)
6569
const vehicleMileage = isMobile ? mileage : formatMillage(mileage, t)
@@ -95,6 +99,7 @@ const VehicleCard = ({
9599
}
96100

97101
const finalPrice = formatPriceWithDiscount(price, discountPercentage)
102+
const imageUrl = parseCloudinaryUrl(get(image, 'url'))
98103

99104
return (
100105
<div className={styles.container} ref={ref}>
@@ -122,10 +127,11 @@ const VehicleCard = ({
122127
href={`/listing/${listingId}`}
123128
className={styles.imageLink}
124129
>
125-
<img
126-
src={image?.url || ''}
127-
draggable="false"
128-
alt={t('vehicle.vehicle')}
130+
<LazyLoadImage
131+
alt={vehicleTitle}
132+
effect="blur"
133+
src={imageUrl}
134+
placeholderSrc={placeholderImageUrl}
129135
/>
130136
</BaseButton>
131137
</div>

components/Cards/VehicleCard.module.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
overflow: hidden;
3535
border-top-right-radius: 8px;
3636
.imageLink {
37+
span {
38+
width: 100%;
39+
height: 100%;
40+
}
3741
&:hover {
3842
img {
3943
transform: scale(1.1);

components/Image/ImageCarousel.module.scss

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
height: 100%;
2525
object-fit: cover;
2626
}
27+
> span {
28+
width: 100%;
29+
height: 100%;
30+
}
2731
.carousel {
2832
position: absolute;
2933

@@ -55,7 +59,10 @@
5559
color: white;
5660
}
5761
}
58-
62+
span {
63+
width: 100%;
64+
height: 100%;
65+
}
5966
img {
6067
border-radius: $border-radius-medium;
6168
border: 1px solid $color-light-gray;

components/Image/ImageCarousel.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import React, { useState } from 'react'
22
import { map, orderBy, get } from 'lodash'
3+
import { useTranslation } from 'react-i18next'
4+
/* @ts-ignore */
5+
import { LazyLoadImage } from 'react-lazy-load-image-component'
36
import { BaseButton } from '../'
47
import { useDispatch } from 'react-redux'
58
import useViewport from '../../hooks/useViewport'
@@ -12,6 +15,7 @@ import styles from './ImageCarousel.module.scss'
1215
import modalTypes from '../../consts/modals'
1316

1417
import ImageType from '../../types/image'
18+
import { parseCloudinaryUrl, placeholderImageUrl } from '~/utils/helpers'
1519

1620
type Props = {
1721
images: ImageType[]
@@ -21,7 +25,7 @@ const ImageCarousel: React.FunctionComponent<Props> = ({ images }) => {
2125
const orderedImages = orderBy(images, (image) => image.order)
2226
const [activeImage, setActiveImage] = useState(0)
2327
const { isMobile } = useViewport()
24-
28+
const { t } = useTranslation()
2529
const dispatch = useDispatch()
2630

2731
const paginate = () => {
@@ -31,11 +35,13 @@ const ImageCarousel: React.FunctionComponent<Props> = ({ images }) => {
3135
}
3236
return (
3337
<div className={styles.container}>
34-
<img
35-
src={get(orderedImages, `${activeImage}.url`, '')}
36-
alt="Image"
37-
draggable="false"
38+
<LazyLoadImage
39+
placeholderSrc={placeholderImageUrl}
40+
src={parseCloudinaryUrl(get(orderedImages, `${activeImage}.url`))}
41+
effect="blur"
42+
alt={t('vehicle.vehicle')}
3843
/>
44+
3945
{/* @ts-ignore */}
4046
<button
4147
className={styles.expandButton}
@@ -50,13 +56,14 @@ const ImageCarousel: React.FunctionComponent<Props> = ({ images }) => {
5056

5157
<div className={styles.carousel}>
5258
{map(orderedImages, ({ url }, key) => (
53-
<img
59+
<LazyLoadImage
5460
key={key}
55-
src={url}
61+
placeholderSrc={placeholderImageUrl}
62+
src={parseCloudinaryUrl(url)}
63+
effect="blur"
5664
className={classNames(activeImage === key && styles.active)}
57-
alt="Image"
58-
draggable="false"
5965
onClick={() => setActiveImage(key)}
66+
alt={t('vehicle.vehicle')}
6067
/>
6168
))}
6269
{isMobile && (

components/Modals/ImageListModal.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
.container {
44
display: flex;
55
flex-direction: column;
6+
min-width: 40vw;
67
img {
78
width: 100vw;
89
height: calc(92vh - 34px);

components/User/Avatar.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
height: 44px;
1212
object-fit: cover;
1313
border-radius: 50%;
14-
margin-right: spacing(1);
1514
}
1615
}
1716
a {
17+
margin-left: spacing(1);
1818
color: $color-primary;
1919
font-size: $font-size-p;
2020
font-family: $font-family-secondary;

components/User/Avatar.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react'
2+
import { parseCloudinaryUrl } from '~/utils/helpers'
23
import { BaseButton } from '../'
34
import styles from './Avatar.module.scss'
5+
import UserAvatar from './UserAvatar'
46

57
type Props = {
68
title?: string
@@ -15,17 +17,14 @@ const Avatar: React.FunctionComponent<Props> = ({
1517
username,
1618
userId,
1719
}) => {
20+
const src = parseCloudinaryUrl(avatarSrc)
21+
const hasImageSrc = src && src !== ''
1822
return (
1923
<div className={styles.container}>
2024
{title && <p>{title}</p>}
2125
<div className={styles.user}>
22-
<img
23-
src={
24-
avatarSrc ||
25-
'https://res.cloudinary.com/forautocloud/image/upload/v1614110570/static/Screenshot_2021-02-23_at_22.02.19_bssgk8.png'
26-
}
27-
alt={username}
28-
/>
26+
{hasImageSrc && <img src={src} alt={username} />}
27+
{!hasImageSrc && <UserAvatar username={username} />}
2928
{/* @ts-ignore */}
3029
<BaseButton
3130
label={username}

components/User/UserAvatar.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ import { currentUserSelector } from '../../store/auth/selectors'
66
import styles from './UserAvatar.module.scss'
77

88
type Props = {
9-
username: string
9+
username?: string
1010
fullScreen?: boolean
1111
}
1212

13-
const UserAvatar:React.FunctionComponent<Props> = ({ username, fullScreen }) => {
13+
const UserAvatar: React.FunctionComponent<Props> = ({
14+
username,
15+
fullScreen,
16+
}) => {
1417
const currentUser = useSelector(currentUserSelector)
15-
const currentFirstName = get(currentUser, 'profile.firstName', '?')
18+
const firstName = get(currentUser, 'profile.firstName')
19+
const usernameFallback = get(currentUser, 'profile.username')
20+
const nameFallback =
21+
firstName && firstName !== '' ? firstName : usernameFallback
1622
return (
17-
<div className={classNames(styles.container, fullScreen && styles.fullScreen)}>
23+
<div
24+
className={classNames(styles.container, fullScreen && styles.fullScreen)}
25+
>
1826
<span>
19-
{username ? username.substring(0, 1) : currentFirstName.substring(0, 1)}
27+
{username ? username.substring(0, 1) : nameFallback.substring(0, 1)}
2028
</span>
2129
</div>
2230
)

components/VehicleOfTheDay/VehicleOfTheDay.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ const VehicleOfTheDay: React.FunctionComponent<VehicleOfTheDayProps> = ({
131131
height: '19vw',
132132
},
133133
}
134-
console.log('votd', listing)
135134
useEffect(() => {
136135
setImageMaximized(isMobile)
137136
}, [isMobile])

package-lock.json

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)