Updated Projects page

This commit is contained in:
TitiLaPierre
2024-10-17 15:56:54 +02:00
parent 212cf6ba58
commit 7115a38316
7 changed files with 288 additions and 249 deletions

View File

@@ -1,56 +0,0 @@
import React from 'react';
interface ProjectBigCardProps {
imgtitle: string;
lefttext: { __html: string };
rightimage: string;
downtitle: string;
downcontent: string;
}
interface ProjectSmallCardProps {
img: string;
title: string;
content: string;
}
export const ProjectBigCard: React.FC<ProjectBigCardProps> = ({
imgtitle,
lefttext,
rightimage,
downtitle,
downcontent,
}) => {
return (
<div className={'project-big-card'}>
<img src={imgtitle} alt={imgtitle} />
<div className={'middle-div-project-big-card'}>
<div
className={'left-text-project-big-card'}
dangerouslySetInnerHTML={lefttext}
/>
<img src={rightimage} alt={rightimage} />
</div>
<div className={'down-div-project-big-card'}>
<h2>{downtitle}</h2>
<p>{downcontent}</p>
</div>
</div>
);
};
export const ProjectSmallCard: React.FC<ProjectSmallCardProps> = ({
img,
title,
content,
}) => {
return (
<div className={'project-small-card'}>
<img src={img} alt={img} />
<div className={'project-small-card-content'}>
<h2>{title}</h2>
<p>{content}</p>
</div>
</div>
);
};

View File

@@ -1,24 +0,0 @@
import React from 'react';
interface ProjectHeaderCardProps {
title: string;
content: string[];
}
export const ProjectHeaderCard: React.FC<ProjectHeaderCardProps> = ({
title,
content,
}) => {
return (
<div className={'project-header-card'}>
<h2>{title}</h2>
<ul className={'project-header-card-ul'}>
{content.map((item, index) => (
<li className={'project-header-card-li'} key={index}>
{item}
</li>
))}
</ul>
</div>
);
};

View File

@@ -1,24 +0,0 @@
import React from 'react';
import { ProjectHeaderCard } from './projectheadercard.tsx';
export const ProjetsHeader: React.FC = () => {
return (
<div className={'project-header-container'}>
<h1>PROJETS</h1>
<p>Vous retrouvez ici la liste des projets en cours et passé.</p>
<div className={'project-header-card-list'}>
<ProjectHeaderCard
title={'Projets en cours'}
content={[
'Coupe de France de robotique 2025',
'Digitalisation du bureau',
]}
/>
<ProjectHeaderCard
title={'Projets passés'}
content={['Coupe de France de robotique 2024', 'Drone DIY']}
/>
</div>
</div>
);
};

View File

@@ -0,0 +1,145 @@
.timeline {
display: flex;
flex-direction: column;
align-items: center;
gap: 150px;
position: relative;
z-index: 0;
}
.timeline::before {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 10px;
height: 100%;
translate: -50% 0;
border-radius: 999px;
background: var(--gray);
z-index: -1;
}
.timeline-tag {
background: var(--gray);
padding: 0.5rem 2rem;
border-radius: 5px;
font-size: 0.8rem;
text-transform: uppercase;
user-select: none;
width: fit-content;
}
.timeline-project {
background: var(--white);
box-shadow: var(--shadow);
padding: 2rem;
border-radius: 15px;
width: 100%;
max-width: 750px;
position: relative;
display: flex;
flex-direction: column;
align-self: center;
gap: 2rem;
}
.timeline-project::before, .timeline-project::after {
content: '';
position: absolute;
top: 50%;
translate: 0 -50%;
background: var(--main);
width: 4px;
height: 100%;
max-height: 150px;
border-radius: 999px;
}
.timeline-project::before { left: -15px; }
.timeline-project::after { right: -15px; }
.timeline-project-content {
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.timeline-project-title {
font-size: 1.5rem;
font-weight: 800;
text-transform: uppercase;
}
.timeline-project-date {
font-size: 0.8rem;
color: var(--darkGray);
}
.timeline-project-banner {
position: absolute;
max-width: 50%;
max-height: 250px;
right: 0;
top: 0;
translate: 0 -50%;
}
.timeline-project-description {
display: flex;
flex-direction: column;
gap: 1rem;
}
.timeline-project-paragraph {
color: var(--darkGray);
& > u {
color: var(--black);
text-decoration: underline var(--main) 2px;
}
}
.timeline-project-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
}
.timeline-project-card {
aspect-ratio: 1/1;
max-width: 150px;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
&.card_stat {
background: var(--lightGray);
}
&.card_image_contain {
padding: 2rem 1rem;
border: 1px solid var(--lightGray);
& .timeline-project-card-image {
object-fit: contain;
}
}
&.card_image_cover .timeline-project-card-image {
object-fit: cover;
}
}
.timeline-project-card-number {
color: var(--main);
font-size: 2em;
font-weight: 700;
}
.timeline-project-card-subtext {
color: var(--darkGray);
font-size: 0.8em;
text-transform: uppercase;
text-align: center;
}
.timeline-project-card-image {
width: 100%;
height: 100%;
}
@media screen and (max-width: 800px) {
.timeline {
gap: 75px;
}
.timeline-project-banner {
max-width: 100%;
max-height: 200px;
object-fit: contain;
translate: 0 0;
position: static;
}
}

