diff --git a/.vscode/settings.json b/.vscode/settings.json index e10c4c989..98ee2a122 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,6 @@ "sonarlint.connectedMode.project": { "connectionId": "graasp", "projectKey": "graasp_graasp-account" - } + }, + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/public/projects/climate.svg b/public/projects/climate.svg new file mode 100644 index 000000000..c6b848217 --- /dev/null +++ b/public/projects/climate.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/projects/helvetas.svg b/public/projects/helvetas.svg new file mode 100644 index 000000000..07de6e45a --- /dev/null +++ b/public/projects/helvetas.svg @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/team/basile.webp b/public/team/basile.webp new file mode 100755 index 000000000..e8f605f41 Binary files /dev/null and b/public/team/basile.webp differ diff --git a/public/team/denis.webp b/public/team/denis.webp new file mode 100755 index 000000000..82567e579 Binary files /dev/null and b/public/team/denis.webp differ diff --git a/public/team/francois.webp b/public/team/francois.webp new file mode 100755 index 000000000..aeecbb5d2 Binary files /dev/null and b/public/team/francois.webp differ diff --git a/public/team/hagop.webp b/public/team/hagop.webp new file mode 100755 index 000000000..a646d11c0 Binary files /dev/null and b/public/team/hagop.webp differ diff --git a/public/team/isabelle.webp b/public/team/isabelle.webp new file mode 100755 index 000000000..0990d929d Binary files /dev/null and b/public/team/isabelle.webp differ diff --git a/public/team/jeremy.webp b/public/team/jeremy.webp new file mode 100755 index 000000000..cd2022e19 Binary files /dev/null and b/public/team/jeremy.webp differ diff --git a/public/team/juancarlos.webp b/public/team/juancarlos.webp new file mode 100755 index 000000000..7ffced982 Binary files /dev/null and b/public/team/juancarlos.webp differ diff --git a/public/team/kim.webp b/public/team/kim.webp new file mode 100755 index 000000000..4891e660f Binary files /dev/null and b/public/team/kim.webp differ diff --git a/public/team/maria.webp b/public/team/maria.webp new file mode 100755 index 000000000..aa8ca80b4 Binary files /dev/null and b/public/team/maria.webp differ diff --git a/public/team/michele.webp b/public/team/michele.webp new file mode 100755 index 000000000..55fee5a96 Binary files /dev/null and b/public/team/michele.webp differ diff --git a/public/team/philippe.webp b/public/team/philippe.webp new file mode 100755 index 000000000..37787a953 Binary files /dev/null and b/public/team/philippe.webp differ diff --git a/public/team/sandy.webp b/public/team/sandy.webp new file mode 100755 index 000000000..07b4da2ff Binary files /dev/null and b/public/team/sandy.webp differ diff --git a/src/locales/en/landing.json b/src/locales/en/landing.json index e37e13628..0ee22058b 100644 --- a/src/locales/en/landing.json +++ b/src/locales/en/landing.json @@ -352,6 +352,49 @@ "BUTTON_TEXT": "Visit our Blog" } }, + "ABOUT_US": { + "TITLE": "Meet the people behind Graasp", + "DESCRIPTION_1": "Founded by a dedicated team of professionals, our mission is to bridge the gap between cutting-edge technology and education, empowering educators and researchers globally.", + "DESCRIPTION_2": "We aim to bridge the gap between research environments and traditional educational settings such as schools. We envision a future where Graasp empowers educators and students in traditional educational setups and more, revolutionizing teaching methodologies and fostering engaging learning experiences.", + + "ASSOCIATION": { + "TITLE": "Graasp Association", + "DESCRIPTION": "Graasp is more than a Learning Experience Platform. It is a product behind which there is a Swiss Non-Profit Organization dedicated to advancing digital education. Our primary goal is to support educators and researchers every step of the way, providing help and training to achieve their objectives effectively.", + "PROJECTS": { + "TITLE": "Other projects", + "HELVETAS": { + "TITLE": "Helvetas", + "DESCRIPTION": "Collaborative digital platform for training young people on migration routes" + }, + "CLIMATE": { + "TITLE": "Climate", + "DESCRIPTION": "Active learning simulations for investigating the science of global warming" + } + } + }, + "TEAM": { + "TITLE": "Meet the team!", + "STATUSES": { + "TITLE_PRESIDENT": "President", + "TITLE_MANAGING_DIRECTOR": "Managing Director", + "TITLE_VP_RESEARCH": "VP Research", + "TITLE_VP_PRODUCT": "VP Product", + "TITLE_VP_ENGINEERING": "VP Engineering", + "TITLE_VP_OUTREACH": "VP Outreach", + "TITLE_VP_INNOVATION": "VP Innovation", + "TITLE_VP_TECHNOLOGY": "VP Technology", + "TITLE_VP_EDUCATION_AND_CONTENT": "VP Education and Content", + "TITLE_SOFTWARE_ENGINEER": "Software Engineer", + "TITLE_AMBASSADOR": "Ambassador", + "TITLE_PEDAGOGICAL_ENGINEER": "Pedagogical Engineer" + } + }, + "PRESENTATION_VIDEO": { + "TITLE": "Take a look at our presentation video", + "JOIN_BUTTON_TEXT": "Join our Community", + "LIBRARY_BUTTON_TEXT": "Explore the Library" + } + }, "NEWSLETTER": { "LEAD_SENTENCE": "Do you want to be updated?", "TITLE": "Subscribe to our newsletter!", diff --git a/src/locales/fr/landing.json b/src/locales/fr/landing.json index dcc9ea460..1cf0d8f79 100644 --- a/src/locales/fr/landing.json +++ b/src/locales/fr/landing.json @@ -346,6 +346,49 @@ } } }, + "ABOUT_US": { + "TITLE": "Rencontre les personnes derrière Graasp", + "DESCRIPTION_1": "Fondée par une équipe dédiée de professionnels, notre mission est de combler l'écart entre la technologie de pointe et l'éducation, en autonomisant les éducateurs et les chercheurs à l'échelle mondiale.", + "DESCRIPTION_2": "Nous avons pour objectif de combler l'écart entre les environnements de recherche et les établissements éducatifs traditionnels tels que les écoles. Nous imaginons un avenir où Graasp permet aux éducateurs et aux étudiants des structures éducatives traditionnelles et au-delà, de révolutionner les méthodes d'enseignement et de favoriser des expériences d'apprentissage engageantes.", + + "ASSOCIATION": { + "TITLE": "Association Graasp", + "DESCRIPTION": "Graasp est bien plus qu'une plateforme d'expérience d'apprentissage. C'est un produit porté par une organisation à but non lucratif suisse dédiée à l'avancement de l'éducation numérique. Notre objectif principal est de soutenir les éducateurs et les chercheurs à chaque étape de leur parcours, en leur offrant aide et formation pour atteindre leurs objectifs de manière efficace.", + "PROJECTS": { + "TITLE": "D'autres projets", + "HELVETAS": { + "TITLE": "Helvetas", + "DESCRIPTION": "Plateforme numérique collaborative pour former les jeunes sur les routes migratoires" + }, + "CLIMATE": { + "TITLE": "Climate", + "DESCRIPTION": "Simulations d'apprentissage actif pour explorer la science du réchauffement climatique" + } + } + }, + "TEAM": { + "TITLE": "Rencontre l'équipe !", + "STATUSES": { + "TITLE_PRESIDENT": "Président", + "TITLE_MANAGING_DIRECTOR": "Directrice Générale", + "TITLE_VP_RESEARCH": "VP Recherche", + "TITLE_VP_PRODUCT": "VP Produit", + "TITLE_VP_ENGINEERING": "VP Ingénieurie", + "TITLE_VP_OUTREACH": "VP Communication et Promotion", + "TITLE_VP_INNOVATION": "VP Innovation", + "TITLE_VP_TECHNOLOGY": "VP Technologie", + "TITLE_VP_EDUCATION_AND_CONTENT": "VP Formation et Contenu", + "TITLE_SOFTWARE_ENGINEER": "Ingénieur logiciel", + "TITLE_AMBASSADOR": "Ambassadeur", + "TITLE_PEDAGOGICAL_ENGINEER": "Ingénieur pédagogique" + } + }, + "PRESENTATION_VIDEO": { + "TITLE": "Regardez notre vidéo de présentation", + "JOIN_BUTTON_TEXT": "Rejoins notre communauté", + "LIBRARY_BUTTON_TEXT": "Explore la Bibliothèque" + } + }, "NEWSLETTER": { "LEAD_SENTENCE": "Voulez-vous rester informé ?", "TITLE": "Abonnez-vous à notre newsletter !", diff --git a/src/modules/landing/aboutUs/Association.tsx b/src/modules/landing/aboutUs/Association.tsx new file mode 100644 index 000000000..27a4856b5 --- /dev/null +++ b/src/modules/landing/aboutUs/Association.tsx @@ -0,0 +1,52 @@ +import { useTranslation } from 'react-i18next'; + +import { Grid2 as Grid, Stack, Typography } from '@mui/material'; + +import { NS } from '@/config/constants'; + +import { ProjectCard } from './ProjectCard'; + +function Association() { + const { t } = useTranslation(NS.Landing, { + keyPrefix: 'ABOUT_US.ASSOCIATION', + }); + + return ( + + + {t('TITLE')} + + + {t('DESCRIPTION')} + + + {t('PROJECTS.TITLE')} + + + + + + + + + + + + ); +} + +export default Association; diff --git a/src/modules/landing/aboutUs/NumberCard.tsx b/src/modules/landing/aboutUs/NumberCard.tsx new file mode 100644 index 000000000..b582ea893 --- /dev/null +++ b/src/modules/landing/aboutUs/NumberCard.tsx @@ -0,0 +1,28 @@ +import { Card, Typography } from '@mui/material'; + +function NumberCard({ + number, + title, +}: Readonly<{ number: string; title: string }>) { + return ( + + + {number} + + + {title} + + + ); +} + +export default NumberCard; diff --git a/src/modules/landing/aboutUs/PresentationVideoSection.tsx b/src/modules/landing/aboutUs/PresentationVideoSection.tsx new file mode 100644 index 000000000..e794cab67 --- /dev/null +++ b/src/modules/landing/aboutUs/PresentationVideoSection.tsx @@ -0,0 +1,48 @@ +import { useTranslation } from 'react-i18next'; + +import { Stack, Typography } from '@mui/material'; + +import { Button } from '@graasp/ui'; + +import { ButtonLink } from '@/components/ui/ButtonLink'; +import { NS } from '@/config/constants'; +import { GRAASP_LIBRARY_HOST } from '@/config/env'; + +function PresentationVideoSection() { + const { t } = useTranslation(NS.Landing, { + keyPrefix: 'ABOUT_US.PRESENTATION_VIDEO', + }); + + return ( + + + {t('TITLE')} + + + + {/* eslint-disable-next-line jsx-a11y/media-has-caption */} + + + + + + {t('JOIN_BUTTON_TEXT')} + + + + + + + ); +} + +export default PresentationVideoSection; diff --git a/src/modules/landing/aboutUs/ProjectCard.tsx b/src/modules/landing/aboutUs/ProjectCard.tsx new file mode 100644 index 000000000..5657ba3f9 --- /dev/null +++ b/src/modules/landing/aboutUs/ProjectCard.tsx @@ -0,0 +1,39 @@ +import { Card, Stack, Typography } from '@mui/material'; + +export function ProjectCard({ + description, + title, + src, + width, +}: Readonly<{ + description: string; + title: string; + src: string; + width?: string | number; +}>) { + return ( + + + {title} + + + {title} + + + {description} + + + + + ); +} diff --git a/src/modules/landing/aboutUs/TeamMembers.tsx b/src/modules/landing/aboutUs/TeamMembers.tsx new file mode 100644 index 000000000..1c905d964 --- /dev/null +++ b/src/modules/landing/aboutUs/TeamMembers.tsx @@ -0,0 +1,130 @@ +import { useTranslation } from 'react-i18next'; + +import { Box, Grid2 as Grid, Stack, Typography } from '@mui/material'; + +import { NS } from '@/config/constants'; + +function TeamMembers() { + const { t } = useTranslation(NS.Landing, { + keyPrefix: 'ABOUT_US.TEAM', + }); + + const TEAM = [ + { + name: 'Denis Gillet', + image: 'denis.webp', + role: 'STATUSES.TITLE_PRESIDENT', + }, + { + name: 'Isabelle Vonèche Cardia', + image: 'isabelle.webp', + role: 'STATUSES.TITLE_MANAGING_DIRECTOR', + }, + { + name: 'María Jesús Rodríguez-Triana', + image: 'maria.webp', + role: 'STATUSES.TITLE_VP_RESEARCH', + }, + { + name: 'Juan Carlos Farah', + image: 'juancarlos.webp', + role: 'STATUSES.TITLE_VP_PRODUCT', + }, + { + name: 'Kim Lan Phan Hoang', + image: 'kim.webp', + role: 'STATUSES.TITLE_VP_ENGINEERING', + }, + { + name: 'Jérémy La Scala', + image: 'jeremy.webp', + role: 'STATUSES.TITLE_VP_OUTREACH', + }, + { + name: 'Sandy Ingram', + image: 'sandy.webp', + role: 'STATUSES.TITLE_VP_INNOVATION', + }, + { + name: 'Basile Spaenlehauer', + image: 'basile.webp', + role: 'STATUSES.TITLE_VP_TECHNOLOGY', + }, + { + name: 'Michele Notari', + image: 'michele.webp', + role: 'STATUSES.TITLE_VP_EDUCATION_AND_CONTENT', + }, + { + name: 'Hagop Taminian', + image: 'hagop.webp', + role: 'STATUSES.TITLE_SOFTWARE_ENGINEER', + }, + { + name: 'Philippe Kobel', + image: 'philippe.webp', + role: 'STATUSES.TITLE_AMBASSADOR', + }, + { + name: 'François Bierlaire', + image: 'francois.webp', + role: 'STATUSES.TITLE_PEDAGOGICAL_ENGINEER', + }, + ] as const; + + return ( + + + {t('TITLE')} + + + {TEAM.map(({ name, image, role }) => ( + + + {name} + + + + {name} + + + {t(role)} + + + ))} + + + ); +} + +export default TeamMembers; diff --git a/src/modules/landing/aboutUs/TitleSection.tsx b/src/modules/landing/aboutUs/TitleSection.tsx new file mode 100644 index 000000000..ee54dede1 --- /dev/null +++ b/src/modules/landing/aboutUs/TitleSection.tsx @@ -0,0 +1,80 @@ +import { useTranslation } from 'react-i18next'; + +import { Box, Grid2 as Grid, Stack, Typography, styled } from '@mui/material'; + +import { Image } from '@/components/ui/StyledImages'; +import { NS } from '@/config/constants'; + +import NumberCard from './NumberCard'; + +export function TitleSection() { + const { t } = useTranslation(NS.Landing, { keyPrefix: 'ABOUT_US' }); + + return ( + + + + Glenn Carstens-Peters on Unsplash`} + sx={{ + // override the "show top of image" behavior of the Image component + objectPosition: 'unset', + }} + /> + + + + {t('TITLE')} + + + + {t('DESCRIPTION_1')} + + + + {t('DESCRIPTION_2')} + + + + + + + + + + + + + + + + + + + + + ); +} + +const HeaderContainer = styled(Stack)(({ theme }) => ({ + flexDirection: 'column', + alignItems: 'center', + textAlign: 'center', + maxWidth: '60ch', + [theme.breakpoints.up('md')]: { + flexDirection: 'row-reverse', + textAlign: 'unset', + maxWidth: theme.breakpoints.values.lg, + }, +})); diff --git a/src/routes/_landing/about-us.tsx b/src/routes/_landing/about-us.tsx index 58e0524e1..37c72159c 100644 --- a/src/routes/_landing/about-us.tsx +++ b/src/routes/_landing/about-us.tsx @@ -1,11 +1,25 @@ import { createFileRoute } from '@tanstack/react-router'; -import { WorkInProgress } from '@/components/WorkInProgress'; +import Association from '~landing/aboutUs/Association'; +import PresentationVideoSection from '~landing/aboutUs/PresentationVideoSection'; +import TeamMembers from '~landing/aboutUs/TeamMembers'; +import { TitleSection } from '~landing/aboutUs/TitleSection'; +import { Preview } from '~landing/preview/PreviewModeContext'; export const Route = createFileRoute('/_landing/about-us')({ component: RouteComponent, }); function RouteComponent() { - return ; + return ( + <> + + + + + + + + + ); }