-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create individual Photostory page (#331)
* feat: create individual photostory page * feat: create individual photostory page * feat: add new Carousel and Photostory integration * chore: remove unused codes * fix: dynamic tags * fix: redirect to photostory page * fix: add exception handling to rendering * fix: render page 500 on error * refactor: update props name
- Loading branch information
1 parent
8957c9b
commit 8cf9578
Showing
11 changed files
with
568 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,27 @@ | ||
import React from 'react'; | ||
|
||
// libraries | ||
import { Container, Typography } from '@mui/material'; | ||
|
||
import makeStyles from '@mui/styles/makeStyles'; | ||
|
||
// Components | ||
import ArticleCardStack from '../widgets/article/ArticleCardStack'; | ||
|
||
const RecommendedArticles = ({ title }) => { | ||
const RecommendedArticles = ({ articles, title }) => { | ||
const classes = useStyles(); | ||
|
||
return ( | ||
<div className={classes.wrapper}> | ||
<Container> | ||
<div className={classes.titleWrapper}> | ||
<Typography variant='h2' className={classes.title}> | ||
{title} | ||
</Typography> | ||
<div className={classes.underline} /> | ||
</div> | ||
<ArticleCardStack /> | ||
</Container> | ||
<ArticleCardStack articleList={articles.slice(0, 3)} title={title} /> | ||
</div> | ||
); | ||
}; | ||
export default RecommendedArticles; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
wrapper: { | ||
marginTop: '2rem', | ||
marginTop: '1.5rem', | ||
backgroundColor: theme.palette.primary.blue10, | ||
paddingTop: '2rem', | ||
paddingTop: '0.1rem', | ||
paddingBottom: '2rem', | ||
}, | ||
titleWrapper: { | ||
display: 'flex', | ||
marginBottom: '20px', | ||
alignItems: 'center', | ||
justifyContent: 'space-between', | ||
}, | ||
title: { | ||
display: 'inline-block', | ||
width: 'auto', | ||
}, | ||
underline: { | ||
height: '2px', | ||
backgroundColor: 'black', | ||
marginLeft: '40px', | ||
flex: 1, | ||
}, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,24 @@ | ||
import React from 'react'; | ||
|
||
import makeStyles from '@mui/styles/makeStyles'; | ||
import { Typography } from '@mui/material'; | ||
// libraries | ||
import { Container } from '@mui/material'; | ||
|
||
// Components | ||
import PhotoCarousel from '../widgets/PhotoCarousel'; | ||
import Carousel from '../../components/photostory/Carousel'; | ||
import Disclaimer from '../article/Disclaimer'; | ||
import ArticleTags from '../article/Tags'; | ||
|
||
// Placeholder | ||
import { PHOTOSTORY } from '../../assets/placeholder/photostory'; | ||
|
||
const Body = () => { | ||
const classes = useStyles(); | ||
const Body = ({ content, tags }) => { | ||
return ( | ||
<div> | ||
<div className={classes.carouselWrapper}> | ||
<div> | ||
<PhotoCarousel IMAGE={PHOTOSTORY.image} /> | ||
</div> | ||
<div className={classes.textWrapper}> | ||
<Typography variant='body1' className={classes.text}> | ||
{PHOTOSTORY.carousel} | ||
</Typography> | ||
</div> | ||
</div> | ||
<div className={classes.wrapper}> | ||
<> | ||
<Carousel content={content} /> | ||
<Container> | ||
<Disclaimer /> | ||
<ArticleTags tags={PHOTOSTORY.tags} /> | ||
</div> | ||
</div> | ||
<ArticleTags tags={tags} /> | ||
<hr /> | ||
</Container> | ||
</> | ||
); | ||
}; | ||
|
||
export default Body; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
carouselWrapper: { | ||
backgroundColor: theme.palette.secondary.main, | ||
padding: '24px 0px 48px 0px', | ||
[theme.breakpoints.down('sm')]: { | ||
padding: '12px 0px', | ||
}, | ||
}, | ||
textWrapper: { | ||
marginTop: '12px', | ||
display: 'flex', | ||
direction: 'row', | ||
justifyContent: 'center', | ||
[theme.breakpoints.down('sm')]: { | ||
padding: '0px 24px', | ||
justifyContent: 'flex-start', | ||
}, | ||
}, | ||
text: { | ||
color: theme.palette.common.white, | ||
alignSelf: 'center', | ||
}, | ||
wrapper: { | ||
maxWidth: '1280px', | ||
margin: '60px auto 0px auto', | ||
[theme.breakpoints.down('sm')]: { | ||
margin: '40px 16px 0px 24px', | ||
}, | ||
}, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import React, { useState } from 'react'; | ||
import Image from 'next/image'; | ||
import makeStyles from '@mui/styles/makeStyles'; | ||
import { IconButton, Typography, useMediaQuery } from '@mui/material'; | ||
import ArrowLeft from '@mui/icons-material/ArrowCircleLeftOutlined'; | ||
import ArrowRight from '@mui/icons-material/ArrowCircleRightOutlined'; | ||
|
||
// Utils | ||
import STORES from '../../utils/getStores'; | ||
import theme from '../../config/themes/light'; | ||
|
||
const Carousel = ({ content }) => { | ||
const classes = useStyles(); | ||
const length = content.length; | ||
|
||
const [left, setLeft] = useState(length - 1); | ||
const [current, setCurrent] = useState(0); | ||
const [right, setRight] = useState(1); | ||
|
||
const nextSlide = () => { | ||
setLeft(left === length - 1 ? 0 : left + 1); | ||
setCurrent(current === length - 1 ? 0 : current + 1); | ||
setRight(right === length - 1 ? 0 : right + 1); | ||
}; | ||
const prevSlide = () => { | ||
setLeft(left === 0 ? length - 1 : left - 1); | ||
setCurrent(current === 0 ? length - 1 : current - 1); | ||
setRight(right === 0 ? length - 1 : right - 1); | ||
}; | ||
|
||
if (!Array.isArray(content) || content.length <= 0) { | ||
return null; | ||
} | ||
|
||
const Desktop = useMediaQuery(theme.breakpoints.up('sm')); | ||
|
||
return ( | ||
<section className={classes.wrapper}> | ||
<div className={classes.imgContainer}> | ||
{Desktop && ( | ||
<Image | ||
className={classes.sideImage} | ||
src={ | ||
STORES[content[left].media.store] + | ||
encodeURI(content[left].media.storePath) | ||
} | ||
alt='travel image' | ||
width='400px' | ||
height='300px' | ||
objectFit='contain' | ||
/> | ||
)} | ||
<div className={classes.midSlide}> | ||
<Image | ||
className={classes.centreImage} | ||
src={ | ||
STORES[content[current].media.store] + | ||
encodeURI(content[current].media.storePath) | ||
} | ||
alt='travel image' | ||
width='600px' | ||
height={Desktop ? '400px' : '700px'} | ||
objectFit='contain' | ||
/> | ||
{content[current].text && ( | ||
<div className={classes.textWrapper}> | ||
<Typography | ||
variant='body2' | ||
textAlign='center' | ||
className={classes.text} | ||
> | ||
{content[current].text} | ||
</Typography> | ||
</div> | ||
)} | ||
</div> | ||
{Desktop && ( | ||
<Image | ||
className={classes.sideImage} | ||
src={ | ||
STORES[content[right].media.store] + | ||
encodeURI(content[right].media.storePath) | ||
} | ||
alt='travel image' | ||
width='400px' | ||
height='300px' | ||
objectFit='contain' | ||
/> | ||
)} | ||
</div> | ||
|
||
<span className={classes.navIconWrapper}> | ||
<IconButton | ||
className={classes.navIcon} | ||
onClick={prevSlide} | ||
size='large' | ||
> | ||
<ArrowLeft /> | ||
</IconButton> | ||
<IconButton | ||
className={classes.navIcon} | ||
onClick={nextSlide} | ||
size='large' | ||
> | ||
<ArrowRight /> | ||
</IconButton> | ||
</span> | ||
</section> | ||
); | ||
}; | ||
|
||
export default Carousel; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
wrapper: { | ||
maxWidth: '100%', | ||
position: 'relative', | ||
backgroundColor: theme.palette.secondary.main, | ||
paddingTop: '0.5rem', | ||
}, | ||
|
||
carousel: { | ||
display: 'flex', | ||
overflowX: 'scroll', | ||
overflowY: 'none', | ||
scrollBehavior: 'smooth', | ||
}, | ||
|
||
imgContainer: { | ||
display: 'flex', | ||
justifyContent: 'center', | ||
marginTop: '1em', | ||
gap: 20, | ||
}, | ||
|
||
centreImage: { | ||
borderRadius: '16px', | ||
}, | ||
|
||
sideImage: { | ||
borderRadius: '16px', | ||
opacity: '0.5', | ||
}, | ||
|
||
midSlide: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
borderRadius: '16px', | ||
}, | ||
|
||
bottomContainer: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
bottom: '3%', | ||
position: 'absolute', | ||
}, | ||
|
||
textWrapper: { | ||
justifyContent: 'justify', | ||
alignItems: 'justify', | ||
marginTop: '15px', | ||
color: theme.palette.common.white, | ||
[theme.breakpoints.down('sm')]: { | ||
paddingLeft: '15px', | ||
paddingRight: '15px', | ||
}, | ||
}, | ||
|
||
navIconWrapper: { | ||
display: 'flex', | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
color: theme.palette.secondary.neutral70, | ||
}, | ||
|
||
navIcon: { | ||
color: theme.palette.secondary.neutral70, | ||
}, | ||
})); |
Oops, something went wrong.