-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(Wallet): Vertical Slide #449
Changes from 19 commits
fa2b39c
2d80dab
480cf9c
8b2e74e
9abc451
9c0ab22
d9382bc
67c7719
9055bba
1b6bbd9
d2ec259
b36e33c
8c9b91f
a9eea1d
4d992cb
19941b9
2dee682
58adbcb
d708139
11c563c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { useEffect, useState } from 'react' | ||
import { ButtonBase, Container, Grid, Typography } from '@mui/material' | ||
import type { BaseBlock } from '@/components/Home/types' | ||
import BracketLeft from '@/public/images/Wallet/VerticalSlide/bracket-left.svg' | ||
import RecoveryIcon from '@/public/images/Wallet/VerticalSlide/recovery.svg' | ||
import ScanIcon from '@/public/images/Wallet/VerticalSlide/scan.svg' | ||
import MultipleKeysIcon from '@/public/images/Wallet/VerticalSlide/multiple-keys.svg' | ||
import BracketRight from '@/public/images/Wallet/VerticalSlide/bracket-right.svg' | ||
import layoutCss from '@/components/common/styles.module.css' | ||
import css from './styles.module.css' | ||
|
||
const VerticalSlide = ({ title, items = [] }: BaseBlock) => { | ||
const [selectedIndex, setSelectedIndex] = useState(0) | ||
|
||
const itemsImages = items.map((item) => item.image) | ||
const icons = [<RecoveryIcon key="recovery" />, <ScanIcon key="scan" />, <MultipleKeysIcon key="multiple-keys" />] | ||
|
||
const handleCardClick = (index: number) => { | ||
setSelectedIndex(index) | ||
} | ||
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: this is somewhat neglible. You can just call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer to leave the click handler |
||
|
||
// Change index every 5 seconds | ||
useEffect(() => { | ||
const interval = setInterval(() => { | ||
setSelectedIndex((prevIndex) => (prevIndex + 1) % items?.length) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I initiate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In which case, we don't need the optional chaining. |
||
}, 5000) | ||
|
||
return () => clearInterval(interval) // Cleanup interval on component unmount | ||
}, [items.length]) | ||
|
||
return ( | ||
<Container className={layoutCss.containerShort}> | ||
<Typography variant="h2" className={css.title}> | ||
{title} | ||
</Typography> | ||
|
||
<Grid container spacing="40px" justifyContent="flex-end"> | ||
<Grid item md={7} className={css.imageItem}> | ||
<div className={css.showInMd}> | ||
<BracketLeft /> | ||
{icons.map((icon, index) => ( | ||
<span key={index} className={index === selectedIndex ? css.selected : undefined}> | ||
{icon} | ||
</span> | ||
))} | ||
<BracketRight /> | ||
</div> | ||
|
||
{itemsImages[selectedIndex] ? ( | ||
<img src={itemsImages[selectedIndex].src} alt={itemsImages[selectedIndex].alt} className={css.image} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can extract |
||
) : null} | ||
</Grid> | ||
|
||
<Grid item xs={12} md={5}> | ||
<div className={css.cardWrapper}> | ||
{items.map((item, index) => { | ||
const { title, text } = item | ||
|
||
return ( | ||
<Grid item key={index} xs={12}> | ||
<ButtonBase | ||
onClick={() => handleCardClick(index)} | ||
disableRipple | ||
className={`${css.card} ${index === selectedIndex ? css.selected : ''}`} | ||
> | ||
<Typography variant="h5">{title}</Typography> | ||
|
||
{text && ( | ||
<Typography color="primary.light" component="div"> | ||
{text} | ||
</Typography> | ||
)} | ||
</ButtonBase> | ||
</Grid> | ||
) | ||
})} | ||
</div> | ||
</Grid> | ||
</Grid> | ||
</Container> | ||
) | ||
} | ||
|
||
export default VerticalSlide |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
.title { | ||
text-align: center; | ||
max-width: 650px; | ||
margin-bottom: 48px; | ||
} | ||
|
||
.image { | ||
height: 300px; | ||
object-fit: contain; | ||
} | ||
|
||
.showInMd { | ||
display: none; | ||
} | ||
|
||
.cardWrapper { | ||
border-radius: 6px; | ||
border: 1px solid var(--mui-palette-border-light); | ||
overflow: hidden; | ||
} | ||
|
||
.card { | ||
border-bottom: 1px solid var(--mui-palette-border-light); | ||
margin-bottom: -1px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
padding: 48px 40px; | ||
text-align: left; | ||
} | ||
|
||
.card.selected::before { | ||
content: ''; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
bottom: 0; | ||
width: 4px; | ||
background-color: var(--mui-palette-primary-main); | ||
} | ||
|
||
.selected { | ||
color: var(--mui-palette-primary-main); | ||
} | ||
|
||
@media (min-width: 900px) { | ||
.title { | ||
margin-bottom: 80px; | ||
} | ||
|
||
.imageItem { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 40px; | ||
} | ||
|
||
.image { | ||
height: 450px; | ||
} | ||
|
||
.showInMd { | ||
display: block; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: we can move this outside of the component.