diff --git a/site/blueprints/pages/white-paper.yml b/site/blueprints/pages/white-paper.yml new file mode 100644 index 0000000..c97619b --- /dev/null +++ b/site/blueprints/pages/white-paper.yml @@ -0,0 +1,61 @@ +title: Livre blanc +icon: file +status: + draft: + label: Brouillon + text: Non visible + listed: + label: Publié + text: Visible publiquement +tabs: + content: + label: Contenu + icon: text + columns: + main: + width: 2/3 + sections: + header: + type: fields + fields: + intro: + label: Description courte + type: writer + nodes: false + marks: + - bold + - italic + - link + maxlength: 200 + sidebar: + width: 1/3 + sections: + meta: + type: fields + fields: + published: + label: Date de publication + type: date + display: DD/MM/YYYY + required: true + default: today + translate: false + cover: + label: Image de couverture + type: files + layout: cards + max: 1 + accept: image/* + translate: false + image: + cover: true + ratio: 3/4 + uploads: + template: image + downloadFile: + label: Fichier PDF + type: files + max: 1 + accept: application/pdf + translate: false + help: Fichier téléchargé après soumission du formulaire diff --git a/site/blueprints/pages/white-papers.yml b/site/blueprints/pages/white-papers.yml new file mode 100644 index 0000000..816c625 --- /dev/null +++ b/site/blueprints/pages/white-papers.yml @@ -0,0 +1,43 @@ +title: Livres blancs +icon: book +status: + draft: + label: Brouillon + text: La page est accessible uniquement pour les éditeurs connectés + listed: + label: Public + text: La page est accessible par tout le monde +tabs: + content: + label: Contenu + icon: text + sections: + content: + type: fields + fields: + intro: + type: writer + marks: + - bold + - italic + - green + - pixel + - underline + - strike + - clear + - link + nodes: + - heading + headings: + - 1 + help: Section de texte centrée (optionnelle). + items: + label: Livres blancs + type: pages + layout: cards + sortBy: published desc + template: white-paper + image: + ratio: 3/4 + cover: true + info: "{{ page.published.toDate('d/m/Y') }}" diff --git a/site/config/config.php b/site/config/config.php index c556463..c88a313 100644 --- a/site/config/config.php +++ b/site/config/config.php @@ -11,4 +11,27 @@ return [ ], 'thumbs' => require __DIR__ . '/thumbs.php', + + 'routes' => [ + [ + 'pattern' => ['(:any)/(:any)/download', 'en/(:any)/(:any)/download'], + 'method' => 'POST', + 'action' => function (string $parent, string $slug) { + $page = kirby()->page($parent . '/' . $slug); + if (!$page || $page->intendedTemplate()->name() !== 'white-paper') { + http_response_code(404); + header('Content-Type: application/json'); + echo json_encode(['error' => 'Not found']); + exit; + } + // TODO: store/email form data ($kirby->request()->body()) + header('Content-Type: application/json'); + echo json_encode([ + 'success' => true, + 'fileUrl' => $page->downloadFile()->toFile()?->url(), + ]); + exit; + } + ] + ], ]; diff --git a/site/config/menu.php b/site/config/menu.php index ab988d0..c88dcc5 100644 --- a/site/config/menu.php +++ b/site/config/menu.php @@ -29,7 +29,8 @@ return [ 'portfolio' => menuItem('portfolio', 'Portfolio','images', 'pages/portfolio'), 'jouer' => menuItem('jouer', 'Jouer', 'play', 'pages/jouer'), 'a-propos' => menuItem('a-propos', 'À propos', 'users', 'pages/a-propos'), - 'blog' => menuItem('blog', 'Blog', 'text', 'pages/blog'), + 'blog' => menuItem('blog', 'Blog', 'text', 'pages/blog'), + 'white-papers' => menuItem('livres-blancs', 'Livres blancs', 'book', 'pages/livres-blancs'), '-', 'users', 'system', diff --git a/site/templates/white-paper.json.php b/site/templates/white-paper.json.php new file mode 100644 index 0000000..852ae95 --- /dev/null +++ b/site/templates/white-paper.json.php @@ -0,0 +1,13 @@ + $page->published()->toDate('d/m/Y'), + 'intro' => $page->intro()->value(), + 'cover' => $page->cover()->toFile()?->url(), + 'fileUrl' => $page->downloadFile()->toFile()?->url(), +]; + +$pageData = array_merge($genericData, $specificData); + +header('Content-Type: application/json'); +echo json_encode($pageData); diff --git a/site/templates/white-paper.php b/site/templates/white-paper.php new file mode 100644 index 0000000..f31b64d --- /dev/null +++ b/site/templates/white-paper.php @@ -0,0 +1,2 @@ + + diff --git a/site/templates/white-papers.json.php b/site/templates/white-papers.json.php new file mode 100644 index 0000000..cfdce03 --- /dev/null +++ b/site/templates/white-papers.json.php @@ -0,0 +1,26 @@ +children()->listed()->sortBy('published', 'desc'); + +$mapItem = function ($item) { + return [ + 'title' => $item->title()->value(), + 'slug' => $item->slug(), + 'published' => $item->published()->toDate('d/m/Y'), + 'intro' => $item->intro()->value(), + 'cover' => $item->cover()->toFile()?->url(), + ]; +}; + +$singleSlug = $items->count() === 1 ? $items->first()->slug() : null; + +$specificData = [ + 'intro' => $page->intro()->value(), + 'items' => $items->map($mapItem)->values(), + 'singleSlug' => $singleSlug, +]; + +$pageData = array_merge($genericData, $specificData); + +header('Content-Type: application/json'); +echo json_encode($pageData); diff --git a/site/templates/white-papers.php b/site/templates/white-papers.php new file mode 100644 index 0000000..f31b64d --- /dev/null +++ b/site/templates/white-papers.php @@ -0,0 +1,2 @@ + + diff --git a/src/App.svelte b/src/App.svelte index daa35b0..9595968 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -16,6 +16,7 @@ import Game from '@views/Game.svelte' import Blog from '@views/Blog.svelte' import Article from '@views/Article.svelte' + import WhitePapers from '@views/WhitePapers.svelte' import Default from '@views/Default.svelte' const templates = { @@ -28,6 +29,7 @@ game: Game, blog: Blog, article: Article, + 'white-papers': WhitePapers, default: Default } diff --git a/src/components/layout/Footer.svelte b/src/components/layout/Footer.svelte index 767047e..2fe610c 100644 --- a/src/components/layout/Footer.svelte +++ b/src/components/layout/Footer.svelte @@ -124,7 +124,7 @@ margin-left: -16.6vw; } - :global(.blog .page-scrollable-footer) { + :global(.collection .page-scrollable-footer) { margin-left: -12.4vw; margin-top: 5rem; } diff --git a/src/i18n/index.js b/src/i18n/index.js index 21f2f6d..1213085 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -47,6 +47,19 @@ const dict = { privacy: { fr: "Confidentialité", en: "Privacy" }, // About our_team: { fr: "NOTRE ÉQUIPE", en: "OUR TEAM" }, + // White Papers + white_paper_label: { fr: "LIVRE BLANC", en: "WHITE PAPER" }, + read_wp: { fr: "Télécharger", en: "Download" }, + wp_form_intro: { fr: "Renseignez vos informations pour télécharger notre livre blanc.", en: "Fill in your information to download our white paper." }, + wp_firstname: { fr: "Prénom*", en: "First name*" }, + wp_lastname: { fr: "Nom*", en: "Last name*" }, + wp_company: { fr: "Société*", en: "Company*" }, + wp_role: { fr: "Fonction*", en: "Role*" }, + wp_email: { fr: "E-mail*", en: "E-mail*" }, + wp_consent: { fr: "En cochant cette case, j'accepte d'être recontacté par la société World Game. Mes données ne seront ni vendues, ni partagées.", en: "By checking this box, I agree to be contacted by World Game. My data will not be sold or shared." }, + wp_download: { fr: "TÉLÉCHARGEMENT", en: "DOWNLOAD" }, + wp_success: { fr: "Votre demande a été enregistrée. Le téléchargement devrait démarrer.", en: "Your request has been registered. The download should start." }, + wp_error: { fr: "Une erreur est survenue, veuillez réessayer.", en: "An error occurred, please try again." }, // Menu menu: { fr: "MENU", en: "MENU" }, connect: { fr: "CONNECT", en: "CONNECT" }, diff --git a/src/styles/collection.css b/src/styles/collection.css new file mode 100644 index 0000000..1312a19 --- /dev/null +++ b/src/styles/collection.css @@ -0,0 +1,180 @@ +/* Shared styles for collection pages (Blog, WhitePapers) */ + +/* --- Header / Intro --- */ +.collection-header { + text-align: center; + padding: 6rem 0 3rem; + max-width: 40rem; + margin: auto; +} + +.collection-header h1 { + font-size: var(--font-size-title-main); + text-transform: uppercase; + margin-bottom: 2rem; +} + +.collection-header p { + font-size: var(--font-size-subtitle); + font-weight: 400; +} + +.collection-header :global(h1) { + font-family: "Terminal", sans-serif; + font-size: var(--font-size-title-main); + text-transform: uppercase; + margin-bottom: 1.5rem; +} + +.collection-header :global(p) { + font-size: var(--font-size-subtitle); + line-height: 1.6; + max-width: 640px; + margin: 0 auto; + opacity: 0.9; +} + +/* --- Card --- */ +.collection-card { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 2rem; + padding: 1.5rem 0; +} + +.collection-card-text { + flex: 1; + display: flex; + flex-direction: column; + gap: 1rem; + max-width: 640px; +} + +.collection-card-date { + color: #d9d9d9; + font-size: var(--font-size-paragraph); +} + +.collection-card-title { + font-family: "Danzza", sans-serif; + font-size: 40px; + max-width: 80%; + font-weight: 700; +} + +.collection-card-title a { + transition: color 0.2s; +} + +.collection-card-title a:hover { + color: var(--color-primary); +} + +.collection-card-description { + color: #d9d9d9; + font-family: "Danzza", sans-serif; + font-size: var(--font-size-paragraph); + font-weight: 400; +} + +.collection-card-readmore { + color: var(--color-primary); + font-family: "Danzza", sans-serif; + font-size: var(--font-size-paragraph); + font-weight: 500; + text-transform: uppercase; +} + +.collection-card-readmore .arrow { + margin-left: 5px; +} + +/* --- Image --- */ +.collection-card-image img { + width: 300px; + height: 169px; + object-fit: cover; + transition: transform 0.3s; +} + +.collection-card-image img:hover { + transform: scale(1.05); +} + +.collection-card-image--featured img { + width: auto; + height: 300px; +} + +/* --- Divider --- */ +.collection-divider { + border: none; + border-top: 1px solid rgba(255, 255, 255, 0.15); + margin: 0; +} + +/* --- Featured --- */ +.collection-card--featured .collection-card-title { + font-size: 36px; + line-height: 1.3; +} + +/* --- Loading --- */ +.collection-loading { + text-align: center; + padding: 4rem 0; + opacity: 0.6; +} + +/* --- Mobile --- */ +@media (max-width: 700px) { + .collection-header { + padding: 4rem 0 2rem; + } + + .collection-header :global(h1) { + font-size: var(--font-size-title-main-mobile); + } + + .collection-header :global(p) { + font-size: var(--font-size-subtitle-mobile); + } + + .collection-card { + flex-direction: column; + } + + .collection-card-image img, + .collection-card-image--featured img { + width: 100%; + height: auto; + aspect-ratio: 16/9; + } + + .collection-card--featured .collection-card-title { + font-size: var(--font-size-title-section-mobile); + } + + .collection-card-title { + font-size: var(--font-size-title-section-mobile); + } +} + +/* --- Tablet --- */ +@media (min-width: 701px) and (max-width: 912px) { + .collection-header :global(h1) { + font-size: var(--font-size-title-main-tablet); + } + + .collection-card { + flex-direction: column; + } + + .collection-card-image img, + .collection-card-image--featured img { + width: 100%; + height: auto; + aspect-ratio: 16/9; + } +} diff --git a/src/styles/fonts.css b/src/styles/fonts.css index 6b34a2a..33a5c1d 100644 --- a/src/styles/fonts.css +++ b/src/styles/fonts.css @@ -65,3 +65,7 @@ background-clip: text; -webkit-background-clip: text; } + +.pixel { + font-family: "Terminal", sans-serif; +} diff --git a/src/styles/index.css b/src/styles/index.css index d437c36..0db6dc0 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -3,6 +3,7 @@ @import './reset.css'; @import './fonts.css'; @import './layout.css'; +@import './collection.css'; @import './buttons.css'; @import './cursor.css'; @import './utils.css'; diff --git a/src/views/Blog.svelte b/src/views/Blog.svelte index d4295b6..9dd0b1f 100644 --- a/src/views/Blog.svelte +++ b/src/views/Blog.svelte @@ -106,7 +106,7 @@
{#if data?.intro} -
+
{@html data.intro}
{/if} {#if featured} -