diff --git a/next.config.mjs b/next.config.mjs index 5bf1654..b1ee349 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -13,6 +13,15 @@ const nextConfig = { }) return config }, + async redirects() { + return [ + { + source: '/grist-2024-qr', + destination: '/grist-paris-summit-2024#agenda', + permanent: true, + }, + ] + }, } export default nextConfig diff --git a/src/fonts/README.md b/src/fonts/README.md index f308dee..3b9252f 100644 --- a/src/fonts/README.md +++ b/src/fonts/README.md @@ -15,7 +15,7 @@ Doing this is OK while we control 100% of the content we render. For now the sub > Glyphhanger is not integrated locally as it requires a few python dependencies… if needed, install glyphhanger locally on your machine to update the files. > Glyphhanger v5.0.0 was used. -Command used to generate files in this folder: +Command used to generate files in this folder (please update it as you add characters): ```bash # pwd = src/fonts @@ -23,7 +23,7 @@ glyphhanger \ --subset="./sources/*.woff2" \ --formats=woff2 \ --output=./subsetted \ - --whitelist="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀàâÇçèÉÊËéêëÏîïÔôùûŒœÆ  &•#…€$~˚°%\_=+-×÷\*/[]{}()<>,.:;?@«»©™←↑→↓↖↗↘↙√≤≥'\!\’\“\”\\\`\"" + --whitelist="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀàâäÇçèÉÊËéêëÏîïÔôùûŒœÆłń  &•#…€$~˚°%\_=+-×÷\*/[]{}()<>,.:;?@«»©™←↑→↓↖↗↘↙√≤≥'\!\’\“\”\\\`\"" ``` You guessed it: the important part of the command is the `whitelist` param that lists all characters we want to keep in the subsetted file. diff --git a/src/fonts/subsetted/Marianne-Bold-subset.woff2 b/src/fonts/subsetted/Marianne-Bold-subset.woff2 index 09aa43b..a6eb0f7 100644 Binary files a/src/fonts/subsetted/Marianne-Bold-subset.woff2 and b/src/fonts/subsetted/Marianne-Bold-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Bold_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-Bold_Italic-subset.woff2 index 4dac51d..53eddc3 100644 Binary files a/src/fonts/subsetted/Marianne-Bold_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-Bold_Italic-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-ExtraBold-subset.woff2 b/src/fonts/subsetted/Marianne-ExtraBold-subset.woff2 index 0d35dc8..60a32c6 100644 Binary files a/src/fonts/subsetted/Marianne-ExtraBold-subset.woff2 and b/src/fonts/subsetted/Marianne-ExtraBold-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-ExtraBold_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-ExtraBold_Italic-subset.woff2 index 6c9ea28..2fd19ea 100644 Binary files a/src/fonts/subsetted/Marianne-ExtraBold_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-ExtraBold_Italic-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Light-subset.woff2 b/src/fonts/subsetted/Marianne-Light-subset.woff2 index f3e66d2..ac418b3 100644 Binary files a/src/fonts/subsetted/Marianne-Light-subset.woff2 and b/src/fonts/subsetted/Marianne-Light-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Light_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-Light_Italic-subset.woff2 index e472768..2606257 100644 Binary files a/src/fonts/subsetted/Marianne-Light_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-Light_Italic-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Medium-subset.woff2 b/src/fonts/subsetted/Marianne-Medium-subset.woff2 index 8f4512c..91ddace 100644 Binary files a/src/fonts/subsetted/Marianne-Medium-subset.woff2 and b/src/fonts/subsetted/Marianne-Medium-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Medium_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-Medium_Italic-subset.woff2 index 66b254f..b741bba 100644 Binary files a/src/fonts/subsetted/Marianne-Medium_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-Medium_Italic-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Regular-subset.woff2 b/src/fonts/subsetted/Marianne-Regular-subset.woff2 index b75fc46..dfb56a0 100644 Binary files a/src/fonts/subsetted/Marianne-Regular-subset.woff2 and b/src/fonts/subsetted/Marianne-Regular-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Regular_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-Regular_Italic-subset.woff2 index 0494ada..5a0ef22 100644 Binary files a/src/fonts/subsetted/Marianne-Regular_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-Regular_Italic-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Thin-subset.woff2 b/src/fonts/subsetted/Marianne-Thin-subset.woff2 index 5f031ed..9132aec 100644 Binary files a/src/fonts/subsetted/Marianne-Thin-subset.woff2 and b/src/fonts/subsetted/Marianne-Thin-subset.woff2 differ diff --git a/src/fonts/subsetted/Marianne-Thin_Italic-subset.woff2 b/src/fonts/subsetted/Marianne-Thin_Italic-subset.woff2 index 8e7a917..e5ae6a1 100644 Binary files a/src/fonts/subsetted/Marianne-Thin_Italic-subset.woff2 and b/src/fonts/subsetted/Marianne-Thin_Italic-subset.woff2 differ diff --git a/src/pages/grist-paris-summit-2024.tsx b/src/pages/grist-paris-summit-2024.tsx index 8710964..4813498 100644 --- a/src/pages/grist-paris-summit-2024.tsx +++ b/src/pages/grist-paris-summit-2024.tsx @@ -1,4 +1,10 @@ -import { ReactNode, useEffect } from 'react' +import { + Children, + cloneElement, + HTMLAttributes, + ReactNode, + useEffect, +} from 'react' import { Layout } from '@/components/Layout' import { ContentSection } from '@/components/ContentSection' import { DoubleBlock } from '@/sections/DoubleBlock' @@ -9,30 +15,233 @@ import SuiteLogo from '@/assets/logo/suite-numerique.svg' import GristGouvLogo from '@/assets/grist-summit/gristgouv-hex.svg' import GristDinum from '@/assets/grist-summit/grist-and-dinum.png' -const ProgramItem = ({ +const ThemeIcon = ({ + theme, + size, + withAlt = true, +}: { + theme: 'real-world' | 'power-user' | 'commons' + size?: 'xs' + withAlt?: boolean +}) => { + const label = `Theme: ${ + theme === 'real-world' + ? `Real-world Grist Examples` + : theme === 'power-user' + ? 'Become a Grist Power User' + : 'The La Suite Project and Digital Commons' + }` + return ( + + {withAlt && {label}} + {theme === 'real-world' && ( + + )} + {theme === 'power-user' && ( + + )} + {theme === 'commons' && ( + + )} + + ) +} + +/** specific timeslots shenanigans to take less space on unimportant stuff + * yes this is a mess + **/ +const adjustVerticalSpaceAndPos = (hourAndMinutes: number) => { + let verticalPosAdjustment = 0 + let verticalSpace = 0 + if ([9, 10, 12.5, 15.5].includes(hourAndMinutes)) { + verticalSpace = 1 + } + if (hourAndMinutes !== 9) { + verticalPosAdjustment -= 1 + } + if (hourAndMinutes > 10) { + } + if (hourAndMinutes > 12.5) { + verticalPosAdjustment -= 5 + } + if (hourAndMinutes > 14) { + verticalPosAdjustment += 1 + } + if (hourAndMinutes > 15.5) { + } + return { verticalPosAdjustment, verticalSpace } +} + +const AgendaTimespot = ({ + fr, + en, + rows = 1, +}: { + fr: string + en: string + rows?: number +}) => { + const fullTimeslot = fr.endsWith('h') ? `${fr}00` : fr + const hour = Number(fullTimeslot.slice(0, -3)) + const minutes = Number(fullTimeslot.slice(-2)) + const hourAndMinutes = hour + minutes / 60 + let verticalPos = 1 + (hour - 9) * 4 + (minutes > 0 ? (minutes / 60) * 4 : 0) + const adjustment = adjustVerticalSpaceAndPos(hourAndMinutes) + verticalPos += adjustment.verticalPosAdjustment + return ( + + ) +} + +const AgendaRooms = ({ row }: { row: number }) => { + return ( + <> + + Main Stage + + + Big Table + + + Classrooms + + + ) +} + +const AgendaItem = ({ time, + stage, + duration, + theme, + type, title, author, children, }: { - time: string - title: string + time: + | '9h' + | '9h30' + | '9h45' + | '10h' + | '10h30' + | '11h' + | '11h30' + | '12h' + | '12h30' + | '14h' + | '14h30' + | '15h' + | '15h30' + | '16h' + | '16h30' + | '17h' + | '17h15' + title: ReactNode author?: string + type?: 'informal' + stage: 'main' | 'table' | 'classrooms' | 'break' | 'plenary' + theme?: 'real-world' | 'power-user' | 'commons' + duration: '15m' | '30m' | '45m' | '1h' | '1h30' + className?: string children?: ReactNode }) => { + // col-span-3 row-span-1 row-span-2 row-span-3 row-span-4 row-span-5 row-span-6 col-start-1 col-start-2 col-start-3 col-start-4 col-start-5 + // row-start-1 row-start-2 row-start-3 row-start-4 row-start-5 row-start-6 row-start-7 + // row-start-8 row-start-9 row-start-10 row-start-11 row-start-12 row-start-13 + // row-start-14 row-start-15 row-start-16 row-start-17 row-start-18 row-start-19 row-start-20 row-start-21 + // row-start-22 row-start-23 row-start-24 row-start-25 row-start-26 row-start-27 row-start-28 row-start-29 + // row-start-30 row-start-31 row-start-32 row-start-33 row-start-34 + const fullTimeslot = time.endsWith('h') ? `${time}00` : time + const hour = Number(fullTimeslot.slice(0, -3)) + const minutes = Number(fullTimeslot.slice(-2)) + const hourAndMinutes = hour + minutes / 60 + + const stageStyles = + stage === 'break' + ? 'mb-2 md:mb-4 p-2 lg:p-4' + : 'mb-2 md:mb-4 p-2 lg:p-4 lg:shadow border border-[#6a6af4] bg-[#fafafa] bsg-[#e3e3fd]' + const typeStyles = type === 'informal' ? 'border-dashed' : '' + + let verticalPos = 1 + (hour - 9) * 4 + (minutes > 0 ? (minutes / 60) * 4 : 0) + let verticalSpace = + duration === '15m' + ? 1 + : duration === '30m' + ? 2 + : duration === '45m' + ? 3 + : duration === '1h' + ? 4 + : 6 + + const adjustment = adjustVerticalSpaceAndPos(hourAndMinutes) + verticalPos += adjustment.verticalPosAdjustment + if (adjustment.verticalSpace) { + verticalSpace = adjustment.verticalSpace + } + const stagesColStart = stage === 'main' ? 2 : stage === 'table' ? 3 : 4 + const inSpecificTrack = + stage === 'main' || stage === 'table' || stage === 'classrooms' return ( -
-
-

- {time} -

-

- {title} -

- {!!author && ( -

{author}

- )} - {!!children &&
{children}
} +
+
+

+ {time} + {title} +

+
+ {theme && } +
+

Duration: {duration}

+ {!!author && ( +

+ {author} +

+ )} +
+ {typeof children === 'string' ?

{children}

: children} +
+
) } @@ -42,12 +251,37 @@ export default function GristParisSummit2024() { document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener('click', function (e) { e.preventDefault() - + history.pushState( + null, + '', + document.location.pathname + anchor.getAttribute('href')! + ) document.querySelector(anchor.getAttribute('href')!)?.scrollIntoView({ behavior: 'smooth', }) }) }) + + const content = document.querySelector( + '.js-horizontal-scroll-content' + )! + const container = document.querySelector( + '.js-horizontal-scroll-container' + )! + const shadow = document.querySelector( + '.js-horizontal-scroll-shadow' + )! + const updateShadowOpacity = () => { + const contentScrollWidth = content.scrollWidth - container.offsetWidth + console.log(contentScrollWidth) + + const currentScroll = content.scrollLeft / contentScrollWidth + shadow.style.opacity = + contentScrollWidth > 0 ? `${1 - currentScroll}` : '0' + } + content.addEventListener('scroll', updateShadowOpacity) + window.addEventListener('resize', updateShadowOpacity) + updateShadowOpacity() }, []) return ( @@ -83,17 +317,15 @@ export default function GristParisSummit2024() {
-
+
- {/* - program will be up soon, just keep this until we have the content to prevent having to think about how to display it later -
- -
*/} +
@@ -178,31 +410,327 @@ export default function GristParisSummit2024() { + +

+ We speak english! +

+
+

+ La majeure partie de l'évènement se déroulera{' '} + en anglais afin d'inclure nos partenaires + internationaux dans les discussions. +

+

+ Une transcription et traduction en direct de + certaines prises de paroles publiques aura lieu. +

+
+
+ -
+

Programme

- Le programme détaillé sera bientôt disponible. + Les portes ouvrent à 9h. Les conférences se déroulent en anglais + dans trois salles (Main Stage,{' '} + Big Table et Classrooms) et sont + réparties en trois thématiques : +

+
    +
  • + + + + + exemples concrets d'utilisation de Grist + +
  • +
  • + + + + + devenir expert·e de Grist + +
  • +
  • + + + + + La Suite numérique et les communs numériques + +
  • +
+

+ Des transcriptions en anglais et français, ainsi qu'une traduction + en français en direct ont lieu pour les conférences du{' '} + Main Stage. +

+

+ Le programme est détaillé en anglais.

- {/* program will be up soon, just keep this until we have the content to prevent having to think about how to display it later -
    + +
    + + - - -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce - condimentum efficitur massa, vel gravida augue ultrices vel. - Etiam massa leo, mattis at nunc nec, laoreet molestie ante. -

    -
    -
*/} + id="agenda" + className="js-horizontal-scroll-content mt-16 w-full overflow-x-auto" + > +
+ + + + + + + + + + + + + + + + + + + + + + + {/* 9h */} + + Get a coffee and meet the team before the first conference + + {/* 9h30 */} + + {/* 9h45 */} + + {/* 10h */} + + {/* 10h30 */} + + + + + + {/* 11h30 */} + + + Come and chat about anything Grist with the teams and the + audience + + + Come and chat with the audience and Grégoire from the + Grist.gouv team + + {/* 12h30 */} + + No need to rush, you have an hour and a half to eat + + {/* 14h */} + + {/* 14h30 */} + + + + + {/* 15h30 */} + + {/* 16h */} + + + + + Come and chat with the audience and Lucie from the Grist.gouv + team + + + + Dramä Cocktail Bar, 48 rue de l’Échiquier, 75010 Paris + +
+
+
@@ -242,23 +770,6 @@ export default function GristParisSummit2024() { - -

- We speak english! -

-
-

- La majeure partie de l'évènement se déroulera{' '} - en anglais afin d'inclure nos partenaires - internationaux dans les discussions. -

-

- Pas de panique si vous ne parlez pas anglais :{' '} - une transcription et traduction en direct des - prises de paroles publiques aura lieu. -

-
-

diff --git a/src/styles/app.css b/src/styles/app.css index 4578bdb..f296976 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -150,6 +150,23 @@ 0 0 0 4px #000091; } +/* grist summit: all the 'min-content' rows are for 'doors opening', 'coffee break', etc rows, and for rows explaining the rooms */ +.grist-summit-agenda-grid { + grid-template-rows: + min-content + repeat(2, minmax(0, 1fr)) + min-content min-content + repeat(8, minmax(0, 1fr)) + min-content + repeat(2, minmax(0, 1fr)) + min-content + repeat(4, minmax(0, 1fr)) + min-content + min-content + repeat(5, minmax(0, 1fr)) + min-content; +} + /** decapcms preview fixes: seems decapcms doesn't like some javascript that is used in the app, dirty "fix" some styles so that it's at least readable */ diff --git a/tailwind.config.ts b/tailwind.config.ts index 1c64151..8eac6f0 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -24,6 +24,7 @@ const config: Config = { ], theme: { fontSize: { + xxs: ['0.675rem', '0.7rem'], xs: ['0.75rem', '1rem'], sm: ['0.8rem', '1.25rem'], base: ['1rem', '1.5rem'], @@ -68,6 +69,7 @@ const config: Config = { 'blue-2': '#1212ff', 'blue-3': '#f3f6fe', 'grey-0': '#f6f6f6', + 'grey-1': '#eeeeee', 'info-0': '#e8edff', 'info-1': '#0063cb', }, @@ -76,6 +78,66 @@ const config: Config = { fontFamily: { sans: ['var(--font-marianne)', ...defaultTheme.fontFamily.sans], }, + gridTemplateRows: { + '26': 'repeat(26, minmax(0, 1fr))', + '27': 'repeat(27, minmax(0, 1fr))', + '28': 'repeat(28, minmax(0, 1fr))', + '29': 'repeat(29, minmax(0, 1fr))', + '32': 'repeat(32, minmax(0, 1fr))', + '34': 'repeat(34, minmax(0, 1fr))', + }, + gridRow: { + ...defaultTheme.gridRow, + 'span-14': 'span 14 / span 14', + 'span-15': 'span 15 / span 15', + 'span-16': 'span 16 / span 16', + 'span-17': 'span 17 / span 17', + 'span-18': 'span 18 / span 18', + 'span-19': 'span 19 / span 19', + 'span-20': 'span 20 / span 20', + 'span-21': 'span 21 / span 21', + 'span-22': 'span 22 / span 22', + 'span-23': 'span 23 / span 23', + 'span-24': 'span 24 / span 24', + 'span-25': 'span 25 / span 25', + 'span-26': 'span 26 / span 26', + 'span-27': 'span 27 / span 27', + 'span-28': 'span 28 / span 28', + 'span-29': 'span 29 / span 29', + 'span-30': 'span 30 / span 30', + 'span-31': 'span 31 / span 31', + 'span-32': 'span 32 / span 32', + 'span-33': 'span 33 / span 33', + 'span-34': 'span 34 / span 34', + 'span-35': 'span 35 / span 35', + 'span-36': 'span 36 / span 36', + }, + gridRowStart: { + ...defaultTheme.gridRowStart, + '14': '14', + '15': '15', + '16': '16', + '17': '17', + '18': '18', + '19': '19', + '20': '20', + '21': '21', + '22': '22', + '23': '23', + '24': '24', + '25': '25', + '26': '26', + '27': '27', + '28': '28', + '29': '29', + '30': '30', + '31': '31', + '32': '32', + '33': '33', + '34': '34', + '35': '35', + '36': '36', + }, }, }, plugins: [],