View File

@@ -0,0 +1,81 @@
import React from "react";
import './timeline.css';
interface StatCardProps {
type: "stat";
data: string;
label: string;
};
interface ImageCardProps {
type: "image";
src: string;
alt: string;
fit: "contain" | "cover";
};
interface TimelineProjectProps {
title: string;
date: string;
banner?: string;
paragraphs: React.ReactNode[];
cards?: (StatCardProps|ImageCardProps)[];
};
interface TimelineProps {
projects: TimelineProjectProps[];
};
const TimelineProjectCard: React.FC<StatCardProps | ImageCardProps> = (props) => {
if (props.type === "stat") {
const { data, label } = props as StatCardProps;
return (
<div className={'timeline-project-card card_stat'}>
<p className={'timeline-project-card-number'}>{data}</p>
<p className={'timeline-project-card-subtext'}>{label}</p>
</div>
);
} else if (props.type === "image") {
const { src, alt, fit } = props as ImageCardProps;
return (
<div className={`timeline-project-card card_image_${fit}`}>
<img className={"timeline-project-card-image"} src={src} alt={alt} />
</div>
);
}
};
export const TimelineProject: React.FC<TimelineProjectProps> = ({ title, banner, date, paragraphs, cards }) => {
return (
<div className={'timeline-project'}>
<div className={'timeline-project-content'}>
<h3 className={'timeline-project-title'}>{title}</h3>
<p className={'timeline-project-date'}>{date}</p>
</div>
{ banner && <img className={'timeline-project-banner'} src={banner} alt={title} /> }
<div className={'timeline-project-description'}>
{ paragraphs.map((paragraph, i) => <p className={'timeline-project-paragraph'} key={i}>{paragraph}</p>) }
</div>
<div className={'timeline-project-cards'}>
{ cards && cards.map((card, i) => <TimelineProjectCard key={i} {...card} />) }
</div>
</div>
);
}
export const Timeline: React.FC<TimelineProps> = ({ projects }) => {
return (
<div className={'timeline'}>
<h4 className={'timeline-tag'}>Aujourd'hui</h4>
{
projects.map((project, i) => {
return (
<TimelineProject key={i} {...project} />
);
})
}
<h4 className={'timeline-tag'}>Il y a quelques temps</h4>
</div>
);
}

View File

@@ -1,104 +0,0 @@
.project-header-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1em;
margin: 2em 0;
}
.project-header-container h1 {
font-size: 3em;
font-weight: 300;
}
.project-header-card-list {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
gap: 10em;
}
.project-header-card {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1em;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
border-radius: 20px;
padding-right: 1em;
}
.project-header-card h2 {
font-size: 2em;
font-weight: 300;
background-color: black;
color: white;
border-radius: 20px;
width: 105%;
text-align: center;
}
.project-header-card-li {
list-style-type: none;
}
.project-big-card {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1em;
border-radius: 20px;
background-color: white;
color: black;
width: 50%;
padding: 5em;
}
.project-big-card img {
width: 45%;
height: auto;
}
.middle-div-project-big-card {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
gap: 1em;
background-color: black;
color: white;
border-radius: 20px;
width: 75%;
}
.middle-div-project-big-card img {
width: 55%;
height: auto;
}
.down-div-project-big-card h2 {
color: #0693E3;
}
.project-small-card {
background-color: white;
color: black;
border-radius: 20px;
width: 50%;
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
gap: 2em;
}
.project-small-card img {
width: 25%;
height: auto;
border-bottom-left-radius: 20px;
border-top-left-radius: 20px;
}

View File

