From df1e58603944b7294330c5279d1dc20aeff934ab Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Tue, 18 Jul 2023 09:49:04 +0300 Subject: [PATCH 01/22] feat: custom speakers, individual speaker, and schedule pages for conf --- gatsby-node.ts | 35 ++++++ package.json | 1 + src/components/Conf/Header/index.tsx | 2 + src/components/Conf/Schedule/ScheduleList.tsx | 102 ++++++++++++++++ src/components/Conf/Speakers/Avatar.tsx | 35 ++++++ src/components/Conf/Speakers/Speaker.tsx | 58 +++++++++ src/components/Conf/Speakers/index.tsx | 2 + src/pages/conf/{schedule.tsx => sched.tsx} | 0 src/templates/schedule.tsx | 67 +++++++++++ src/templates/speaker.tsx | 110 ++++++++++++++++++ src/templates/speakers.tsx | 78 +++++++++++++ yarn.lock | 39 +++++++ 12 files changed, 529 insertions(+) create mode 100644 src/components/Conf/Schedule/ScheduleList.tsx create mode 100644 src/components/Conf/Speakers/Avatar.tsx create mode 100644 src/components/Conf/Speakers/Speaker.tsx rename src/pages/conf/{schedule.tsx => sched.tsx} (100%) create mode 100644 src/templates/schedule.tsx create mode 100644 src/templates/speaker.tsx create mode 100644 src/templates/speakers.tsx diff --git a/gatsby-node.ts b/gatsby-node.ts index 0833710e4c..f07f7f3f2b 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -1,3 +1,4 @@ +import { SchedSpeaker } from "./src/components/Conf/Speakers/Speaker" import { GatsbyNode } from "gatsby" import * as path from "path" import { glob } from "glob" @@ -116,6 +117,40 @@ export const createPages: GatsbyNode["createPages"] = async ({ }) => { const { createPage, createRedirect } = actions + const schedAccessToken = process.env.SCHED_ACCESS_TOKEN + // Fetch conf speakers and sessions concurrently + const [schedule, speakers] = (await Promise.all([ + fetch( + `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json` + ).then(response => response.json()), + fetch( + `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username,company,position,name,about,location,url,avatar,role` + ).then(response => response.json()), + ])) as [any, SchedSpeaker[]] + + // Create schedule page + createPage({ + path: "/conf/schedule", + component: path.resolve("./src/templates/schedule.tsx"), + context: { schedule }, + }) + + // Create speakers list page + createPage({ + path: "/conf/speakers", + component: path.resolve("./src/templates/speakers.tsx"), + context: { speakers }, + }) + + // Create a page for each speaker + speakers.forEach(speaker => { + createPage({ + path: `/conf/speakers/${speaker.username}`, + component: path.resolve("./src/templates/speaker.tsx"), + context: { speaker, schedule }, + }) + }) + createRedirect({ fromPath: "/conf/program", toPath: "/conf/schedule", diff --git a/package.json b/package.json index f97018b837..892add62cf 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "clsx": "1.2.1", "codemirror": "5.65.1", "codemirror-graphql": "1.3.2", + "date-fns": "^2.30.0", "gatsby": "5.10.0", "gatsby-plugin-anchor-links": "1.2.1", "gatsby-plugin-feed": "5.10.0", diff --git a/src/components/Conf/Header/index.tsx b/src/components/Conf/Header/index.tsx index 6f31b4e10c..aadb55dfbc 100644 --- a/src/components/Conf/Header/index.tsx +++ b/src/components/Conf/Header/index.tsx @@ -9,6 +9,8 @@ interface LinkItem { const links: LinkItem[] = [ { text: "Attend", href: "/conf/#attend" }, + { text: "Sched", href: "/conf/sched/" }, + { text: "Speakers", href: "/conf/speakers/" }, { text: "Schedule", href: "/conf/schedule/" }, { text: "Sponsor", href: "/conf/sponsor/" }, { text: "Partner", href: "/conf/partner/" }, diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx new file mode 100644 index 0000000000..4fa7ad33c1 --- /dev/null +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -0,0 +1,102 @@ +import { format, parseISO } from "date-fns" +import React, { FC, useEffect, useState } from "react" + +interface Session { + speakers: string +} +interface SessionGroup { + date: string + sessions: Session[] +} + +interface Props { + scheduleData: any + filterSchedule?: (sessions: Session[]) => Session[] +} +const ScheduleList: FC = ({ filterSchedule, scheduleData }) => { + const [sessions, setSessions] = useState([]) + + useEffect(() => { + const filteredSessions = !!filterSchedule + ? filterSchedule(scheduleData) + : scheduleData + + // Sort sessions in ascending order by date + const sortedSessions = filteredSessions.sort( + (a: any, b: any) => + new Date(a.event_start).getTime() - new Date(b.event_start).getTime() + ) + + // Group sessions by date + const sessionGroups: { [date: string]: any[] } = {} + + sortedSessions.forEach((session: any) => { + const date = format(parseISO(session.event_start), "yyyy-MM-dd") + if (!sessionGroups[date]) { + sessionGroups[date] = [] + } + sessionGroups[date].push(session) + }) + + // Convert session groups to an array and sort by date + const sessionGroupArray = Object.keys(sessionGroups) + .sort() + .map(date => ({ date, sessions: sessionGroups[date] })) + + setSessions(sessionGroupArray) + }, []) + + return ( + <> + {sessions.map(({ date, sessions }) => ( +
+

+ {format(parseISO(date), "EEEE, MMMM d")} +

+ {sessions.map((session: any) => ( +
+
+ + {format(parseISO(session.event_start), "hh:mmaaaa 'PDT'")} + +
+ {session.name} ({/* Sigular */} + {(session.event_type as string).substring( + 0, + session.event_type.length - 1 + )} + ) +
+
+
+ ))} +
+ ))} + + ) +} + +export default ScheduleList + +function getSessionColor(sessionType: string) { + if (sessionType.includes("breaks")) { + return "#fffc5c" + } else if (sessionType.includes("keynote")) { + return "#42a1cd" + } else if (sessionType.includes("lightning")) { + return "#3db847" + } else if (sessionType.includes("presentations")) { + return "#d64292" + } else if (sessionType.includes("workshops")) { + return "#f3a149" + } else { + return "#E05CAA" // default color if none of the keywords match + } +} diff --git a/src/components/Conf/Speakers/Avatar.tsx b/src/components/Conf/Speakers/Avatar.tsx new file mode 100644 index 0000000000..79a64903d0 --- /dev/null +++ b/src/components/Conf/Speakers/Avatar.tsx @@ -0,0 +1,35 @@ +import React, { FC } from "react" + +interface Props { + avatar?: string + name: string + className: string + href: string +} +export const Avatar: FC = ({ avatar, name, className, href }) => { + const nameInitialsAvatarFallback = name + .split(" ") + .map(e => e[0]) + .join("") + .toUpperCase() + + return ( + + {avatar ? ( + {`${name} + ) : ( +
+ + {nameInitialsAvatarFallback} + +
+ )} +
+ ) +} diff --git a/src/components/Conf/Speakers/Speaker.tsx b/src/components/Conf/Speakers/Speaker.tsx new file mode 100644 index 0000000000..a809b9ee1e --- /dev/null +++ b/src/components/Conf/Speakers/Speaker.tsx @@ -0,0 +1,58 @@ +import React, { FC } from "react" +import { Avatar } from "./Avatar" + +export interface SchedSpeaker { + username: string + name: string + about: string + company?: string + position?: string + avatar?: string + url?: string + role: string + location?: string +} + +const Speaker: FC = ({ + name, + company, + position, + avatar, + url, + username, +}) => { + return ( +
+ +
+ + {name || "-"} + +

+ {company ? ( + url ? ( + + {company} + + ) : ( + company + ) + ) : ( + "-" + )} +

+

{position || "-"}

+
+
+ ) +} + +export default Speaker diff --git a/src/components/Conf/Speakers/index.tsx b/src/components/Conf/Speakers/index.tsx index e28141bdd4..2b8946fa18 100644 --- a/src/components/Conf/Speakers/index.tsx +++ b/src/components/Conf/Speakers/index.tsx @@ -100,3 +100,5 @@ const SpeakersConf = () => { } export default SpeakersConf + +export { speakers as keynoteSpeakers } diff --git a/src/pages/conf/schedule.tsx b/src/pages/conf/sched.tsx similarity index 100% rename from src/pages/conf/schedule.tsx rename to src/pages/conf/sched.tsx diff --git a/src/templates/schedule.tsx b/src/templates/schedule.tsx new file mode 100644 index 0000000000..df510912be --- /dev/null +++ b/src/templates/schedule.tsx @@ -0,0 +1,67 @@ +import React, { FC } from "react" +import FooterConf from "../components/Conf/Footer" +import HeaderConf from "../components/Conf/Header" +import LayoutConf from "../components/Conf/Layout" +import SeoConf from "../components/Conf/Seo" +import { PageProps } from "gatsby" +import ScheduleList from "../components/Conf/Schedule/ScheduleList" + +const ScheduleTemplate: FC> = ({ + pageContext: { schedule }, +}) => { + return ( + + + +
+
+

GraphQLConf 2023 Schedule

+
+

September 19-21, 2023 I San Francisco Bay Area, CA

+

+ Please note: All session times are in Pacific Daylight Time (UTC + -7). To view the schedule in your preferred timezone, + please select from the drop-down menu to the right, above “Filter + by Date.” +

+

+ IMPORTANT NOTE: Timing of sessions and room locations are{" "} + subject to change. +

+ + + + + {/* +

Workshop Day

+

+ Join us for a GraphQLConf Workshop Day on September 19. Workshops + are included in GraphQLConf registration though pre-registration + is required -{" "} + + register now + + , or modify your registration and join us! Workshop space is + available on a first come, first served basis. +

+

Thank you to our Workshop Day sponsor, The Guild.

+
+ +
*/} +
+
+
+ +
+ ) +} + +export function Head() { + return +} + +export default ScheduleTemplate diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx new file mode 100644 index 0000000000..fa4f0dad73 --- /dev/null +++ b/src/templates/speaker.tsx @@ -0,0 +1,110 @@ +import React, { FC } from "react" +import FooterConf from "../components/Conf/Footer" +import HeaderConf from "../components/Conf/Header" +import LayoutConf from "../components/Conf/Layout" +import SeoConf from "../components/Conf/Seo" +import { PageProps } from "gatsby" +import { SchedSpeaker } from "../components/Conf/Speakers/Speaker" +import ScheduleList from "../components/Conf/Schedule/ScheduleList" +import { Avatar } from "../components/Conf/Speakers/Avatar" + +const SpeakersTemplate: FC< + PageProps<{}, { speaker: SchedSpeaker; schedule: any }> +> = ({ pageContext: { schedule, speaker } }) => { + return ( + + + +
+
+ <> +
+ + ← Back to Speakers + +
+ + +
+

{speaker.name}

+
+ {renderPositionAndCompany(speaker)} +
+

+

+
+
+ +
+

+ My Speakers Sessions +

+ {speaker && ( + + sessions.filter(session => + session.speakers?.includes(speaker?.name) + ) + } + /> + )} +
+ +
+
+ + +
+ ) +} + +export default SpeakersTemplate + +export function Head() { + return +} + +function renderPositionAndCompany(speaker: SchedSpeaker) { + // Reassign "-" if position or company are undefined + const position = speaker.position || "-" + const company = speaker.company || "-" + + // Only include anchor element if url is not an empty string + const companyElement = + speaker.url !== "" ? ( + + {company} + + ) : ( + company + ) + + if (position !== "-" && company !== "-") { + return ( + <> + {position} at {companyElement} + + ) + } else if (position !== "-") { + return position + } else if (company !== "-") { + return <>Works at {companyElement} + } else { + return "-" + } +} diff --git a/src/templates/speakers.tsx b/src/templates/speakers.tsx new file mode 100644 index 0000000000..1dbcbfa5a8 --- /dev/null +++ b/src/templates/speakers.tsx @@ -0,0 +1,78 @@ +import React, { FC, useEffect, useState } from "react" +import FooterConf from "../components/Conf/Footer" +import HeaderConf from "../components/Conf/Header" +import LayoutConf from "../components/Conf/Layout" +import SeoConf from "../components/Conf/Seo" +import { keynoteSpeakers } from "../components/Conf/Speakers" +import Speaker, { SchedSpeaker } from "../components/Conf/Speakers/Speaker" +import { PageProps } from "gatsby" + +const SpeakersTemplate: FC> = ({ + pageContext: { speakers: speakersData }, +}) => { + const [speakers, setSpeakers] = useState([]) + + useEffect(() => { + const keynoteNames = keynoteSpeakers.map(speaker => speaker.name) + + // create an array for keynote speakers in fetched data maintaining the order in keynoteSpeakers + const keynoteSpeakersData = keynoteNames + .map(name => { + return speakersData.find( + (speaker: any) => + speaker.name === name && speaker.role.includes("speaker") + ) + }) + .filter(Boolean) as SchedSpeaker[] + + const otherSpeakersData = speakersData.filter( + (speaker: any) => + speaker.role.includes("speaker") && !keynoteNames.includes(speaker.name) + ) + + // Sort other speakers by last name alphabetically + otherSpeakersData.sort((a: any, b: any) => { + const aLastName = a.name.split(" ").slice(-1)[0].toLowerCase() + const bLastName = b.name.split(" ").slice(-1)[0].toLowerCase() + + return aLastName.localeCompare(bLastName) + }) + + setSpeakers([...keynoteSpeakersData, ...otherSpeakersData]) + }, []) + + return ( + + + +
+
+

GraphQLConf 2023 Speakers

+

+ Meet the unique lineup of insightful speakers we've carefully + chosen, who are primed to share their groundbreaking ideas and + innovative practices in the realm of GraphQL at the conference. +

+
+
+ {speakers.length ? ( + speakers.map((speaker: any) => ( + + )) + ) : ( +

+ Loading Speakers... +

+ )} +
+
+ +
+ ) +} + +export function Head() { + return +} + +export default SpeakersTemplate diff --git a/yarn.lock b/yarn.lock index 7601b038e8..709792d69f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4819,6 +4819,11 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + date-fns@^2.30.0: version "2.30.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" @@ -5971,6 +5976,14 @@ fbjs@^3.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -6157,6 +6170,13 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -8972,6 +8992,11 @@ node-addon-api@^6.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -8991,6 +9016,15 @@ node-fetch@^2.6.9: dependencies: whatwg-url "^5.0.0" +node-fetch@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-gyp-build-optional-packages@5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" @@ -12035,6 +12069,11 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + web-vitals@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-1.1.2.tgz#06535308168986096239aa84716e68b4c6ae6d1c" From 8dd5c4c758ec01556f60a039184ab24bf1e59fec Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Tue, 18 Jul 2023 14:35:30 +0300 Subject: [PATCH 02/22] fix: default avatar pink link --- src/components/Conf/Speakers/Avatar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Conf/Speakers/Avatar.tsx b/src/components/Conf/Speakers/Avatar.tsx index 79a64903d0..c474649afc 100644 --- a/src/components/Conf/Speakers/Avatar.tsx +++ b/src/components/Conf/Speakers/Avatar.tsx @@ -23,7 +23,7 @@ export const Avatar: FC = ({ avatar, name, className, href }) => { /> ) : (
{nameInitialsAvatarFallback} From b170bed8145ca00417bf86a0762051c5a32e75f1 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Fri, 21 Jul 2023 15:03:27 +0300 Subject: [PATCH 03/22] add social links --- gatsby-node.ts | 49 ++++++++++++++--- src/components/Conf/Speakers/Avatar.tsx | 46 +++++++++------- src/components/Conf/Speakers/Speaker.tsx | 53 ++++++++++++++++++ src/templates/speaker.tsx | 70 +++++++++++++++++++++++- static/img/logos/facebook.svg | 11 ++++ static/img/logos/instagram.svg | 30 ++++++++++ static/img/logos/linkedin.svg | 5 ++ static/img/logos/snapchat.svg | 5 ++ 8 files changed, 237 insertions(+), 32 deletions(-) create mode 100644 static/img/logos/facebook.svg create mode 100644 static/img/logos/instagram.svg create mode 100644 static/img/logos/linkedin.svg create mode 100644 static/img/logos/snapchat.svg diff --git a/gatsby-node.ts b/gatsby-node.ts index f07f7f3f2b..9617e33c21 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -2,6 +2,7 @@ import { SchedSpeaker } from "./src/components/Conf/Speakers/Speaker" import { GatsbyNode } from "gatsby" import * as path from "path" import { glob } from "glob" +import _ from "lodash" import { updateCodeData } from "./scripts/update-code-data/update-code-data" import { organizeCodeData } from "./scripts/update-code-data/organize-code-data" import { sortCodeData } from "./scripts/update-code-data/sort-code-data" @@ -118,15 +119,45 @@ export const createPages: GatsbyNode["createPages"] = async ({ const { createPage, createRedirect } = actions const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - // Fetch conf speakers and sessions concurrently - const [schedule, speakers] = (await Promise.all([ - fetch( - `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json` - ).then(response => response.json()), - fetch( - `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username,company,position,name,about,location,url,avatar,role` - ).then(response => response.json()), - ])) as [any, SchedSpeaker[]] + + const schedule = await fetch( + `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + + const usernames = await fetch( + `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + + // Fetch full info of each speaker individually and concurrently + const speakers: SchedSpeaker[] = await Promise.all( + usernames.map(async (user: { username: string }) => { + await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min + return fetch( + `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + }) + ) // Create schedule page createPage({ diff --git a/src/components/Conf/Speakers/Avatar.tsx b/src/components/Conf/Speakers/Avatar.tsx index c474649afc..eed1115e94 100644 --- a/src/components/Conf/Speakers/Avatar.tsx +++ b/src/components/Conf/Speakers/Avatar.tsx @@ -4,7 +4,7 @@ interface Props { avatar?: string name: string className: string - href: string + href?: string } export const Avatar: FC = ({ avatar, name, className, href }) => { const nameInitialsAvatarFallback = name @@ -13,23 +13,29 @@ export const Avatar: FC = ({ avatar, name, className, href }) => { .join("") .toUpperCase() - return ( - - {avatar ? ( - {`${name} - ) : ( -
- - {nameInitialsAvatarFallback} - -
- )} -
- ) + const Component = () => + avatar ? ( + {`${name} + ) : ( +
+ + {nameInitialsAvatarFallback} + +
+ ) + + if (href) + return ( + + + + ) + + return } diff --git a/src/components/Conf/Speakers/Speaker.tsx b/src/components/Conf/Speakers/Speaker.tsx index a809b9ee1e..7b4fe35e38 100644 --- a/src/components/Conf/Speakers/Speaker.tsx +++ b/src/components/Conf/Speakers/Speaker.tsx @@ -1,5 +1,10 @@ import React, { FC } from "react" import { Avatar } from "./Avatar" +import { ReactComponent as TwitterIcon } from "../../../../static/img/logos/twitter.svg" +import { ReactComponent as FacebookIcon } from "../../../../static/img/logos/facebook.svg" +import { ReactComponent as InstagramIcon } from "../../../../static/img/logos/instagram.svg" +import { ReactComponent as SnapChatIcon } from "../../../../static/img/logos/snapchat.svg" +import { ReactComponent as LinkedinIcon } from "../../../../static/img/logos/linkedin.svg" export interface SchedSpeaker { username: string @@ -11,6 +16,35 @@ export interface SchedSpeaker { url?: string role: string location?: string + socialurls?: { service: string; url: string }[] +} + +type SocialMediaIconServiceType = + | "twitter" + | "linkedin" + | "facebook" + | "instagram" + | "snapchat" + +const SocialMediaIcon = ({ + service, +}: { + service: SocialMediaIconServiceType +}) => { + switch (service) { + case "twitter": + return + case "linkedin": + return + case "facebook": + return + case "instagram": + return + case "snapchat": + return + default: + return null + } } const Speaker: FC = ({ @@ -20,6 +54,7 @@ const Speaker: FC = ({ avatar, url, username, + socialurls, }) => { return (
@@ -50,6 +85,24 @@ const Speaker: FC = ({ )}

{position || "-"}

+
+ {socialurls?.map((e, index) => { + const isLastOne = socialurls.length - 1 === index + return ( + + + + ) + })} +
) diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index fa4f0dad73..ec06c3df52 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -7,18 +7,52 @@ import { PageProps } from "gatsby" import { SchedSpeaker } from "../components/Conf/Speakers/Speaker" import ScheduleList from "../components/Conf/Schedule/ScheduleList" import { Avatar } from "../components/Conf/Speakers/Avatar" +import { ReactComponent as TwitterIcon } from "../../static/img/logos/twitter.svg" +import { ReactComponent as FacebookIcon } from "../../static/img/logos/facebook.svg" +import { ReactComponent as InstagramIcon } from "../../static/img/logos/instagram.svg" +import { ReactComponent as SnapChatIcon } from "../../static/img/logos/snapchat.svg" +import { ReactComponent as LinkedinIcon } from "../../static/img/logos/linkedin.svg" + +type SocialMediaIconServiceType = + | "twitter" + | "linkedin" + | "facebook" + | "instagram" + | "snapchat" + +const SocialMediaIcon = ({ + service, +}: { + service: SocialMediaIconServiceType +}) => { + switch (service) { + case "twitter": + return + case "linkedin": + return + case "facebook": + return + case "instagram": + return + case "snapchat": + return + default: + return null + } +} const SpeakersTemplate: FC< PageProps<{}, { speaker: SchedSpeaker; schedule: any }> > = ({ pageContext: { schedule, speaker } }) => { + console.log("whatsap?", speaker) return ( -
+

My Speakers Sessions

diff --git a/static/img/logos/facebook.svg b/static/img/logos/facebook.svg new file mode 100644 index 0000000000..8673e33c35 --- /dev/null +++ b/static/img/logos/facebook.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/static/img/logos/instagram.svg b/static/img/logos/instagram.svg new file mode 100644 index 0000000000..d37922b6f7 --- /dev/null +++ b/static/img/logos/instagram.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/img/logos/linkedin.svg b/static/img/logos/linkedin.svg new file mode 100644 index 0000000000..639ed9d9e1 --- /dev/null +++ b/static/img/logos/linkedin.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/static/img/logos/snapchat.svg b/static/img/logos/snapchat.svg new file mode 100644 index 0000000000..a4684fb072 --- /dev/null +++ b/static/img/logos/snapchat.svg @@ -0,0 +1,5 @@ + + + + + From 1fbb8ba36394c202740398c20843c1edf81e5641 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Fri, 21 Jul 2023 15:50:19 +0300 Subject: [PATCH 04/22] add trailing ... to long social handles --- src/templates/speaker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index ec06c3df52..f51827a5a7 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -94,9 +94,9 @@ const SpeakersTemplate: FC< social.service.toLowerCase() as SocialMediaIconServiceType } /> - + / - {social.url + {decodeURIComponent(new URL(social.url).pathname) .replace(/\/+$/, "") .split("/") .reverse()[0] From 4d32ff880aa6a7d0ed40c003a33ad69d45c8809a Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Fri, 21 Jul 2023 16:40:00 +0300 Subject: [PATCH 05/22] better social media icons --- src/templates/speaker.tsx | 67 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index f51827a5a7..0a6d0f2e74 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -27,15 +27,15 @@ const SocialMediaIcon = ({ }) => { switch (service) { case "twitter": - return + return case "linkedin": - return + return case "facebook": - return + return case "instagram": - return + return case "snapchat": - return + return default: return null } @@ -67,7 +67,32 @@ const SpeakersTemplate: FC< />
-

{speaker.name}

+
+

+ {speaker.name} +

+ + {!!speaker.socialurls?.length && ( +
+
+ {speaker.socialurls.map(social => ( + + + + ))} +
+
+ )} +
{renderPositionAndCompany(speaker)}
@@ -76,36 +101,6 @@ const SpeakersTemplate: FC< dangerouslySetInnerHTML={{ __html: speaker.about }} />
- - {speaker.socialurls && ( - - )}
From e19179c8a7f9fdb37b06d22e371e84b97084990d Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Fri, 21 Jul 2023 16:50:06 +0300 Subject: [PATCH 06/22] text justify on bio --- src/templates/speaker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index 0a6d0f2e74..b373e87826 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -97,7 +97,7 @@ const SpeakersTemplate: FC< {renderPositionAndCompany(speaker)}

From 0636e84a49669043f3c372e2d68ab9a9aa8ad5b0 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Fri, 21 Jul 2023 23:00:01 +0300 Subject: [PATCH 07/22] better back to speakers link --- src/templates/speaker.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index b373e87826..980ac1d16d 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -55,9 +55,18 @@ const SpeakersTemplate: FC<

- ← Back to Speakers + + ← + + Back to Speakers
Date: Fri, 21 Jul 2023 23:30:38 +0300 Subject: [PATCH 08/22] ci: read gatsby's env var --- .github/workflows/CI.yml | 3 +++ gatsby-node.ts | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6ecc928455..954c9ccf24 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,6 +13,9 @@ jobs: - run: yarn install + - name: Set Sched's API token env + run: echo "SCHED_ACCESS_TOKEN=${{ secrets.SCHED_ACCESS_TOKEN }}" >> .env.production + # Verify it compiles - run: yarn build diff --git a/gatsby-node.ts b/gatsby-node.ts index 9617e33c21..41e9b5d821 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -7,6 +7,10 @@ import { updateCodeData } from "./scripts/update-code-data/update-code-data" import { organizeCodeData } from "./scripts/update-code-data/organize-code-data" import { sortCodeData } from "./scripts/update-code-data/sort-code-data" +require("dotenv").config({ + path: `.env.${process.env.NODE_ENV}`, +}) + export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"] = async ({ actions }) => { const gql = String.raw From a1da1e6e31b6c74587003f701a52d786c84d1dbf Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sat, 22 Jul 2023 00:12:16 +0300 Subject: [PATCH 09/22] debug --- gatsby-node.ts | 120 +++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/gatsby-node.ts b/gatsby-node.ts index 41e9b5d821..2723abf62d 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -122,69 +122,73 @@ export const createPages: GatsbyNode["createPages"] = async ({ }) => { const { createPage, createRedirect } = actions - const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - - const schedule = await fetch( - `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - - const usernames = await fetch( - `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - - // Fetch full info of each speaker individually and concurrently - const speakers: SchedSpeaker[] = await Promise.all( - usernames.map(async (user: { username: string }) => { - await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min - return fetch( - `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - }) - ) + try { + const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - // Create schedule page - createPage({ - path: "/conf/schedule", - component: path.resolve("./src/templates/schedule.tsx"), - context: { schedule }, - }) + const schedule = await fetch( + `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) - // Create speakers list page - createPage({ - path: "/conf/speakers", - component: path.resolve("./src/templates/speakers.tsx"), - context: { speakers }, - }) + const usernames = await fetch( + `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + + // Fetch full info of each speaker individually and concurrently + const speakers: SchedSpeaker[] = await Promise.all( + usernames.map(async (user: { username: string }) => { + await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min + return fetch( + `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + }) + ) - // Create a page for each speaker - speakers.forEach(speaker => { + // Create schedule page createPage({ - path: `/conf/speakers/${speaker.username}`, - component: path.resolve("./src/templates/speaker.tsx"), - context: { speaker, schedule }, + path: "/conf/schedule", + component: path.resolve("./src/templates/schedule.tsx"), + context: { schedule }, }) - }) + + // Create speakers list page + createPage({ + path: "/conf/speakers", + component: path.resolve("./src/templates/speakers.tsx"), + context: { speakers }, + }) + + // Create a page for each speaker + speakers.forEach(speaker => { + createPage({ + path: `/conf/speakers/${speaker.username}`, + component: path.resolve("./src/templates/speaker.tsx"), + context: { speaker, schedule }, + }) + }) + } catch (error) { + console.log("CATCH ME:", error) + } createRedirect({ fromPath: "/conf/program", From 186b51c58cd28f3a0c64f4b4d20edb0bcc23f420 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sat, 22 Jul 2023 00:16:39 +0300 Subject: [PATCH 10/22] chore: remove debug --- gatsby-node.ts | 120 ++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/gatsby-node.ts b/gatsby-node.ts index 2723abf62d..41e9b5d821 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -122,73 +122,69 @@ export const createPages: GatsbyNode["createPages"] = async ({ }) => { const { createPage, createRedirect } = actions - try { - const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - - const schedule = await fetch( - `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) + const schedAccessToken = process.env.SCHED_ACCESS_TOKEN + + const schedule = await fetch( + `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + + const usernames = await fetch( + `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + + // Fetch full info of each speaker individually and concurrently + const speakers: SchedSpeaker[] = await Promise.all( + usernames.map(async (user: { username: string }) => { + await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min + return fetch( + `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + } + ).then(response => response.json()) + }) + ) - const usernames = await fetch( - `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - - // Fetch full info of each speaker individually and concurrently - const speakers: SchedSpeaker[] = await Promise.all( - usernames.map(async (user: { username: string }) => { - await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min - return fetch( - `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - }) - ) + // Create schedule page + createPage({ + path: "/conf/schedule", + component: path.resolve("./src/templates/schedule.tsx"), + context: { schedule }, + }) - // Create schedule page - createPage({ - path: "/conf/schedule", - component: path.resolve("./src/templates/schedule.tsx"), - context: { schedule }, - }) + // Create speakers list page + createPage({ + path: "/conf/speakers", + component: path.resolve("./src/templates/speakers.tsx"), + context: { speakers }, + }) - // Create speakers list page + // Create a page for each speaker + speakers.forEach(speaker => { createPage({ - path: "/conf/speakers", - component: path.resolve("./src/templates/speakers.tsx"), - context: { speakers }, + path: `/conf/speakers/${speaker.username}`, + component: path.resolve("./src/templates/speaker.tsx"), + context: { speaker, schedule }, }) - - // Create a page for each speaker - speakers.forEach(speaker => { - createPage({ - path: `/conf/speakers/${speaker.username}`, - component: path.resolve("./src/templates/speaker.tsx"), - context: { speaker, schedule }, - }) - }) - } catch (error) { - console.log("CATCH ME:", error) - } + }) createRedirect({ fromPath: "/conf/program", From d089d0bd596d3e581c17bb0bd68abca649c8fdf2 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sat, 22 Jul 2023 00:30:48 +0300 Subject: [PATCH 11/22] build: fix --- gatsby-node.ts | 113 +++++++++++++++++++------------------- src/templates/speaker.tsx | 1 - 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/gatsby-node.ts b/gatsby-node.ts index 41e9b5d821..13764690e9 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -116,75 +116,76 @@ export const onCreatePage: GatsbyNode["onCreatePage"] = async ({ }) } +const fetchData = async (url: string) => { + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": "GraphQL Conf / GraphQL Foundation", + }, + }) + const data = await response.json() + return data + } catch (error) { + throw new Error( + `Error fetching data from ${url}: ${error.message || error.toString()}` + ) + } +} + export const createPages: GatsbyNode["createPages"] = async ({ actions, graphql, }) => { const { createPage, createRedirect } = actions - const schedAccessToken = process.env.SCHED_ACCESS_TOKEN + try { + const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - const schedule = await fetch( - `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) + const schedule = await fetchData( + `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json` + ) - const usernames = await fetch( - `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - - // Fetch full info of each speaker individually and concurrently - const speakers: SchedSpeaker[] = await Promise.all( - usernames.map(async (user: { username: string }) => { - await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min - return fetch( - `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - "User-Agent": "GraphQL Conf / GraphQL Foundation", - }, - } - ).then(response => response.json()) - }) - ) + const usernames = await fetchData( + `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username` + ) - // Create schedule page - createPage({ - path: "/conf/schedule", - component: path.resolve("./src/templates/schedule.tsx"), - context: { schedule }, - }) + // Fetch full info of each speaker individually and concurrently + const speakers: SchedSpeaker[] = await Promise.all( + usernames.map(async (user: { username: string }) => { + await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min + return fetchData( + `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls` + ) + }) + ) - // Create speakers list page - createPage({ - path: "/conf/speakers", - component: path.resolve("./src/templates/speakers.tsx"), - context: { speakers }, - }) + // Create schedule page + createPage({ + path: "/conf/schedule", + component: path.resolve("./src/templates/schedule.tsx"), + context: { schedule }, + }) - // Create a page for each speaker - speakers.forEach(speaker => { + // Create speakers list page createPage({ - path: `/conf/speakers/${speaker.username}`, - component: path.resolve("./src/templates/speaker.tsx"), - context: { speaker, schedule }, + path: "/conf/speakers", + component: path.resolve("./src/templates/speakers.tsx"), + context: { speakers }, }) - }) + + // Create a page for each speaker + speakers.forEach(speaker => { + createPage({ + path: `/conf/speakers/${speaker.username}`, + component: path.resolve("./src/templates/speaker.tsx"), + context: { speaker, schedule }, + }) + }) + } catch (error) { + console.log("CATCH ME:", error) + } createRedirect({ fromPath: "/conf/program", diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index 980ac1d16d..7b9ee4aada 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -44,7 +44,6 @@ const SocialMediaIcon = ({ const SpeakersTemplate: FC< PageProps<{}, { speaker: SchedSpeaker; schedule: any }> > = ({ pageContext: { schedule, speaker } }) => { - console.log("whatsap?", speaker) return ( From 23cedd87002395e539c026cc75ab892155603dbb Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sat, 22 Jul 2023 23:28:10 +0300 Subject: [PATCH 12/22] feat: show concurrent events and events gloassary --- src/components/Conf/Schedule/ScheduleList.tsx | 150 ++++++++++-------- src/templates/schedule.tsx | 46 +++--- src/templates/speaker.tsx | 7 +- 3 files changed, 113 insertions(+), 90 deletions(-) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index 4fa7ad33c1..ae7df555d9 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -1,78 +1,110 @@ import { format, parseISO } from "date-fns" import React, { FC, useEffect, useState } from "react" +import { eventsColors } from "../../../templates/schedule" + +function groupByKey(arr: T[], getKey: (entity: T) => any) { + return Array.from<[string, T[]]>( + arr.reduce( + (entryMap, e) => + entryMap.set(getKey(e) as keyof T, [ + ...(entryMap.get(getKey(e) as keyof T) || []), + e, + ]), + new Map() + ) + ) +} interface Session { + id: string + audience: string + description: string + event_end: string + event_start: string + event_subtype: string + event_type: string + name: string speakers: string } -interface SessionGroup { - date: string - sessions: Session[] -} + +type Date = string +type ConcurrentSessionsGroups = [Date, Session[]][] +type SessionsGroupByDay = [Date, ConcurrentSessionsGroups][] interface Props { - scheduleData: any + showEventType?: boolean + scheduleData: Session[] filterSchedule?: (sessions: Session[]) => Session[] } -const ScheduleList: FC = ({ filterSchedule, scheduleData }) => { - const [sessions, setSessions] = useState([]) +const ScheduleList: FC = ({ + showEventType, + filterSchedule, + scheduleData, +}) => { + const [groupedSessionsByDay, setGroupedSessionsByDay] = + useState([]) useEffect(() => { - const filteredSessions = !!filterSchedule - ? filterSchedule(scheduleData) - : scheduleData - - // Sort sessions in ascending order by date - const sortedSessions = filteredSessions.sort( - (a: any, b: any) => - new Date(a.event_start).getTime() - new Date(b.event_start).getTime() + const filteredSortedSchedule = ( + filterSchedule ? filterSchedule(scheduleData) : scheduleData + ).sort( + (a, b) => + new Date(a.event_start).getTime() - new Date(b.event_end).getTime() ) - // Group sessions by date - const sessionGroups: { [date: string]: any[] } = {} - - sortedSessions.forEach((session: any) => { - const date = format(parseISO(session.event_start), "yyyy-MM-dd") - if (!sessionGroups[date]) { - sessionGroups[date] = [] - } - sessionGroups[date].push(session) - }) + const groupedConcurrentSessions = groupByKey( + filteredSortedSchedule, + e => e.event_start + ) - // Convert session groups to an array and sort by date - const sessionGroupArray = Object.keys(sessionGroups) - .sort() - .map(date => ({ date, sessions: sessionGroups[date] })) + const groupedSessionsByDay = groupByKey( + groupedConcurrentSessions, + // e[0] is the event date `yyyy/mm/dd hh:mm` and we split it by empty space to only get the day date excluding time. + e => e[0].split(" ")[0] + ) - setSessions(sessionGroupArray) + setGroupedSessionsByDay(groupedSessionsByDay) }, []) return ( <> - {sessions.map(({ date, sessions }) => ( -
+ {groupedSessionsByDay.map(([date, concurrentSessionsGroup]) => ( +

{format(parseISO(date), "EEEE, MMMM d")}

- {sessions.map((session: any) => ( -
-
- - {format(parseISO(session.event_start), "hh:mmaaaa 'PDT'")} - -
- {session.name} ({/* Sigular */} - {(session.event_type as string).substring( - 0, - session.event_type.length - 1 - )} - ) + {concurrentSessionsGroup.map(([sharedStartDate, sessions]) => ( +
+
+
+ + {format(parseISO(sharedStartDate), "hh:mmaaaa 'PDT'")} + +
+
+
+
+ + {sessions.map(session => { + const singularEventType = ( + session.event_type as string + ).substring(0, session.event_type.length - 1) + + return ( +
+ {showEventType ? singularEventType + " / " : ""} + {session.name} +
+ ) + })}
@@ -86,17 +118,5 @@ const ScheduleList: FC = ({ filterSchedule, scheduleData }) => { export default ScheduleList function getSessionColor(sessionType: string) { - if (sessionType.includes("breaks")) { - return "#fffc5c" - } else if (sessionType.includes("keynote")) { - return "#42a1cd" - } else if (sessionType.includes("lightning")) { - return "#3db847" - } else if (sessionType.includes("presentations")) { - return "#d64292" - } else if (sessionType.includes("workshops")) { - return "#f3a149" - } else { - return "#E05CAA" // default color if none of the keywords match - } + return eventsColors.find(e => sessionType.includes(e[0]))?.[1] } diff --git a/src/templates/schedule.tsx b/src/templates/schedule.tsx index df510912be..56ebc52ea2 100644 --- a/src/templates/schedule.tsx +++ b/src/templates/schedule.tsx @@ -6,6 +6,14 @@ import SeoConf from "../components/Conf/Seo" import { PageProps } from "gatsby" import ScheduleList from "../components/Conf/Schedule/ScheduleList" +export const eventsColors = [ + ["breaks", "#fffc5c"], + ["keynote", "#42a1cd"], + ["lightning", "#3db847"], + ["presentations", "#d64292"], + ["workshops", "#f3a149"], +] + const ScheduleTemplate: FC> = ({ pageContext: { schedule }, }) => { @@ -28,30 +36,24 @@ const ScheduleTemplate: FC> = ({ IMPORTANT NOTE: Timing of sessions and room locations are{" "} subject to change.

- +
+ + Event Types: + +
+ {eventsColors.map(([event, color]) => ( +
+
+ {event} +
+ ))} +
+
- - {/* -

Workshop Day

-

- Join us for a GraphQLConf Workshop Day on September 19. Workshops - are included in GraphQLConf registration though pre-registration - is required -{" "} - - register now - - , or modify your registration and join us! Workshop space is - available on a first come, first served basis. -

-

Thank you to our Workshop Day sponsor, The Guild.

-
- -
*/}
diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index 7b9ee4aada..013780340c 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -112,12 +112,13 @@ const SpeakersTemplate: FC<
-
-

- My Speakers Sessions +
+

+ My Speakers Sessions:

{speaker && ( sessions.filter(session => From 430b82ffea8d43f73e2c95f2a340994fc987fda0 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sat, 22 Jul 2023 23:35:14 +0300 Subject: [PATCH 13/22] some style fixes --- src/components/Conf/Schedule/ScheduleList.tsx | 2 +- src/templates/schedule.tsx | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index ae7df555d9..9d979ccabe 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -118,5 +118,5 @@ const ScheduleList: FC = ({ export default ScheduleList function getSessionColor(sessionType: string) { - return eventsColors.find(e => sessionType.includes(e[0]))?.[1] + return eventsColors.find(e => sessionType.includes(e[0].toLowerCase()))?.[1] } diff --git a/src/templates/schedule.tsx b/src/templates/schedule.tsx index 56ebc52ea2..412df0d7eb 100644 --- a/src/templates/schedule.tsx +++ b/src/templates/schedule.tsx @@ -7,11 +7,11 @@ import { PageProps } from "gatsby" import ScheduleList from "../components/Conf/Schedule/ScheduleList" export const eventsColors = [ - ["breaks", "#fffc5c"], - ["keynote", "#42a1cd"], - ["lightning", "#3db847"], - ["presentations", "#d64292"], - ["workshops", "#f3a149"], + ["Breaks", "#fffc5c"], + ["Keynote Sessions", "#42a1cd"], + ["Lightning Talks", "#3db847"], + ["Session Presentations", "#d64292"], + ["Workshops", "#f3a149"], ] const ScheduleTemplate: FC> = ({ @@ -41,7 +41,7 @@ const ScheduleTemplate: FC> = ({ Event Types: -
+
{eventsColors.map(([event, color]) => (
Date: Sun, 23 Jul 2023 00:50:49 +0300 Subject: [PATCH 14/22] custom event page --- gatsby-node.ts | 23 +- src/components/Conf/Schedule/ScheduleList.tsx | 26 ++- src/templates/event.tsx | 217 ++++++++++++++++++ 3 files changed, 257 insertions(+), 9 deletions(-) create mode 100644 src/templates/event.tsx diff --git a/gatsby-node.ts b/gatsby-node.ts index 13764690e9..e1d12cac5d 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -1,3 +1,4 @@ +import { ScheduleSession } from "./src/components/Conf/Schedule/ScheduleList" import { SchedSpeaker } from "./src/components/Conf/Speakers/Speaker" import { GatsbyNode } from "gatsby" import * as path from "path" @@ -143,17 +144,17 @@ export const createPages: GatsbyNode["createPages"] = async ({ try { const schedAccessToken = process.env.SCHED_ACCESS_TOKEN - const schedule = await fetchData( + const schedule: ScheduleSession[] = await fetchData( `https://graphqlconf23.sched.com/api/session/list?api_key=${schedAccessToken}&format=json` ) - const usernames = await fetchData( + const usernames: { username: string }[] = await fetchData( `https://graphqlconf23.sched.com/api/user/list?api_key=${schedAccessToken}&format=json&fields=username` ) // Fetch full info of each speaker individually and concurrently const speakers: SchedSpeaker[] = await Promise.all( - usernames.map(async (user: { username: string }) => { + usernames.map(async user => { await new Promise(resolve => setTimeout(resolve, 2000)) // 2 second delay between requests, rate limit is 30req/min return fetchData( `https://graphqlconf23.sched.com/api/user/get?api_key=${schedAccessToken}&by=username&term=${user.username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls` @@ -168,6 +169,22 @@ export const createPages: GatsbyNode["createPages"] = async ({ context: { schedule }, }) + // Create schedule events' pages + schedule.forEach(event => { + createPage({ + path: `/conf/schedule/${event.id}`, + component: path.resolve("./src/templates/event.tsx"), + context: { + event, + speaker: speakers.find( + e => + event.name.includes(e.name) && + event.name.includes(e?.company || "") + ), + }, + }) + }) + // Create speakers list page createPage({ path: "/conf/speakers", diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index 9d979ccabe..8521484978 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -15,7 +15,7 @@ function groupByKey(arr: T[], getKey: (entity: T) => any) { ) } -interface Session { +export interface ScheduleSession { id: string audience: string description: string @@ -28,13 +28,13 @@ interface Session { } type Date = string -type ConcurrentSessionsGroups = [Date, Session[]][] +type ConcurrentSessionsGroups = [Date, ScheduleSession[]][] type SessionsGroupByDay = [Date, ConcurrentSessionsGroups][] interface Props { showEventType?: boolean - scheduleData: Session[] - filterSchedule?: (sessions: Session[]) => Session[] + scheduleData: ScheduleSession[] + filterSchedule?: (sessions: ScheduleSession[]) => ScheduleSession[] } const ScheduleList: FC = ({ showEventType, @@ -90,7 +90,7 @@ const ScheduleList: FC = ({ session.event_type as string ).substring(0, session.event_type.length - 1) - return ( + return session.event_type === "Breaks" ? (
= ({ session.event_type.toLowerCase() ), }} - className="text-black py-2 px-4 rounded-md shadow-lg w-full h-full" + className="text-black py-2 px-4 rounded-md shadow-lg w-full h-full font-light" > {showEventType ? singularEventType + " / " : ""} {session.name}
+ ) : ( + + {showEventType ? singularEventType + " / " : ""} + {session.name} + ) })}
diff --git a/src/templates/event.tsx b/src/templates/event.tsx new file mode 100644 index 0000000000..59c5b49170 --- /dev/null +++ b/src/templates/event.tsx @@ -0,0 +1,217 @@ +import React, { FC } from "react" +import { PageProps } from "gatsby" +import FooterConf from "../components/Conf/Footer" +import HeaderConf from "../components/Conf/Header" +import LayoutConf from "../components/Conf/Layout" +import SeoConf from "../components/Conf/Seo" +import { SchedSpeaker } from "../components/Conf/Speakers/Speaker" +import { ScheduleSession } from "../components/Conf/Schedule/ScheduleList" +import { format, parseISO } from "date-fns" +import { ReactComponent as TwitterIcon } from "../../static/img/logos/twitter.svg" +import { ReactComponent as FacebookIcon } from "../../static/img/logos/facebook.svg" +import { ReactComponent as InstagramIcon } from "../../static/img/logos/instagram.svg" +import { ReactComponent as SnapChatIcon } from "../../static/img/logos/snapchat.svg" +import { ReactComponent as LinkedinIcon } from "../../static/img/logos/linkedin.svg" +import { Avatar } from "../components/Conf/Speakers/Avatar" + +type SocialMediaIconServiceType = + | "twitter" + | "linkedin" + | "facebook" + | "instagram" + | "snapchat" + +const SocialMediaIcon = ({ + service, +}: { + service: SocialMediaIconServiceType +}) => { + switch (service) { + case "twitter": + return + case "linkedin": + return + case "facebook": + return + case "instagram": + return + case "snapchat": + return + default: + return null + } +} + +const SpeakersTemplate: FC< + PageProps<{}, { event: ScheduleSession; speaker: SchedSpeaker }> +> = ({ pageContext: { event, speaker } }) => { + console.log(event, speaker) + + const Tag = ({ text }: { text: string }) => ( + + {text} + + ) + return ( + + + +
+
+
+ + + ← + + Back to Schedule + +
+
+ + + {/* */} + + + + {format(parseISO(event.event_start), "EEEE, MMM d")} + + + + {/* */} + + + + {format(parseISO(event.event_start), "hh:mmaaaa 'PDT'")} + +
+

+ {/* Event name without speaker's name and company */} + {event.name.split(speaker.name)[0].slice(0, -2)} +

+
+ + + +
+

+ {event.description} +

+ +
+
+ + +
+ + {speaker.name} + + + + {renderPositionAndCompany(speaker)} + + {!!speaker.socialurls?.length && ( +
+
+ {speaker.socialurls.map(social => ( + + + + ))} +
+
+ )} +
+
+
+
+
+
+
+ + +
+ ) +} + +export default SpeakersTemplate + +export function Head() { + return +} + +function renderPositionAndCompany(speaker: SchedSpeaker) { + // Reassign "-" if position or company are undefined + const position = speaker.position || "-" + const company = speaker.company || "-" + + // Only include anchor element if url is not an empty string + const companyElement = + speaker.url !== "" ? ( + + {company} + + ) : ( + company + ) + + if (position !== "-" && company !== "-") { + return ( + <> + {position} at {companyElement} + + ) + } else if (position !== "-") { + return position + } else if (company !== "-") { + return <>Works at {companyElement} + } else { + return "-" + } +} From 788fc85ebe6c7ce53fff022db0467df503c3e765 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sun, 23 Jul 2023 01:19:13 +0300 Subject: [PATCH 15/22] fix: speakers breaking the build --- gatsby-node.ts | 10 +- src/components/Conf/Schedule/ScheduleList.tsx | 2 +- src/templates/event.tsx | 96 +++++++++---------- src/templates/schedule.tsx | 6 +- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/gatsby-node.ts b/gatsby-node.ts index e1d12cac5d..b306bef9e2 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -171,16 +171,16 @@ export const createPages: GatsbyNode["createPages"] = async ({ // Create schedule events' pages schedule.forEach(event => { + const eventSpeakers = speakers.filter(e => + event.speakers?.includes(e.name) + ) + createPage({ path: `/conf/schedule/${event.id}`, component: path.resolve("./src/templates/event.tsx"), context: { event, - speaker: speakers.find( - e => - event.name.includes(e.name) && - event.name.includes(e?.company || "") - ), + speakers: eventSpeakers, }, }) }) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index 8521484978..2d40c7157d 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -24,7 +24,7 @@ export interface ScheduleSession { event_subtype: string event_type: string name: string - speakers: string + speakers?: string } type Date = string diff --git a/src/templates/event.tsx b/src/templates/event.tsx index 59c5b49170..759eadc165 100644 --- a/src/templates/event.tsx +++ b/src/templates/event.tsx @@ -42,16 +42,14 @@ const SocialMediaIcon = ({ } } +const Tag = ({ text }: { text: string }) => ( + + {text} + +) const SpeakersTemplate: FC< - PageProps<{}, { event: ScheduleSession; speaker: SchedSpeaker }> -> = ({ pageContext: { event, speaker } }) => { - console.log(event, speaker) - - const Tag = ({ text }: { text: string }) => ( - - {text} - - ) + PageProps<{}, { event: ScheduleSession; speakers: SchedSpeaker[] }> +> = ({ pageContext: { event, speakers } }) => { return ( @@ -113,7 +111,7 @@ const SpeakersTemplate: FC<

{/* Event name without speaker's name and company */} - {event.name.split(speaker.name)[0].slice(0, -2)} + {event?.speakers}

@@ -124,47 +122,49 @@ const SpeakersTemplate: FC< {event.description}

-
-
- - -
- - {speaker.name} - +
+ {speakers.map(speaker => ( +
+ - - {renderPositionAndCompany(speaker)} - - {!!speaker.socialurls?.length && ( -
-
- {speaker.socialurls.map(social => ( - - - - ))} +
+ + {speaker.name} + + + + {renderPositionAndCompany(speaker)} + + {!!speaker.socialurls?.length && ( +
+
+ {speaker.socialurls.map(social => ( + + + + ))} +
-
- )} + )} +
-
+ ))}
diff --git a/src/templates/schedule.tsx b/src/templates/schedule.tsx index 412df0d7eb..ff829a021f 100644 --- a/src/templates/schedule.tsx +++ b/src/templates/schedule.tsx @@ -4,7 +4,9 @@ import HeaderConf from "../components/Conf/Header" import LayoutConf from "../components/Conf/Layout" import SeoConf from "../components/Conf/Seo" import { PageProps } from "gatsby" -import ScheduleList from "../components/Conf/Schedule/ScheduleList" +import ScheduleList, { + ScheduleSession, +} from "../components/Conf/Schedule/ScheduleList" export const eventsColors = [ ["Breaks", "#fffc5c"], @@ -14,7 +16,7 @@ export const eventsColors = [ ["Workshops", "#f3a149"], ] -const ScheduleTemplate: FC> = ({ +const ScheduleTemplate: FC> = ({ pageContext: { schedule }, }) => { return ( From bdb96b7272d032364f8441a05f456d00df7257ef Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sun, 23 Jul 2023 02:13:10 +0300 Subject: [PATCH 16/22] fix: event title, show event name --- src/templates/event.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/event.tsx b/src/templates/event.tsx index 759eadc165..3753cc4b11 100644 --- a/src/templates/event.tsx +++ b/src/templates/event.tsx @@ -111,7 +111,7 @@ const SpeakersTemplate: FC<

{/* Event name without speaker's name and company */} - {event?.speakers} + {event.name}

@@ -123,7 +123,7 @@ const SpeakersTemplate: FC<

- {speakers.map(speaker => ( + {speakers?.map(speaker => (
Date: Sun, 23 Jul 2023 02:34:37 +0300 Subject: [PATCH 17/22] fix: tag styles --- src/templates/event.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/templates/event.tsx b/src/templates/event.tsx index 3753cc4b11..1aaf8057b5 100644 --- a/src/templates/event.tsx +++ b/src/templates/event.tsx @@ -42,11 +42,12 @@ const SocialMediaIcon = ({ } } -const Tag = ({ text }: { text: string }) => ( - - {text} - -) +const Tag = ({ text }: { text: string }) => + !text ? null : ( + + {text} + + ) const SpeakersTemplate: FC< PageProps<{}, { event: ScheduleSession; speakers: SchedSpeaker[] }> > = ({ pageContext: { event, speakers } }) => { @@ -113,7 +114,7 @@ const SpeakersTemplate: FC< {/* Event name without speaker's name and company */} {event.name}

-
+
From 8a5ae394f22aa1532f5a43a2a426430e155e8a34 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sun, 23 Jul 2023 03:00:20 +0300 Subject: [PATCH 18/22] fix: sorting inconsistency on different browsers --- src/components/Conf/Schedule/ScheduleList.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index 2d40c7157d..eae93efb28 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -1,4 +1,4 @@ -import { format, parseISO } from "date-fns" +import { format, parseISO, compareAsc } from "date-fns" import React, { FC, useEffect, useState } from "react" import { eventsColors } from "../../../templates/schedule" @@ -47,9 +47,8 @@ const ScheduleList: FC = ({ useEffect(() => { const filteredSortedSchedule = ( filterSchedule ? filterSchedule(scheduleData) : scheduleData - ).sort( - (a, b) => - new Date(a.event_start).getTime() - new Date(b.event_end).getTime() + ).sort((a, b) => + compareAsc(new Date(a.event_start), new Date(b.event_start)) ) const groupedConcurrentSessions = groupByKey( From b1db2c8302ff1a8cb806233bf9590e693434f3a5 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sun, 23 Jul 2023 13:16:29 +0300 Subject: [PATCH 19/22] new color palette for schedule --- src/components/Conf/Schedule/ScheduleList.tsx | 23 +++++++++++-------- src/templates/schedule.tsx | 10 ++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index eae93efb28..0e23db1353 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -89,15 +89,17 @@ const ScheduleList: FC = ({ session.event_type as string ).substring(0, session.event_type.length - 1) + const [backgroundColor, textColor] = getSessionColor( + session.event_type.toLowerCase() + ) return session.event_type === "Breaks" ? (
{showEventType ? singularEventType + " / " : ""} {session.name} @@ -107,11 +109,10 @@ const ScheduleList: FC = ({ href={`/conf/schedule/${session.id}?name=${session.name}`} key={session.id} style={{ - backgroundColor: getSessionColor( - session.event_type.toLowerCase() - ), + backgroundColor, + color: textColor, }} - className="text-black py-2 px-4 rounded-md shadow-lg w-full h-full font-light underline" + className="py-2 px-4 rounded-md shadow-lg w-full h-full font-light underline" > {showEventType ? singularEventType + " / " : ""} {session.name} @@ -131,5 +132,9 @@ const ScheduleList: FC = ({ export default ScheduleList function getSessionColor(sessionType: string) { - return eventsColors.find(e => sessionType.includes(e[0].toLowerCase()))?.[1] + return ( + eventsColors + .find(e => sessionType.includes(e[0].toLowerCase())) + ?.slice(1) || [] + ) } diff --git a/src/templates/schedule.tsx b/src/templates/schedule.tsx index ff829a021f..3940306005 100644 --- a/src/templates/schedule.tsx +++ b/src/templates/schedule.tsx @@ -9,11 +9,11 @@ import ScheduleList, { } from "../components/Conf/Schedule/ScheduleList" export const eventsColors = [ - ["Breaks", "#fffc5c"], - ["Keynote Sessions", "#42a1cd"], - ["Lightning Talks", "#3db847"], - ["Session Presentations", "#d64292"], - ["Workshops", "#f3a149"], + ["Breaks", "#a7b7c4", "#171c24"], // Cool light blue with Dark Blue-Gray text + ["Keynote Sessions", "#a56be8", "#ffffff"], // Vibrant Purple with White text + ["Lightning Talks", "#16a596", "#ffffff"], // Turquoise with White text + ["Session Presentations", "#ec4646", "#ffffff"], // Vibrant Red with White text + ["Workshops", "#e6812f", "#ffffff"], // Slightly Darker Orange with White text ] const ScheduleTemplate: FC> = ({ From af10acd4f18e8cc04c7d900d2ae4c40e4cd7e880 Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Sun, 23 Jul 2023 13:43:22 +0300 Subject: [PATCH 20/22] rearrange event tags --- src/templates/event.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/event.tsx b/src/templates/event.tsx index 1aaf8057b5..e0d0de1683 100644 --- a/src/templates/event.tsx +++ b/src/templates/event.tsx @@ -115,9 +115,9 @@ const SpeakersTemplate: FC< {event.name}
+ -

{event.description} From 4c233a85c55a7ca1badc0cf2c5b1f9725590486a Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Tue, 25 Jul 2023 06:24:21 +0300 Subject: [PATCH 21/22] lots of improvements --- package.json | 2 + src/components/Conf/Header/index.tsx | 91 +++++-- src/components/Conf/Schedule/ScheduleList.tsx | 79 ++++++- src/components/Conf/Speakers/Speaker.tsx | 8 +- src/templates/event.tsx | 222 +++++++++--------- src/templates/speaker.tsx | 10 +- src/templates/speakers.tsx | 4 +- yarn.lock | 107 +++++---- 8 files changed, 343 insertions(+), 180 deletions(-) diff --git a/package.json b/package.json index 892add62cf..f6724c7a1b 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "prismjs": "1.29.0", "react": "18.2.0", "react-dom": "18.2.0", + "react-tooltip": "^5.18.1", "timeago.js": "4.0.2" }, "devDependencies": { @@ -51,6 +52,7 @@ "@tailwindcss/typography": "0.5.9", "@types/codemirror": "5.60.7", "@types/prismjs": "1.26.0", + "@types/react-tooltip": "^4.2.4", "@typescript-eslint/parser": "5.59.7", "autoprefixer": "10.4.14", "eslint": "8.42.0", diff --git a/src/components/Conf/Header/index.tsx b/src/components/Conf/Header/index.tsx index aadb55dfbc..905f9cd7ad 100644 --- a/src/components/Conf/Header/index.tsx +++ b/src/components/Conf/Header/index.tsx @@ -1,15 +1,14 @@ -import React from "react" +import React, { useState } from "react" import ButtonConf from "../Button" +import { Cross2Icon } from "@radix-ui/react-icons" interface LinkItem { text: string href: string - noMobile?: boolean } const links: LinkItem[] = [ { text: "Attend", href: "/conf/#attend" }, - { text: "Sched", href: "/conf/sched/" }, { text: "Speakers", href: "/conf/speakers/" }, { text: "Schedule", href: "/conf/schedule/" }, { text: "Sponsor", href: "/conf/sponsor/" }, @@ -17,31 +16,85 @@ const links: LinkItem[] = [ { text: "FAQ", href: "/conf/faq/" }, ] +const LinksList = () => ( + <> + {links.map(link => ( + + {link.text} + + ))} + +) + const HeaderConf = () => { + const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false) + + const handleDrawerClick = () => { + setMobileDrawerOpen(!mobileDrawerOpen) + } + return (

-
+
- {links.map(link => ( - - {link.text} - - ))} - + )} + + + +
- Buy a Ticket! - + + Buy a Ticket! + +
+ + +
+
) diff --git a/src/components/Conf/Schedule/ScheduleList.tsx b/src/components/Conf/Schedule/ScheduleList.tsx index 0e23db1353..91b8f76df4 100644 --- a/src/components/Conf/Schedule/ScheduleList.tsx +++ b/src/components/Conf/Schedule/ScheduleList.tsx @@ -1,6 +1,8 @@ import { format, parseISO, compareAsc } from "date-fns" import React, { FC, useEffect, useState } from "react" import { eventsColors } from "../../../templates/schedule" +import { Tooltip } from "react-tooltip" +import EventTemplate, { EventComponent } from "../../../templates/event" function groupByKey(arr: T[], getKey: (entity: T) => any) { return Array.from<[string, T[]]>( @@ -43,6 +45,11 @@ const ScheduleList: FC = ({ }) => { const [groupedSessionsByDay, setGroupedSessionsByDay] = useState([]) + const [hoveredSession, setHoveredSession] = useState( + null + ) + const [isOpen, setIsOpen] = useState(false) + const [hoveredSessionId, setHoveredSessionId] = useState(null) useEffect(() => { const filteredSortedSchedule = ( @@ -65,11 +72,67 @@ const ScheduleList: FC = ({ setGroupedSessionsByDay(groupedSessionsByDay) }, []) + const isMobile = window.screen.width < 1024 + return ( <> + {!isMobile && ( + + )} + {groupedSessionsByDay.map(([date, concurrentSessionsGroup]) => (
-

+

{format(parseISO(date), "EEEE, MMMM d")}

{concurrentSessionsGroup.map(([sharedStartDate, sessions]) => ( @@ -92,6 +155,7 @@ const ScheduleList: FC = ({ const [backgroundColor, textColor] = getSessionColor( session.event_type.toLowerCase() ) + return session.event_type === "Breaks" ? (
= ({
) : ( { + if (!isMobile) { + setHoveredSession(session) + setHoveredSessionId(`session-${session.id}`) + } }} - className="py-2 px-4 rounded-md shadow-lg w-full h-full font-light underline" > {showEventType ? singularEventType + " / " : ""} {session.name} diff --git a/src/components/Conf/Speakers/Speaker.tsx b/src/components/Conf/Speakers/Speaker.tsx index 7b4fe35e38..eaac56fd3b 100644 --- a/src/components/Conf/Speakers/Speaker.tsx +++ b/src/components/Conf/Speakers/Speaker.tsx @@ -60,18 +60,18 @@ const Speaker: FC = ({
-
+
{name || "-"} -

+

{company ? ( url ? ( diff --git a/src/templates/event.tsx b/src/templates/event.tsx index e0d0de1683..fb8f36955f 100644 --- a/src/templates/event.tsx +++ b/src/templates/event.tsx @@ -48,19 +48,20 @@ const Tag = ({ text }: { text: string }) => {text} ) -const SpeakersTemplate: FC< - PageProps<{}, { event: ScheduleSession; speakers: SchedSpeaker[] }> -> = ({ pageContext: { event, speakers } }) => { - return ( - - -

-
-
+export const EventComponent: FC<{ + event: ScheduleSession + speakers: SchedSpeaker[] + hideBackButton?: boolean +}> = ({ event, speakers, hideBackButton }) => { + return ( +
+
+
+ {!hideBackButton && ( Back to Schedule -
-
- - - {/* */} - - - - {format(parseISO(event.event_start), "EEEE, MMM d")} - - - - {/* */} - - - - {format(parseISO(event.event_start), "hh:mmaaaa 'PDT'")} - -
-

- {/* Event name without speaker's name and company */} - {event.name} -

-
- - - -
-

- {event.description} -

- -
- {speakers?.map(speaker => ( -
- - -
- - {speaker.name} - - - - {renderPositionAndCompany(speaker)} - - {!!speaker.socialurls?.length && ( -
-
- {speaker.socialurls.map(social => ( - - - - ))} -
+ )} +
+
+ + + {/* */} + + + + {format(parseISO(event.event_start), "EEEE, MMM d")} + + + + {/* */} + + + + {format(parseISO(event.event_start), "hh:mmaaaa 'PDT'")} + +
+

+ {/* Event name without speaker's name and company */} + {event.name} +

+
+ + + +
+

+ {event.description} +

+ +
+ {speakers?.map(speaker => ( +
+ + +
+ + {speaker.name} + + + + {renderPositionAndCompany(speaker)} + + {!!speaker.socialurls?.length && ( +
+
+ {speaker.socialurls.map(social => ( + + + + ))}
- )} -
+
+ )}
- ))} -
+
+ ))}
-
-
+
+
+
+ ) +} + +const EventTemplate: FC< + PageProps<{}, { event: ScheduleSession; speakers: SchedSpeaker[] }> +> = ({ pageContext }) => { + return ( + + + ) } -export default SpeakersTemplate +export default EventTemplate export function Head() { return diff --git a/src/templates/speaker.tsx b/src/templates/speaker.tsx index 013780340c..826aacbcd9 100644 --- a/src/templates/speaker.tsx +++ b/src/templates/speaker.tsx @@ -49,12 +49,12 @@ const SpeakersTemplate: FC<
-
+
<>
Back to Speakers -
+

@@ -153,7 +153,7 @@ function renderPositionAndCompany(speaker: SchedSpeaker) { speaker.url !== "" ? ( {company} diff --git a/src/templates/speakers.tsx b/src/templates/speakers.tsx index 1dbcbfa5a8..ed3bd8b553 100644 --- a/src/templates/speakers.tsx +++ b/src/templates/speakers.tsx @@ -46,7 +46,7 @@ const SpeakersTemplate: FC> = ({
-
+

GraphQLConf 2023 Speakers

Meet the unique lineup of insightful speakers we've carefully @@ -54,7 +54,7 @@ const SpeakersTemplate: FC> = ({ innovative practices in the realm of GraphQL at the conference.

-
+
{speakers.length ? ( speakers.map((speaker: any) => ( diff --git a/yarn.lock b/yarn.lock index 709792d69f..72e220bd01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1465,6 +1465,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.18.3": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/runtime@^7.20.7": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" @@ -1624,6 +1631,18 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.42.0.tgz#484a1d638de2911e6f5a30c12f49c7e4a3270fb6" integrity sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw== +"@floating-ui/core@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.3.1.tgz#4d795b649cc3b1cbb760d191c80dcb4353c9a366" + integrity sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g== + +"@floating-ui/dom@^1.0.0": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.4.5.tgz#336dfb9870c98b471ff5802002982e489b8bd1c5" + integrity sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw== + dependencies: + "@floating-ui/core" "^1.3.1" + "@gatsbyjs/parcel-namer-relative-to-cwd@^2.10.0": version "2.10.0" resolved "https://registry.yarnpkg.com/@gatsbyjs/parcel-namer-relative-to-cwd/-/parcel-namer-relative-to-cwd-2.10.0.tgz#3ad8ba465cde801282809559190893aab1f42e8e" @@ -2495,6 +2514,11 @@ "@pnpm/network.ca-file" "^1.0.1" config-chain "^1.1.11" +"@popperjs/core@^2.11.5": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + "@radix-ui/react-aspect-ratio@1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.0.2.tgz#4d40e9d80d861ae5805e951bc319802d2d65a96e" @@ -2950,6 +2974,13 @@ dependencies: "@types/react" "*" +"@types/react-tooltip@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@types/react-tooltip/-/react-tooltip-4.2.4.tgz#d0acad2a3061806e10aab91dd26a95a77fd35125" + integrity sha512-UzjzmgY/VH3Str6DcAGTLMA1mVVhGOyARNTANExrirtp+JgxhaIOVDxq4TIRmpSi4voLv+w4HA9CC5GvhhCA0A== + dependencies: + react-tooltip "*" + "@types/react@*": version "16.9.55" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.55.tgz#47078587f5bfe028a23b6b46c7b94ac0d436acff" @@ -4215,6 +4246,11 @@ ci-info@2.0.0, ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +classnames@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + cli-boxes@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" @@ -4819,11 +4855,6 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== -data-uri-to-buffer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" - integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== - date-fns@^2.30.0: version "2.30.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" @@ -5976,14 +6007,6 @@ fbjs@^3.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" -fetch-blob@^3.1.2, fetch-blob@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" - integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== - dependencies: - node-domexception "^1.0.0" - web-streams-polyfill "^3.0.3" - figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -6170,13 +6193,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -formdata-polyfill@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" - integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - dependencies: - fetch-blob "^3.1.2" - forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -8992,11 +9008,6 @@ node-addon-api@^6.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== -node-domexception@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -9016,15 +9027,6 @@ node-fetch@^2.6.9: dependencies: whatwg-url "^5.0.0" -node-fetch@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" - integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== - dependencies: - data-uri-to-buffer "^4.0.0" - fetch-blob "^3.1.4" - formdata-polyfill "^4.0.10" - node-gyp-build-optional-packages@5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" @@ -10223,6 +10225,11 @@ react-error-overlay@^6.0.11: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== +react-fast-compare@^3.0.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -10233,6 +10240,23 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-popper-tooltip@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-4.4.2.tgz#0dc4894b8e00ba731f89bd2d30584f6032ec6163" + integrity sha512-y48r0mpzysRTZAIh8m2kpZ8S1YPNqGtQPDrlXYSGvDS1c1GpG/NUXbsbIdfbhXfmSaRJuTcaT6N1q3CKuHRVbg== + dependencies: + "@babel/runtime" "^7.18.3" + "@popperjs/core" "^2.11.5" + react-popper "^2.3.0" + +react-popper@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" + integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== + dependencies: + react-fast-compare "^3.0.1" + warning "^4.0.2" + react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -10247,6 +10271,14 @@ react-server-dom-webpack@0.0.0-experimental-c8b778b7f-20220825: loose-envify "^1.1.0" neo-async "^2.6.1" +react-tooltip@*, react-tooltip@^5.18.1: + version "5.18.1" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.18.1.tgz#72945248d1fa141d5b02e59b50a805d0098b0c01" + integrity sha512-5zUKoMoKHTYxobzhR160+kkHdLtB+yYO8p16aQRoz2jGcOdtV0o1enNynoA4YqQb3xTjl84N8KLNoscmgMNuSg== + dependencies: + "@floating-ui/dom" "^1.0.0" + classnames "^2.3.0" + react@18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" @@ -12044,7 +12076,7 @@ vscode-languageserver-types@^3.17.1: resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== -warning@^4.0.3: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== @@ -12069,11 +12101,6 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== -web-streams-polyfill@^3.0.3: - version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - web-vitals@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-1.1.2.tgz#06535308168986096239aa84716e68b4c6ae6d1c" From 9c25b5e35d8b4b7cf57e7df053e471e4f693fccf Mon Sep 17 00:00:00 2001 From: YassinEldeeb Date: Tue, 25 Jul 2023 13:17:03 +0300 Subject: [PATCH 22/22] fix: build issue --- src/assets/css/global.css | 2 +- src/components/Conf/Header/index.tsx | 10 +- src/components/Conf/Schedule/ScheduleList.tsx | 113 ++++++++---------- 3 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src/assets/css/global.css b/src/assets/css/global.css index 43cbb25787..51c793afb1 100644 --- a/src/assets/css/global.css +++ b/src/assets/css/global.css @@ -1,4 +1,4 @@ -/*@tailwind base;*/ +@tailwind base; @tailwind components; @tailwind utilities; diff --git a/src/components/Conf/Header/index.tsx b/src/components/Conf/Header/index.tsx index 905f9cd7ad..96a7d8be7d 100644 --- a/src/components/Conf/Header/index.tsx +++ b/src/components/Conf/Header/index.tsx @@ -55,13 +55,9 @@ const HeaderConf = () => { )}