Skip to content
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

Vu sur/v0 #62

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions TRANSLATIONS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

- [FAQ](src/posts/faq.md) - Original: [FAQ](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/faq.md)
- [Passez à l’action](src/posts/agir.md) - Original: [Take action](https://github.com/PauseAI/pauseai-website/blob/95be1d5327015a2c41f5c518d92812d7f6c79bda/src/posts/action.md)
- [Rejoignez Pause IA](src/posts/nous-rejoindre.md) - Original: [Join PauseAI](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/join.md)
- [Faire un don à Pause IA](src/posts/dons.md) - Original: [Donate to PauseAI](https://github.com/PauseAI/pauseai-website/blob/03a62f1a06c6a2eac0f3fc79a2bbc7a7083bd31e/src/posts/donate.md)
- [Qui sommes-nous ?](src/posts/qui-sommes-nous.md) - Original: [QUI](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/faq.md)
- [FAQ](src/posts/faq.md) - Original: [FAQ](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/faq.md)
- [Rejoignez Pause IA](src/posts/nous-rejoindre.md) - Original: [Join PauseAI](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/join.md)
- [Propositions de Pause IA](src/posts/propositions.md) - Original: [PauseAI Proposal](https://github.com/PauseAI/pauseai-website/blob/0cabfef1037097bd7a99f4fddd1bcd73abbe6760/src/posts/proposal.md)
- [Qui sommes-nous ?](src/posts/qui-sommes-nous.md) - Original: [QUI](https://github.com/PauseAI/pauseai-website/blob/5950ca0185d6e7cf52e2416e795acfab7222dace/src/posts/faq.md)
1 change: 1 addition & 0 deletions src/lib/components/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<h2>Autres</h2>
<a href="/mentions-legales">Mentions légales</a>
<a href="/politique-de-confidentialite">Politique de confidentialité</a>
<a href="/charte-des-valeurs">Charte des valeurs</a>
<ExternalLink href="https://creativecommons.org/licenses/by/4.0/deed.fr" target="_blank"
>Licence: CC-BY 4.0</ExternalLink
>
Expand Down
6 changes: 2 additions & 4 deletions src/lib/components/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@
</script>

<Banner>
«{'\u00A0'}IA{'\u00A0'}: nos craintes pour la France{'\u00A0'}» |
<a href="https://contre-rapport-ia.fr/" target="_blank"
>Lisez notre contre-expertise du Rapport de la Commission de l’IA</a
>
Rejoignez la manifestation internationale de PauseAI
<a href="https://lu.ma/0tjhnnf9?tk=MlIZ1d" target="_blank">à Paris le 22 novembre !</a>
</Banner>

<!-- probably have to change nav colors and classes to respond to banner presence instead of route -->
Expand Down
142 changes: 142 additions & 0 deletions src/lib/components/home/VuSur.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<script lang="ts">
import { onMount } from 'svelte'
import UnderlinedTitle from '$components/UnderlinedTitle.svelte'
const label_id = 'logos-title'

let logosData: { src: string; alt: string; url: string }[] = []

// Vos paramètres existants
let logoWidth = 110
let logoHeight = 110
let logoGap = 50
let logoMargin = 0
let sectionPaddingTop = 10
let sectionPaddingBottom = 10
let hoverScale = 1.1
let maxLogos = 10

onMount(async () => {
try {
const response = await fetch('/src/posts/vu-sur.md')
if (!response.ok) {
console.error('Échec du chargement du fichier vu-sur.md:', response.statusText)
return
}
const text = await response.text()

// Votre code existant pour traiter le fichier Markdown
const lines = text
.split('\n')
.map((line) => line.trim())
.filter((line) => line)
const maxLogosLine = lines.find((line) => line.startsWith('#maxLogos='))
if (maxLogosLine) {
maxLogos = parseInt(maxLogosLine.replace('#maxLogos=', '').trim(), 10) || maxLogos
lines.splice(lines.indexOf(maxLogosLine), 1)
}
const logosLines = lines.filter(
(line) => !line.startsWith('#') && !line.startsWith('<!--') && line.includes('|')
)
logosData = logosLines
.slice(0, maxLogos + 1)
.map((line) => {
const parts = line.split('|').map((part) => part.trim())
if (parts.length !== 3) {
console.warn(`Format de ligne invalide : "${line}"`)
return null
}
const [src, alt, url] = parts
return { src, alt, url }
})
.filter(
(logo): logo is { src: string; alt: string; url: string } =>
logo !== null && isValidLogo(logo)
)
} catch (error) {
console.error('Erreur lors du traitement du fichier Markdown :', error)
}
})

function isValidLogo(logo: { src: string; alt: string; url: string }): boolean {
return (
typeof logo.src === 'string' &&
logo.src.trim() !== '' &&
typeof logo.alt === 'string' &&
logo.alt.trim() !== '' &&
typeof logo.url === 'string' &&
logo.url.trim() !== ''
)
}

function handleImageError(event: Event, src: string) {
console.error('Image introuvable :', src)
const target = event.currentTarget as HTMLImageElement
target.style.display = 'none'
}
</script>

<section
aria-labelledby={label_id}
class="logos-section"
style="padding-top: {sectionPaddingTop}px; padding-bottom: {sectionPaddingBottom}px;"
>
<UnderlinedTitle id={label_id}>Nos apparitions médiatiques</UnderlinedTitle>
<div class="logos-container" style="gap: {logoGap}px;">
{#each logosData as logo}
<a
href={logo.url}
target="_blank"
rel="noopener noreferrer"
class="logo-wrapper"
style="margin-left: {logoMargin}px; margin-right: {logoMargin}px;"
>
<img
src={logo.src}
alt={logo.alt}
class="logo"
style="width: {logoWidth}px; height: {logoHeight}px;"
on:error={(event) => handleImageError(event, logo.src)}
/>
</a>
{/each}
</div>
</section>

<style>
/* Style de la section principale */
.logos-section {
width: 100%;
text-align: left;
}

/* Le reste de votre CSS reste inchangé */
.logos-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}

.logo-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
transition:
transform 0.3s ease,
filter 0.3s ease;
}

.logo {
width: 100%;
height: 100%;
object-fit: contain;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
border-radius: 8px;
}

.logo-wrapper:hover,
.logo-wrapper:focus {
transform: scale(1.1);
filter: brightness(1.1);
}
</style>
159 changes: 122 additions & 37 deletions src/lib/components/home/articles.svelte
Original file line number Diff line number Diff line change
@@ -1,63 +1,148 @@
<script lang="ts">
import { onMount } from 'svelte'
import ArticleCard from '$components/ArticleCard.svelte'
import Button from '$components/Button.svelte'
import UnderlinedTitle from '$components/UnderlinedTitle.svelte'

const label_id = 'articles-title'

let articles: { title: string; blurb: string; url: string }[] = []
let title = ''
let maxArticles = 12

onMount(async () => {
const response = await fetch('/src/posts/articles.md')
if (!response.ok) {
console.error('Failed to fetch articles.md:', response.statusText)
return
}
const text = await response.text()
const { content, metadata } = parseMarkdown(text)
title = metadata.title
maxArticles = metadata.maxArticles || Infinity
articles = parseArticles(content).slice(0, maxArticles) as {
title: string
blurb: string
url: string
}[]
document.documentElement.style.setProperty('--columns', Math.ceil(maxArticles / 2).toString())

// Restaurer la position de défilement lors du retour
const scrollPosition = localStorage.getItem('scrollPosition')
if (scrollPosition) {
window.scrollTo(0, parseInt(scrollPosition, 10))
localStorage.removeItem('scrollPosition')
}
})

function parseMarkdown(text: string) {
const [metadata, ...content] = text.split('---').slice(1)
const metadataObj = Object.fromEntries(
metadata
.trim()
.split('\n')
.map((line) => line.split(': ').map((str) => str.trim()))
)
return { metadata: metadataObj, content: content.join('---') }
}

function parseArticles(content: string) {
const articles = []
const lines = content.split('\n').filter((line) => line.trim() !== '')
let article: { title?: string; blurb?: string; url?: string } = {}
for (const line of lines) {
if (line.startsWith('- title:')) {
if (Object.keys(article).length > 0) {
articles.push(article)
article = {}
}
article.title = line.replace('- title:', '').trim()
} else if (line.startsWith(' blurb:')) {
article.blurb = line.replace(' blurb:', '').trim()
} else if (line.startsWith(' url:')) {
article.url = line.replace(' url:', '').trim()
}
}
if (Object.keys(article).length > 0) {
articles.push(article)
}
return articles
}

// Stocker la position de défilement avant de naviguer
function handleButtonClick() {
localStorage.setItem('scrollPosition', window.scrollY.toString())
window.location.href = 'https://pauseia.substack.com/'
}

// Stocker la position de défilement avant de naviguer vers un article
function handleArticleClick(url: string) {
localStorage.setItem('scrollPosition', window.scrollY.toString())
window.location.href = url
}

// Gestionnaire d'événements clavier pour les articles
function handleKeyDown(event: KeyboardEvent, url: string) {
if (event.key === 'Enter' || event.key === ' ') {
handleArticleClick(url)
}
}
</script>

<section aria-labelledby={label_id}>
<UnderlinedTitle id={label_id}>Nos articles mis en avant</UnderlinedTitle>
<UnderlinedTitle id={label_id}>{title}</UnderlinedTitle>
<div class="articles-grid">
<ArticleCard
title="L’IA et la Cybersécurité"
blurb="Les systèmes d'IA peuvent déjà analyser et écrire du code, identifier des vulnérabilités et les exploiter."
url="https://pauseia.substack.com/p/lia-et-la-cybersecurite"
/>
<ArticleCard
title="Quatre niveaux de réglementation de l’IA"
blurb="Clarifier et mesurer l'efficacité des réglementations aux différentes étapes du processus de création d'un modèle."
url="https://pauseia.substack.com/p/quatre-niveaux-de-reglementation"
/>
<ArticleCard
title="Classement p(doom) des scientifiques"
blurb="L'estimation du potentiel de destruction de l'IA par les scientifiques du secteur de l'IA"
url="https://pauseia.substack.com/p/classement-pdoom-des-scientifiques"
/>
<ArticleCard
title="Les risques existentiels liés à une superintelligence artificielle"
blurb="Monteriez-vous dans un prototype d’avion dont les ingénieurs aéronautiques estiment qu’il a 14{'\u202F'}% de chances de s’écraser{'\u202F'}?"
url="https://pauseia.substack.com/p/les-risques-existentiels-lies-a-une"
/>
<ArticleCard
title="Les modèles d’IA face aux humains"
blurb="Où en sont les modèles les plus récents par rapport à l'intelligence humaine{'\u202F'}?"
url="https://pauseia.substack.com/p/les-modeles-dia-face-aux-humains"
/>
<ArticleCard
title="Pourquoi une superintelligence pourrait apparaître plus tôt que prévu"
blurb="L'accélération exponentielle des progrès en IA et ses implications alarmantes"
url="https://pauseia.substack.com/p/pourquoi-une-superintelligence-pourrait"
/>
{#each articles as article}
<div
role="button"
tabindex="0"
on:click={() => handleArticleClick(article.url)}
on:keydown={(event) => handleKeyDown(event, article.url)}
class="article-card"
>
<ArticleCard title={article.title} blurb={article.blurb} url={article.url} />
</div>
{/each}
</div>
<div style="margin-top: 2rem; text-align: left;">
<Button on:click={handleButtonClick}>Voir tous les articles</Button>
</div>
<Button href="https://pauseia.substack.com/">Voir tous les articles</Button>
</section>

<style>
.articles-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
margin-bottom: 2rem; /* Ajoute de l'espace en dessous des articles */
}

.article-card {
text-align: left; /* Aligner à gauche le contenu des articles */
cursor: pointer; /* Indiquer que l'élément est cliquable */
}

@media (min-width: 1200px) {
.articles-grid {
grid-template-columns: repeat(var(--columns), 1fr);
}
}

@media (min-width: 900px) and (max-width: 1199px) {
.articles-grid {
grid-template-columns: repeat(2, 1fr);
}
}

@media (min-width: 640px) {
@media (min-width: 600px) and (max-width: 899px) {
.articles-grid {
grid-template-columns: 1fr 1fr;
grid-template-columns: repeat(2, 1fr);
}
}

@media (min-width: 1024px) {
@media (max-width: 599px) {
.articles-grid {
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr;
}
}
</style>
Loading