@@ -1,51 +1,72 @@
import React from 'react';
import { ProjetsHeader } from '../../components/projetheader/projetheader';
import {
ProjectBigCard,
ProjectSmallCard,
} from '../../components/projectcard/projectcard';
import { Timeline, TimelineProject } from '../../components/timeline/timeline';
import './Projets.css';
const Projets: React.FC = () => {
return (
<>
<ProjetsHeader />
<div className={'project-header-container page-contrast'}>
<ProjectBigCard
imgtitle={'https://r2.modelec.club/cdf.png'}
lefttext={{
__html:
"1 robot<br>3000 heures<br>0 compétances<br>10 étudiants<br>1ère participation<br><span style='color: #0693E3;'>14 ème</span> sur 82 équipes",
}}
rightimage={'https://r2.modelec.club/serge.png'}
downtitle={'Notre robot'}
downcontent={
"Voici Serge, notre robot pour la coupe de France de robotique 2024. Il est équipé de 2 roues motrices, 2 roues codeuses, 3 pinces et 2 bras d'orientation pour les panneaux solaires. Il est également équipé d'une caméra pour la vision et d'un lidar pour la détection d'adversaire et la triangulation. Coté hardware, il est géré par un raspberry pi 5 et un arduino mega. Côté software, il est géré par des programmes C++ fait sur mesure dont le code est disponible sur notre github. A coté Serge est accompagné de 2 Pixels, ses PAMI (Partie Autonome Mobile Intelligente) qui sont des robots autonomes qui peuvent se déplacer et se repérer dans l'espace. Ils sont gérés par des arduino uno."
<h1 className={'page-title'}>Cette année</h1>
<TimelineProject
title={'La Coupe de France de Robotique 2025'}
date={'À venir'}
paragraphs={[
<>Cette année encore, nous participons à la <u>Coupe de France de Robotique</u> pour notre <b>deuxième participation</b> !</>,
]}
/>
<h1 className={'page-title'}>Remonter dans le Temps</h1>
<Timeline
projects={[
{
title: 'Serge : Notre robot',
date: '2024',
banner: 'https://r2.modelec.club/serge.png',
paragraphs: [
<>Voici Serge, notre robot pour la <u>coupe de France de Robotique</u> 2024 !</>,
<>Il est équipé de <b>2 roues motrices</b>, <b>2 roues codeuses</b>, <b>3 pinces</b> et <b>2 bras d'orientation</b> pour les panneaux solaires. Il est également équipé d'<b>une caméra</b> pour la vision et d'<b>un LiDAR</b> pour la détection d'adversaire et la triangulation.</>,
<>Coté <u>Hardware</u>, il est géré par un <b>Raspberry Pi 5</b> et un <b>Arduino Mega</b>.</>,
<>Côté <u>Software</u>, il est géré par des programmes <b>C++</b> faits sur mesure dont le code est disponible sur notre Github.</>,
<>Serge n'est pas seul, il est accompagné de <u>2 Pixels</u>, ses <b>Partie Autonome Mobile Intelligente</b> ou <u>PAMI</u> qui sont des robots autonomes gérés par des <b>Arduino Uno</b> qui peuvent se déplacer et se repérer dans l'espace.</>
],
cards: [
{ type: 'stat', data: '3000', label: 'Heures de travail' },
{ type: 'stat', data: '10', label: 'Étudiants' },
{ type: 'stat', data: '2024', label: 'Première participation' },
{ type: 'stat', data: '14', label: '/82 équipes' },
{ type: 'image', src: 'https://r2.modelec.club/cdf.png', alt: 'Logo Coupe de France de Robotique', fit: 'contain' },
],
},
{
title: 'Construction de la table de jeu',
date: '2024',
paragraphs: [
<>Afin de pouvoir tester notre robot, nous avons construit une <b>table de jeu</b> pour la <u>coupe de France de Robotique</u>.</>,
<>Elle est faite en <b>bois</b> et en <b>vinyle</b>.</>,
],
cards: [
{ type: 'image', src: 'https://r2.modelec.club/table2024.jpg', alt: 'Table de jeu pour la Coupe de France de Robotique', fit: 'cover' },
],
},
{
title: 'PAMI v1',
date: '2024',
paragraphs: [
<>Les <b>PAMI v1</b> sont des <b>robots autonomes</b> qui peuvent se déplacer et se repérer dans l'espace.</>,
<>Ils sont gérés par des <b>Arduino Uno</b>.</>,
],
cards: [
{ type: 'image', src: 'https://r2.modelec.club/PAMI-V1.png', alt: 'PAMI v1', fit: 'cover' },
],
},
{
title: 'Digitalisation du bureau',
date: '2024',
paragraphs: [
<>Afin de faciliter la gestion du club, nous avons décidé de <b>digitaliser</b> le <b>bureau</b>.</>,
],
}
/>
<ProjectSmallCard
img={'https://r2.modelec.club/table2024.jpg'}
title={'Constructions tables de jeu CDF'}
content={
'Afin de pouvoir tester notre robot, nous avons construit 1 table de jeu pour la coupe de France de robotique. Elle est faites en bois et en vynile.'
}
/>
<ProjectSmallCard
img={'https://r2.modelec.club/PAMI-V1.png'}
title={'PAMI V1'}
content={
"Les PAMI V1 sont des robots autonomes qui peuvent se déplacer et se repérer dans l'espace. Ils sont gérés par des arduino uno."
}
/>
<ProjectSmallCard
img={'https://r2.modelec.club/digitalisation.png'}
title={'Digitalisation du bureau'}
content={
'Afin de faciliter la gestion du club, nous avons décidé de digitaliser le bureau.'
}
/>
</div>
]}
/>
</>
);
};