✨(frontend) add slide feature in the IntroSlider
Avoided installing a dependency for such small piece of code. I've implemented a naive component, which allow users explore the slide presenting key feature of our app. User experience should be ok. However, I might need to optimize image format and loading strategy. First 'raw' iteration, gonna optimize it in the future.
This commit is contained in:
committed by
aleb_the_flash
parent
b06880be15
commit
8516782d79
Binary file not shown.
|
Before Width: | Height: | Size: 177 KiB |
BIN
src/frontend/src/assets/intro-slider/1_solo.png
Normal file
BIN
src/frontend/src/assets/intro-slider/1_solo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 635 KiB |
BIN
src/frontend/src/assets/intro-slider/2_multiple.png
Normal file
BIN
src/frontend/src/assets/intro-slider/2_multiple.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 702 KiB |
BIN
src/frontend/src/assets/intro-slider/3_resume.png
Normal file
BIN
src/frontend/src/assets/intro-slider/3_resume.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 599 KiB |
@@ -1,5 +1,13 @@
|
|||||||
import firstSlide from '@/assets/intro-slider/1.png'
|
import firstSlide from '@/assets/intro-slider/1_solo.png'
|
||||||
import { styled, VStack } from '@/styled-system/jsx'
|
import secondSlide from '@/assets/intro-slider/2_multiple.png'
|
||||||
|
import thirdSlide from '@/assets/intro-slider/3_resume.png'
|
||||||
|
|
||||||
|
import { styled } from '@/styled-system/jsx'
|
||||||
|
import { css } from '@/styled-system/css'
|
||||||
|
import { Button } from '@/primitives'
|
||||||
|
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
const Heading = styled('h2', {
|
const Heading = styled('h2', {
|
||||||
base: {
|
base: {
|
||||||
@@ -32,18 +40,161 @@ const Image = styled('img', {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// todo - refactor it in a proper slider, only displaying a single slide yet
|
const Dot = styled('div', {
|
||||||
|
base: {
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'inline-block',
|
||||||
|
height: '.375rem',
|
||||||
|
margin: '0 .25rem',
|
||||||
|
width: '.375rem',
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
selected: {
|
||||||
|
true: {
|
||||||
|
backgroundColor: '#000091',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
backgroundColor: '#CACAFB',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const Container = styled('div', {
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const ButtonVerticalCenter = styled('div', {
|
||||||
|
base: {
|
||||||
|
marginTop: '10.3125rem',
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const SlideContainer = styled('div', {
|
||||||
|
base: {
|
||||||
|
alignItems: 'stretch',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const Slide = styled('div', {
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.5rem',
|
||||||
|
justifyContent: 'start',
|
||||||
|
minHeight: '550px',
|
||||||
|
minWidth: '200px',
|
||||||
|
width: '22.625rem',
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
visible: {
|
||||||
|
true: {
|
||||||
|
visibility: 'visible',
|
||||||
|
position: 'static',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
visibility: 'hidden',
|
||||||
|
position: 'absolute',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
type Slide = {
|
||||||
|
key: string
|
||||||
|
img: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo - optimize how images are imported
|
||||||
|
const SLIDES: Slide[] = [
|
||||||
|
{
|
||||||
|
key: 'slide1',
|
||||||
|
img: firstSlide,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'slide2',
|
||||||
|
img: secondSlide,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'slide3',
|
||||||
|
img: thirdSlide,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export const IntroSlider = () => {
|
export const IntroSlider = () => {
|
||||||
|
const [slideIndex, setSlideIndex] = useState(0)
|
||||||
|
const { t } = useTranslation('home', { keyPrefix: 'introSlider' })
|
||||||
|
const NUMBER_SLIDES = SLIDES.length
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container>
|
||||||
<Image src={firstSlide} alt="" />
|
<div
|
||||||
<VStack justify={'center'} gap={0.5}>
|
className={css({
|
||||||
<Heading>Essayez Visio pour simplifier votre quotidien</Heading>
|
display: 'flex',
|
||||||
<Body>
|
flexGrow: 1,
|
||||||
Découvrez une solution intuitive et accessible, conçue pour tous les
|
justifyContent: 'center',
|
||||||
agents publics et leurs partenaires, et bien plus encore.
|
})}
|
||||||
</Body>
|
>
|
||||||
</VStack>
|
<div>
|
||||||
</>
|
<ButtonVerticalCenter>
|
||||||
|
<Button
|
||||||
|
square
|
||||||
|
invisible
|
||||||
|
aria-label={t('previous.label')}
|
||||||
|
tooltip={t('previous.tooltip')}
|
||||||
|
onPress={() => setSlideIndex(slideIndex - 1)}
|
||||||
|
isDisabled={slideIndex == 0}
|
||||||
|
>
|
||||||
|
<RiArrowLeftSLine />
|
||||||
|
</Button>
|
||||||
|
</ButtonVerticalCenter>
|
||||||
|
</div>
|
||||||
|
<SlideContainer>
|
||||||
|
{SLIDES.map((slide, index) => (
|
||||||
|
<Slide visible={index == slideIndex}>
|
||||||
|
<Image src={slide.img} alt={t(`${slide.key}.imgAlt`)} />
|
||||||
|
<Heading>{t(`${slide.key}.title`)}</Heading>
|
||||||
|
<Body>{t(`${slide.key}.body`)}</Body>
|
||||||
|
</Slide>
|
||||||
|
))}
|
||||||
|
</SlideContainer>
|
||||||
|
<div>
|
||||||
|
<ButtonVerticalCenter>
|
||||||
|
<Button
|
||||||
|
square
|
||||||
|
invisible
|
||||||
|
aria-label={t('next.label')}
|
||||||
|
tooltip={t('next.tooltip')}
|
||||||
|
onPress={() => setSlideIndex(slideIndex + 1)}
|
||||||
|
isDisabled={slideIndex == NUMBER_SLIDES - 1}
|
||||||
|
>
|
||||||
|
<RiArrowRightSLine />
|
||||||
|
</Button>
|
||||||
|
</ButtonVerticalCenter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={css({
|
||||||
|
marginTop: '0.5rem',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{SLIDES.map((_, index) => (
|
||||||
|
<Dot key={index} selected={index == slideIndex} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,30 @@
|
|||||||
"copy": "",
|
"copy": "",
|
||||||
"copied": "",
|
"copied": "",
|
||||||
"permissions": ""
|
"permissions": ""
|
||||||
|
},
|
||||||
|
"introSlider": {
|
||||||
|
"previous": {
|
||||||
|
"label": "",
|
||||||
|
"tooltip": ""
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"label": "",
|
||||||
|
"tooltip": ""
|
||||||
|
},
|
||||||
|
"slide1": {
|
||||||
|
"title": "",
|
||||||
|
"body": "",
|
||||||
|
"imgAlt": ""
|
||||||
|
},
|
||||||
|
"slide2": {
|
||||||
|
"title": "",
|
||||||
|
"body": "",
|
||||||
|
"imgAlt": ""
|
||||||
|
},
|
||||||
|
"slide3": {
|
||||||
|
"title": "",
|
||||||
|
"body": "",
|
||||||
|
"imgAlt": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,30 @@
|
|||||||
"copy": "Copy the meeting link",
|
"copy": "Copy the meeting link",
|
||||||
"copied": "Link copied to clipboard",
|
"copied": "Link copied to clipboard",
|
||||||
"permissions": "People with this link do not need your permission to join this meeting."
|
"permissions": "People with this link do not need your permission to join this meeting."
|
||||||
|
},
|
||||||
|
"introSlider": {
|
||||||
|
"previous": {
|
||||||
|
"label": "previous",
|
||||||
|
"tooltip": "previous"
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"label": "next",
|
||||||
|
"tooltip": "next"
|
||||||
|
},
|
||||||
|
"slide1": {
|
||||||
|
"title": "Try Visio to simplify your daily tasks",
|
||||||
|
"body": "Discover an intuitive and accessible solution, designed for all public agents, their partners, and much more.",
|
||||||
|
"imgAlt": "Illustration of a user-friendly and accessible collaboration platform"
|
||||||
|
},
|
||||||
|
"slide2": {
|
||||||
|
"title": "Host group calls without limits",
|
||||||
|
"body": "Unlimited time meetings, up to 15 participants, with smooth and high-quality communication, no matter the group size.",
|
||||||
|
"imgAlt": "Image of a virtual meeting with multiple participants collaborating seamlessly"
|
||||||
|
},
|
||||||
|
"slide3": {
|
||||||
|
"title": "Transform your meetings with AI",
|
||||||
|
"body": "Get accurate and actionable transcripts to boost your productivity. Feature in beta—try it now!",
|
||||||
|
"imgAlt": "Illustration of AI-powered note-taking in a virtual meeting"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,30 @@
|
|||||||
"copy": "Copier le lien de la réunion",
|
"copy": "Copier le lien de la réunion",
|
||||||
"copied": "Lien copié dans le presse-papiers",
|
"copied": "Lien copié dans le presse-papiers",
|
||||||
"permissions": "Les personnes disposant de ce lien n'ont pas besoin de votre autorisation pour rejoindre cette réunion."
|
"permissions": "Les personnes disposant de ce lien n'ont pas besoin de votre autorisation pour rejoindre cette réunion."
|
||||||
|
},
|
||||||
|
"introSlider": {
|
||||||
|
"previous": {
|
||||||
|
"label": "précédent",
|
||||||
|
"tooltip": "précédent"
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"label": "suivant",
|
||||||
|
"tooltip": "suivant"
|
||||||
|
},
|
||||||
|
"slide1": {
|
||||||
|
"title": "Essayez Visio pour simplifier votre quotidien",
|
||||||
|
"body": "Découvrez une solution intuitive et accessible, conçue pour tous les agents publics et leurs partenaires, et bien plus encore.",
|
||||||
|
"imgAlt": "Illustration d'une plateforme de collaboration simple et accessible"
|
||||||
|
},
|
||||||
|
"slide2": {
|
||||||
|
"title": "Organisez des appels de groupe sans limite",
|
||||||
|
"body": "Réunions sans limite de temps, jusqu'à 15 participants, avec une communication fluide et de haute qualité, quel que soit le nombre.",
|
||||||
|
"imgAlt": "Image d'une réunion virtuelle avec plusieurs participants collaborant efficacement"
|
||||||
|
},
|
||||||
|
"slide3": {
|
||||||
|
"title": "Transformez vos réunions avec l'IA",
|
||||||
|
"body": "Obtenez des transcriptions précises et actionnables, pour booster votre productivité. Fonctionnalité en beta, essayez-la maintenant !",
|
||||||
|
"imgAlt": "Illustration de prise de notes assistée par l'IA dans une réunion virtuelle"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user