diff --git a/client/components/Header/index.js b/client/components/Header/index.js index acd5c04..9554ad5 100644 --- a/client/components/Header/index.js +++ b/client/components/Header/index.js @@ -1,5 +1,4 @@ import React from 'react'; -import logo from '../../assets/logo.svg'; const headerStyle = { height: '65px', @@ -19,7 +18,7 @@ const imageStyle = { const Header = () => { return (
- logo +

App Sample

); diff --git a/client/components/LazyImage/index.js b/client/components/LazyImage/index.js new file mode 100644 index 0000000..b6059cd --- /dev/null +++ b/client/components/LazyImage/index.js @@ -0,0 +1,58 @@ +import React, { useState } from 'react'; +import { string, object } from 'prop-types'; +import useIntersect from '@jackyef/use-intersect'; + +const optionsData = { + root: null, + rootMargin: '0px', + threshold: [0, 0, 0, 0], +}; + +const LazyImage = ({ alt, src, style, width, height }) => { + const placeholder = `https://res.cloudinary.com/irfan-maulana-tkpd/image/fetch/c_fill,g_auto:face,h_50,fl_force_strip.progressive/f_webp/${encodeURIComponent( + 'https://res.cloudinary.com/irfan-maulana-tkpd/image/upload/v1597041453/placeholder_qzxxc6.png', + )}`; + + const [showSrc, setShowSrc] = useState(placeholder); + const [loaded, setLoaded] = useState(false); + + const onIntersect = () => { + const imgObj = new Image(); + imgObj.onload = () => { + setLoaded(true); + } + imgObj.src = src; + setShowSrc(src); + }; + + const targetRef = useIntersect(onIntersect, optionsData, true); + + return ( + {alt} + ); +}; + +LazyImage.propTypes = { + alt: string.isRequired, + height: string, + src: string, + style: object, + width: string, +}; + +LazyImage.defaultProps = { + height: undefined, + src: '', + style: {}, + width: '100%', +}; + +export default LazyImage; diff --git a/client/routes/Home/components/index.js b/client/routes/Home/components/index.js index 30b36b0..6407591 100644 --- a/client/routes/Home/components/index.js +++ b/client/routes/Home/components/index.js @@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'; import Header from '../../../components/Header'; import RatingReview from '../../../components/RatingReview'; +import LazyImage from '../../../components/LazyImage'; import Footer from '../../../components/Footer'; const productWrapper = { @@ -21,15 +22,14 @@ const productCard = { marginBottom: '10px', boxShadow: '0 1px 6px 0 rgb(255 255 255 / 0.32)', borderRadius: '8px', - textDecoration: 'none', - color: '#fff', - cursor: 'pointer', + textDecoration: 'none', + color: '#fff', + cursor: 'pointer', }; const productImg = { width: '100%', height: '130px', - objectFit: 'cover', borderRadius: '8px 8px 0 0', }; @@ -43,8 +43,8 @@ const productName = { }; const productPrice = { - color: '#ff5722', - fontSize: '14px', + color: '#ff5722', + fontSize: '14px', marginTop: '5px', }; @@ -53,12 +53,14 @@ const { API_URL } = process.env; function Home() { const { data, loading } = useData(`${API_URL}/products`, {}, { method: 'GET' }, { ssr: true }); - const getResizedImage = (imageUrl) => { - if (imageUrl) { - return `https://res.cloudinary.com/irfan-maulana-tkpd/image/fetch/c_fill,g_auto:face,h_200,fl_force_strip.progressive/f_webp/${encodeURIComponent(imageUrl)}`; - } - return ''; - }; + const getResizedImage = imageUrl => { + if (imageUrl) { + return `https://res.cloudinary.com/irfan-maulana-tkpd/image/fetch/c_fill,g_auto:face,h_130,fl_force_strip.progressive/f_webp/${encodeURIComponent( + imageUrl, + )}`; + } + return ''; + }; return (
@@ -68,7 +70,8 @@ function Home() {
{data.data.map(item => ( - {item.name} + +
{item.name}
{item.price}
diff --git a/client/styles/index.scss b/client/styles/index.scss index 81dded2..97fddce 100644 --- a/client/styles/index.scss +++ b/client/styles/index.scss @@ -19,3 +19,13 @@ code { border-left: 1px solid #fff; border-right: 1px solid #fff; } + +.img { + transition: filter .5s linear; +} +.img.img--loading { + filter: blur(1px); +} +.img.img--loaded { + filter: blur(0); +} diff --git a/package.json b/package.json index 059be52..ba6bf97 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@babel/polyfill": "^7.10.4", + "@jackyef/use-intersect": "^0.0.6", "@loadable/babel-plugin": "5.12.0", "@loadable/component": "5.12.0", "@loadable/server": "5.12.0", diff --git a/public/index.client.html b/public/index.client.html index a40e0cd..15d0569 100644 --- a/public/index.client.html +++ b/public/index.client.html @@ -6,7 +6,7 @@ - + @@ -19,6 +19,7 @@
+