Compare commits

..

9 Commits

Author SHA1 Message Date
lebaudantoine f20842b481 (frontend) allow user register to beta feature
I've created a beta form, allowing interested visitors to
register to be a beta user.

This form is yet created with Grist, could be enhance. I'll
investigate using PostHog.
2024-11-17 00:59:40 +01:00
lebaudantoine 3f3ef34053 💫(frontend) add fadein animation on home
Elements' apparition felt quite harsh.
Add an animation to fade in content.
Used a pre-defined animation in panda configs.
2024-11-17 00:53:21 +01:00
lebaudantoine cf647b872f 💫(frontend) add animation on interaction with slider
Add a minimal animation to enhance micro-interaction with our app.
I've tried being minimal, please feel free to enhance or tune this
animation.
2024-11-17 00:52:16 +01:00
lebaudantoine bc9f8c2239 (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.
2024-11-17 00:50:26 +01:00
lebaudantoine d6372bfd86 💄(frontend) enhance home page
I've totally rework the homepage, heavily inspired by GMeet.
Goal: make it more pro, and polished.
2024-11-17 00:49:19 +01:00
lebaudantoine 4bbdb6abe6 (frontend) introduce learn more link component
Component providing a 'learn more' feature. Inspired by GMeet.
Naive component.
2024-11-17 00:48:33 +01:00
lebaudantoine 8b7708f3a3 🚸(frontend) update A component hover animation
I found original to hide text decoration on hover. It felt wrong
to me, I proposed a new animation. Please feel free to rework it
or enhance it in the future.
2024-11-17 00:47:38 +01:00
lebaudantoine 73a5511dcd 🚧(frontend) add intro slider component with feature slides
Created a component for an intro slider to showcase app features.
Each slide will include a minimal illustration and concise descriptions.

Work In Progress, Slide logic will be added in upcomming commits.
2024-11-17 00:45:04 +01:00
lebaudantoine 998a62041f 💄(frontend) remove bottom border on header
The bottom border on the header was unnecessary
and removed for a cleaner design.
2024-11-17 00:43:53 +01:00
27 changed files with 158 additions and 572 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "meet"
version = "0.1.8"
version = "0.1.7"
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
classifiers = [
"Development Status :: 5 - Production/Stable",
+7 -21
View File
@@ -1,12 +1,12 @@
{
"name": "meet",
"version": "0.1.8",
"version": "0.1.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "meet",
"version": "0.1.8",
"version": "0.1.7",
"dependencies": {
"@livekit/components-react": "2.6.5",
"@livekit/components-styles": "1.1.3",
@@ -22,7 +22,7 @@
"i18next-parser": "9.0.2",
"i18next-resources-to-backend": "1.2.1",
"livekit-client": "2.5.7",
"posthog-js": "1.186.1",
"posthog-js": "1.167.0",
"react": "18.3.1",
"react-aria-components": "1.4.0",
"react-dom": "18.3.1",
@@ -409,7 +409,6 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
"extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {
@@ -4530,17 +4529,6 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
},
"node_modules/core-js": {
"version": "3.39.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz",
"integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -8265,15 +8253,13 @@
"license": "MIT"
},
"node_modules/posthog-js": {
"version": "1.186.1",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.186.1.tgz",
"integrity": "sha512-m6TNW01nfqErwMxaZxNScYdMaUJO0s3bbmt/tboL29yZDnuHdOiYFbG+T4MCxdFxjWRa5gOR25bQD/SSt1t/4A==",
"license": "MIT",
"version": "1.167.0",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.167.0.tgz",
"integrity": "sha512-/zXQ6tuJgiF1d4mgg3UsAi/uoyg7UnfFNQtikuALmaE53xFExpcAKbMfHPG/f54QgTvLxSHyGL1kFl/1uspkGg==",
"dependencies": {
"core-js": "^3.38.1",
"fflate": "^0.4.8",
"preact": "^10.19.3",
"web-vitals": "^4.2.0"
"web-vitals": "^4.0.1"
}
},
"node_modules/preact": {
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "meet",
"private": true,
"version": "0.1.8",
"version": "0.1.7",
"type": "module",
"scripts": {
"dev": "panda codegen && vite",
@@ -27,7 +27,7 @@
"i18next-parser": "9.0.2",
"i18next-resources-to-backend": "1.2.1",
"livekit-client": "2.5.7",
"posthog-js": "1.186.1",
"posthog-js": "1.167.0",
"react": "18.3.1",
"react-aria-components": "1.4.0",
"react-dom": "18.3.1",
-1
View File
@@ -40,7 +40,6 @@ const config: Config = {
// media queries are defined in em so that zooming with text-only mode triggers breakpoints
breakpoints: {
xs: '22.6em', // 360px (we assume less than that are old/entry level mobile phones)
xsm: '31.25em', // 500px,
sm: '40em', // 640px
md: '48em', // 768px
lg: '64em', // 1024px
+25
View File
@@ -0,0 +1,25 @@
import { css } from '@/styled-system/css'
import { RiExternalLinkLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { LinkButton } from '@/primitives'
export const Feedback = () => {
const { t } = useTranslation()
return (
<LinkButton
href="https://grist.incubateur.net/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4"
variant="success"
target="_blank"
>
<span className={css({ marginRight: 0.5 })} aria-hidden="true">
💡
</span>
{t('feedbackAlert')}
<RiExternalLinkLine
size={16}
className={css({ marginLeft: 0.5 })}
aria-hidden="true"
/>
</LinkButton>
)
}
@@ -1,46 +0,0 @@
import { css } from '@/styled-system/css'
import { RiErrorWarningLine, RiExternalLinkLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { Text, A } from '@/primitives'
const GRIST_FORM =
'https://grist.numerique.gouv.fr/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4'
export const FeedbackBanner = () => {
const { t } = useTranslation()
return (
<div
className={css({
width: '100%',
backgroundColor: '#E8EDFF',
color: '#0063CB',
display: { base: 'none', sm: 'flex' },
justifyContent: 'center',
padding: '0.5rem 0',
})}
>
<div
className={css({
display: 'inline-flex',
gap: '0.5rem',
alignItems: 'center',
})}
>
<RiErrorWarningLine size={20} />
<Text as="p">{t('feedback.context')}</Text>
<div
className={css({
display: 'flex',
alignItems: 'center',
gap: 0.25,
})}
>
<A href={GRIST_FORM} target="_blank">
{t('feedback.cta')}
</A>
<RiExternalLinkLine size={16} aria-hidden="true" />
</div>
</div>
</div>
)
}
@@ -38,7 +38,7 @@ const Body = styled('p', {
const Image = styled('img', {
base: {
maxHeight: '362px',
maxHeight: '330px',
height: '100%',
width: 'fit-content',
},
@@ -74,15 +74,9 @@ const Container = styled('div', {
},
})
const ButtonContainer = styled('div', {
base: {
display: { base: 'none', xsm: 'block' },
},
})
const ButtonVerticalCenter = styled('div', {
base: {
marginTop: '13.3125rem',
marginTop: '10.3125rem',
transform: 'translateY(-50%)',
},
})
@@ -102,9 +96,9 @@ const Slide = styled('div', {
alignItems: 'center',
gap: '0.5rem',
justifyContent: 'start',
minHeight: { base: 'none', xsm: '550px' },
minWidth: { base: 'none', xsm: '200px' },
width: { base: '100%', xsm: '22.625rem' },
minHeight: '550px',
minWidth: '200px',
width: '22.625rem',
},
variants: {
visible: {
@@ -182,7 +176,7 @@ export const IntroSlider = () => {
justifyContent: 'center',
})}
>
<ButtonContainer>
<div>
<ButtonVerticalCenter>
<Button
square
@@ -195,10 +189,10 @@ export const IntroSlider = () => {
<RiArrowLeftSLine />
</Button>
</ButtonVerticalCenter>
</ButtonContainer>
</div>
<SlideContainer>
{SLIDES.map((slide, index) => (
<Slide visible={index == slideIndex} key={index}>
<Slide visible={index == slideIndex}>
<Image src={slide.img} alt={t(`${slide.key}.imgAlt`)} />
<TextAnimation visible={index == slideIndex}>
<Heading>{t(`${slide.key}.title`)}</Heading>
@@ -218,7 +212,7 @@ export const IntroSlider = () => {
</Slide>
))}
</SlideContainer>
<ButtonContainer>
<div>
<ButtonVerticalCenter>
<Button
square
@@ -231,12 +225,11 @@ export const IntroSlider = () => {
<RiArrowRightSLine />
</Button>
</ButtonVerticalCenter>
</ButtonContainer>
</div>
</div>
<div
className={css({
marginTop: '0.5rem',
display: { base: 'none', xsm: 'block' },
})}
>
{SLIDES.map((_, index) => (
+13 -25
View File
@@ -1,7 +1,7 @@
import { useTranslation } from 'react-i18next'
import { DialogTrigger, MenuItem, Menu as RACMenu } from 'react-aria-components'
import { Button, Menu } from '@/primitives'
import { styled } from '@/styled-system/jsx'
import { HStack, styled } from '@/styled-system/jsx'
import { navigateTo } from '@/navigation/navigateTo'
import { Screen } from '@/layout/Screen'
import { generateRoomId } from '@/features/rooms'
@@ -24,19 +24,18 @@ const Columns = ({ children }: { children?: ReactNode }) => {
<div
className={css({
alignItems: 'center',
margin: 'auto',
display: 'inline-flex',
flexDirection: 'column',
height: '100%',
minHeight: '100%',
justifyContent: 'normal',
padding: '0 1rem',
width: 'calc(100% - 2rem)',
width: 'calc(100%-2rem)',
opacity: 0,
animation: '.5s ease-in fade 0s forwards',
lg: {
flexDirection: 'row',
justifyContent: 'center',
justifyContent: 'space-evenly',
width: '100%',
padding: 0,
},
@@ -57,7 +56,7 @@ const LeftColumn = ({ children }: { children?: ReactNode }) => {
flexDirection: 'column',
flexBasis: 'auto',
flexShrink: 0,
maxWidth: '38rem',
maxWidth: '39rem',
width: '100%',
padding: '1rem 3%',
marginTop: 'auto',
@@ -66,8 +65,8 @@ const LeftColumn = ({ children }: { children?: ReactNode }) => {
textAlign: 'left',
alignItems: 'flex-start',
flexShrink: '1',
flexBasis: '36rem',
maxWidth: '36rem',
flexBasis: '45rem',
maxWidth: '45rem',
padding: '1em 3em',
},
})}
@@ -114,29 +113,25 @@ const Separator = styled('div', {
const Heading = styled('h1', {
base: {
fontSize: '3rem',
lineHeight: '3.2rem',
letterSpacing: '0',
fontWeight: '500',
fontStyle: 'normal',
fontStretch: 'normal',
fontOpticalSizing: 'auto',
marginBottom: 0,
paddingBottom: '0.75rem',
fontSize: '2.3rem',
lineHeight: '2.5rem',
letterSpacing: '0',
xsm: {
fontSize: '3rem',
lineHeight: '3.2rem',
},
},
})
const IntroText = styled('div', {
base: {
marginBottom: '3rem',
fontSize: '1.5rem',
fontSize: '1.375rem',
lineHeight: '1.8rem',
textWrap: 'pretty',
maxWidth: '32rem',
maxWidth: '28rem',
},
})
@@ -158,14 +153,7 @@ export const Home = () => {
<LeftColumn>
<Heading>{t('heading')}</Heading>
<IntroText>{t('intro')}</IntroText>
<div
className={css({
display: 'flex',
gap: 0.5,
flexDirection: { base: 'column', xsm: 'row' },
alignItems: { base: 'center', xsm: 'items-start' },
})}
>
<HStack gap="gutter" alignItems="start">
{isLoggedIn ? (
<Menu>
<Button variant="primary" data-attr="create-meeting">
@@ -217,7 +205,7 @@ export const Home = () => {
</Button>
<JoinMeetingDialog />
</DialogTrigger>
</div>
</HStack>
<Separator />
<div
className={css({
@@ -1,249 +0,0 @@
import { Button, H, Text, TextArea } from '@/primitives'
import { useEffect, useState } from 'react'
import { cva } from '@/styled-system/css'
import { useTranslation } from 'react-i18next'
import { styled, VStack } from '@/styled-system/jsx'
import { usePostHog } from 'posthog-js/react'
import { PostHog } from 'posthog-js'
const Card = styled('div', {
base: {
border: '1px solid',
borderColor: 'gray.300',
padding: '1rem',
marginTop: '1.5rem',
borderRadius: '0.25rem',
boxShadow: '',
minWidth: '380px',
minHeight: '196px',
},
})
const Bar = styled('div', {
base: {
display: 'flex',
border: '2px solid',
borderColor: 'gray.300',
borderRadius: '8px',
overflowY: 'hidden',
scrollbar: 'hidden',
},
})
const ratingButtonRecipe = cva({
base: {
backgroundColor: 'white',
color: 'initial',
border: 'none',
borderRadius: 0,
padding: '0.5rem 0.85rem',
flexGrow: '1',
cursor: 'pointer',
},
variants: {
selected: {
true: {
backgroundColor: '#1d4ed8',
color: 'white',
},
false: {
'&[data-hovered]': {
backgroundColor: 'gray.100',
},
},
},
borderLeft: {
true: {
borderLeft: '1px solid',
borderColor: 'gray.300',
},
},
},
})
const labelRecipe = cva({
base: {
color: 'gray.600',
paddingTop: '0.25rem',
},
})
const OpenFeedback = ({
posthog,
onNext,
}: {
posthog: PostHog
onNext: () => void
}) => {
const { t } = useTranslation('rooms', { keyPrefix: 'openFeedback' })
const [feedback, setFeedback] = useState('')
const onContinue = () => {
setFeedback('')
onNext()
}
const onSubmit = () => {
try {
posthog.capture('survey sent', {
$survey_id: '01933c5a-5a1d-0000-ada8-e39f5918c2d4',
$survey_response: feedback,
})
} catch (e) {
console.warn(e)
} finally {
onContinue()
}
}
return (
<Card>
<H lvl={3}>{t('question')}</H>
<TextArea
id="feedbackInput"
name="feedback"
placeholder={t('placeholder')}
required
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
style={{
minHeight: '150px',
marginBottom: '1rem',
}}
/>
<VStack gap="0.5">
<Button
variant="primary"
size="sm"
fullWidth
isDisabled={!feedback}
onPress={onSubmit}
>
{t('submit')}
</Button>
<Button invisible size="sm" fullWidth onPress={onNext}>
{t('skip')}
</Button>
</VStack>
</Card>
)
}
const RateQuality = ({
posthog,
onNext,
maxRating = 7,
}: {
posthog: PostHog
onNext: () => void
maxRating?: number
}) => {
const { t } = useTranslation('rooms', { keyPrefix: 'rating' })
const [selectedRating, setSelectedRating] = useState<number | null>(null)
const handleRatingClick = (rating: number) => {
setSelectedRating((prevRating) => (prevRating === rating ? null : rating))
}
const onSubmit = () => {
try {
posthog.capture('survey sent', {
$survey_id: '01933c22-d005-0000-b623-20b752171e2e',
$survey_response: `${selectedRating}`,
})
} catch (e) {
console.warn(e)
} finally {
setSelectedRating(null)
onNext()
}
}
return (
<Card>
<H lvl={3}>{t('question')}</H>
<Bar>
{[...Array(maxRating)].map((_, index) => (
<Button
key={index}
onPress={() => handleRatingClick(index + 1)}
className={ratingButtonRecipe({
selected: selectedRating === index + 1,
borderLeft: index != 0,
})}
>
{index + 1}
</Button>
))}
</Bar>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
marginBottom: '1rem',
}}
>
<Text variant="sm" className={labelRecipe()}>
{t('levels.min')}
</Text>
<Text variant="sm" className={labelRecipe()}>
{t('levels.max')}
</Text>
</div>
<Button
variant="primary"
size="sm"
fullWidth
isDisabled={!selectedRating}
onPress={onSubmit}
>
{t('submit')}
</Button>
</Card>
)
}
const ConfirmationMessage = ({ onNext }: { onNext: () => void }) => {
const { t } = useTranslation('rooms', { keyPrefix: 'confirmationMessage' })
useEffect(() => {
const timer = setTimeout(() => {
onNext()
}, 10000)
return () => clearTimeout(timer)
}, [onNext])
return (
<Card
style={{
maxWidth: '380px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<VStack gap={0}>
<H lvl={3}>{t('heading')}</H>
<Text as="p" variant="paragraph" centered>
{t('body')}
</Text>
</VStack>
</Card>
)
}
export const Rating = () => {
const posthog = usePostHog()
const [step, setStep] = useState(0)
if (step == 0) {
return <RateQuality posthog={posthog} onNext={() => setStep(step + 1)} />
}
if (step == 1) {
return <OpenFeedback posthog={posthog} onNext={() => setStep(step + 1)} />
}
if (step == 2) {
return <ConfirmationMessage onNext={() => setStep(0)} />
}
}
@@ -1,7 +1,8 @@
import { Button, TextArea } from '@/primitives'
import { Button } from '@/primitives'
import { HStack } from '@/styled-system/jsx'
import { RiSendPlane2Fill } from '@remixicon/react'
import { useState, useEffect } from 'react'
import { TextArea } from '@/primitives/TextArea'
import { RefObject } from 'react'
import { useTranslation } from 'react-i18next'
@@ -1,47 +1,17 @@
import { useTranslation } from 'react-i18next'
import { Button } from '@/primitives'
import { Text } from '@/primitives'
import { Screen } from '@/layout/Screen'
import { Center, HStack, styled, VStack } from '@/styled-system/jsx'
import { Rating } from '@/features/rooms/components/Rating.tsx'
import { useLocation } from 'wouter'
// fixme - duplicated with home, refactor in a proper style
const Heading = styled('h1', {
base: {
fontWeight: '500',
fontStyle: 'normal',
fontStretch: 'normal',
fontOpticalSizing: 'auto',
fontSize: '2.3rem',
lineHeight: '2.5rem',
letterSpacing: '0',
paddingBottom: '2rem',
},
})
import { CenteredContent } from '@/layout/CenteredContent'
export const FeedbackRoute = () => {
const { t } = useTranslation('rooms')
const [, setLocation] = useLocation()
return (
<Screen layout="centered">
<Center>
<VStack>
<Heading>{t('feedback.heading')}</Heading>
<HStack>
<Button
outline
variant="primary"
onPress={() => window.history.back()}
>
{t('feedback.back')}
</Button>
<Button variant="primary" onPress={() => setLocation('/')}>
{t('feedback.home')}
</Button>
</HStack>
<Rating />
</VStack>
</Center>
<CenteredContent title={t('feedback.heading')} withBackButton>
<Text as="p" variant="h3" centered>
{t('feedback.body')}
</Text>
</CenteredContent>
</Screen>
)
}
+8 -11
View File
@@ -13,14 +13,11 @@ i18n
)
.use(initReactI18next)
.use(LanguageDetector)
.init({
supportedLngs: ['en', 'fr'],
fallbackLng: 'fr',
ns: i18nDefaultNamespace,
detection: {
order: ['localStorage', 'navigator'],
},
interpolation: {
escapeValue: false,
},
})
i18n.init({
supportedLngs: ['en', 'fr'],
fallbackLng: 'en',
ns: i18nDefaultNamespace,
interpolation: {
escapeValue: false,
},
})
+64 -72
View File
@@ -6,7 +6,7 @@ import { Text, Button } from '@/primitives'
import { SettingsButton } from '@/features/settings'
import { logoutUrl, useUser } from '@/features/auth'
import { useMatchesRoute } from '@/navigation/useMatchesRoute'
import { FeedbackBanner } from '@/components/FeedbackBanner.tsx'
import { Feedback } from '@/components/Feedback'
import { Menu } from '@/primitives/Menu'
import { MenuList } from '@/primitives/MenuList'
import { ProConnectButton } from '@/components/ProConnectButton'
@@ -20,85 +20,77 @@ export const Header = () => {
const { user, isLoggedIn } = useUser()
return (
<>
<FeedbackBanner />
<div
className={css({
paddingY: 1,
paddingX: 1,
flexShrink: 0,
})}
>
<div
className={css({
paddingY: 1,
paddingX: 1,
flexShrink: 0,
})}
>
<div
className={css({
display: 'flex',
display: 'flex',
flexDirection: 'column',
rowGap: 1,
md: {
rowGap: 0,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
})}
>
<header>
<Stack gap={2.25} direction="row" align="center">
<Text bold variant="h1" margin={false}>
<Link
onClick={(event) => {
if (
isRoom &&
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
) {
event.preventDefault()
},
})}
>
<header>
<Stack gap={2.25} direction="row" align="center">
<Text bold variant="h1" margin={false}>
<Link
onClick={(event) => {
if (
isRoom &&
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
) {
event.preventDefault()
}
}}
to="/"
>
{t('app')}
</Link>
</Text>
<Feedback />
</Stack>
</header>
<nav>
<Stack gap={1} direction="row" align="center">
{isLoggedIn === false && !isHome && (
<ProConnectButton hint={false} />
)}
{!!user && (
<Menu>
<Button
size="sm"
invisible
tooltip={t('loggedInUserTooltip')}
tooltipType="delayed"
>
{user?.full_name || user?.email}
</Button>
<MenuList
items={[{ value: 'logout', label: t('logout') }]}
onAction={(value) => {
if (value === 'logout') {
terminateAnalyticsSession()
terminateSupportSession()
window.location.href = logoutUrl()
}
}}
to="/"
>
{t('app')}
</Link>
</Text>
</Stack>
</header>
<nav>
<Stack gap={1} direction="row" align="center">
{isLoggedIn === false && !isHome && (
<ProConnectButton hint={false} />
)}
{!!user && (
<Menu>
<Button
size="sm"
invisible
tooltip={t('loggedInUserTooltip')}
tooltipType="delayed"
>
<span
className={css({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
display: 'block',
maxWidth: { base: '80px', xsm: '350px' },
})}
>
{user?.full_name || user?.email}
</span>
</Button>
<MenuList
items={[{ value: 'logout', label: t('logout') }]}
onAction={(value) => {
if (value === 'logout') {
terminateAnalyticsSession()
terminateSupportSession()
window.location.href = logoutUrl()
}
}}
/>
</Menu>
)}
<SettingsButton />
</Stack>
</nav>
</div>
/>
</Menu>
)}
<SettingsButton />
</Stack>
</nav>
</div>
</>
</div>
)
}
+1 -4
View File
@@ -6,10 +6,7 @@
"error": {
"heading": ""
},
"feedback": {
"context": "",
"cta": ""
},
"feedbackAlert": "",
"forbidden": {
"heading": ""
},
+2 -21
View File
@@ -1,8 +1,7 @@
{
"feedback": {
"heading": "",
"home": "",
"back": ""
"body": "",
"heading": ""
},
"join": {
"videoinput": {
@@ -110,24 +109,6 @@
"chat": {
"disclaimer": ""
},
"rating": {
"submit": "",
"question": "",
"levels": {
"min": "",
"max": ""
}
},
"openFeedback": {
"question": "",
"placeholder": "",
"submit": "",
"skip": ""
},
"confirmationMessage": {
"heading": "",
"body": ""
},
"participants": {
"subheading": "",
"contributors": "",
+1 -4
View File
@@ -6,10 +6,7 @@
"error": {
"heading": "An error occurred while loading the page"
},
"feedback": {
"context": "Visio is still in early development — your input matters!",
"cta": "Share your feedback"
},
"feedbackAlert": "Give us feedback",
"forbidden": {
"heading": "You don't have the permission to view this page"
},
+2 -2
View File
@@ -19,7 +19,7 @@
},
"laterMeetingDialog": {
"heading": "Your connection details",
"description": "Send this link to the people you want to invite to the meeting. They will be able to join without ProConnect.",
"description": "Send this link to the people you want to invite to the meeting. They will be able to join without Agent Connect.",
"copy": "Copy the meeting link",
"copied": "Link copied to clipboard",
"permissions": "People with this link do not need your permission to join this meeting."
@@ -44,7 +44,7 @@
},
"slide2": {
"title": "Host group calls without limits",
"body": "Unlimited time meetings, with smooth and high-quality communication, no matter the group size.",
"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": {
+2 -21
View File
@@ -1,8 +1,7 @@
{
"feedback": {
"heading": "You have left the meeting",
"home": "Return to home",
"back": "Rejoin the meeting"
"body": "Please fill out the form available in the header to give us your precious feedback! Thanks.",
"heading": "Help us improve Visio"
},
"join": {
"videoinput": {
@@ -108,24 +107,6 @@
"chat": {
"disclaimer": "The messages are visible to participants only at the time they are sent. All messages are deleted at the end of the call."
},
"rating": {
"submit": "Submit",
"question": "What do you think about the quality of your call?",
"levels": {
"min": "very poor",
"max": "excellent"
}
},
"openFeedback": {
"question": "What can we do to improve Visio?",
"placeholder": "Describe your bugs or share your suggestions…",
"submit": "Submit",
"skip": "Skip"
},
"confirmationMessage": {
"heading": "Thank you for your submission",
"body": "Our product team takes the time to carefully review your feedback. We will get back to you as soon as possible."
},
"participants": {
"subheading": "In room",
"you": "You",
+1 -4
View File
@@ -6,10 +6,7 @@
"error": {
"heading": "Une erreur est survenue lors du chargement de la page"
},
"feedback": {
"context": "Visio est en pleine construction — votre avis compte !",
"cta": "Partagez votre avis"
},
"feedbackAlert": "Donnez-nous votre avis",
"forbidden": {
"heading": "Accès interdit"
},
+2 -2
View File
@@ -19,7 +19,7 @@
},
"laterMeetingDialog": {
"heading": "Vos informations de connexion",
"description": "Envoyez ce lien aux personnes que vous souhaitez inviter à la réunion. Ils pourront la rejoindre sans ProConnect.",
"description": "Envoyez ce lien aux personnes que vous souhaitez inviter à la réunion. Ils pourront la rejoindre sans Agent Connect.",
"copy": "Copier le lien de la réunion",
"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."
@@ -44,7 +44,7 @@
},
"slide2": {
"title": "Organisez des appels de groupe sans limite",
"body": "Réunions sans limite de temps, avec une communication fluide et de haute qualité, quel que soit le nombre.",
"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": {
+2 -21
View File
@@ -1,8 +1,7 @@
{
"feedback": {
"heading": "Vous avez quitté la réunion",
"home": "Retourner à l'accueil",
"back": "Réintégrer la réunion"
"body": "Remplissez le formulaire disponible dans l'entête du site pour nous donner votre avis sur l'outil. Vos retours sont précieux ! Merci.",
"heading": "Aidez-nous à améliorer Visio"
},
"join": {
"videoinput": {
@@ -108,24 +107,6 @@
"chat": {
"disclaimer": "Les messages sont visibles par les participants uniquement au moment de\nleur envoi. Tous les messages sont supprimés à la fin de l'appel."
},
"rating": {
"submit": "Envoyer",
"question": "Que pensez-vous de la qualité de votre appel ?",
"levels": {
"min": "très mauvaise",
"max": "excellente"
}
},
"openFeedback": {
"question": "Que pouvons-nous faire pour améliorer Visio ?",
"placeholder": "Décrivez vos bugs ou partagez vos suggestions …",
"submit": "Envoyer",
"skip": "Passer"
},
"confirmationMessage": {
"heading": "Merci pour votre submission",
"body": "Notre équipe produit prend le temps d'analyser attentivement vos réponses. Nous reviendrons vers vous dans les plus brefs délais."
},
"participants": {
"subheading": "Dans la réunion",
"you": "Vous",
@@ -59,9 +59,6 @@ export const buttonRecipe = cva({
},
primary: {
colorPalette: 'primary',
'&[data-disabled]': {
opacity: 0.3,
},
},
// @TODO: better handling of colors… this is a mess
success: {
-1
View File
@@ -28,4 +28,3 @@ export { Text } from './Text'
export { ToggleButton } from './ToggleButton'
export { Ul } from './Ul'
export { VerticallyOffCenter } from './VerticallyOffCenter'
export { TextArea } from './TextArea'
@@ -1,7 +1,7 @@
image:
repository: lasuite/meet-backend
pullPolicy: Always
tag: "v0.1.8"
tag: "v0.1.7"
backend:
migrateJobAnnotations:
@@ -128,7 +128,7 @@ frontend:
image:
repository: lasuite/meet-frontend
pullPolicy: Always
tag: "v0.1.8"
tag: "v0.1.7"
ingress:
enabled: true
+1 -1
View File
@@ -1,7 +1,7 @@
apiVersion: core.libre.sh/v1alpha1
kind: Bucket
metadata:
name: meet-media-storage
name: impress-media-storage
namespace: {{ .Release.Namespace | quote }}
spec:
provider: data
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mail_mjml",
"version": "0.1.8",
"version": "0.1.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mail_mjml",
"version": "0.1.8",
"version": "0.1.7",
"license": "MIT",
"dependencies": {
"@html-to/text-cli": "0.5.4",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mail_mjml",
"version": "0.1.8",
"version": "0.1.7",
"description": "An util to generate html and text django's templates from mjml templates",
"type": "module",
"dependencies": {