diff --git a/.astro/settings.json b/.astro/settings.json index 58d9537..340fa15 100644 --- a/.astro/settings.json +++ b/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1726119011870 + "lastUpdateCheck": 1727383549757 } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 735c7c4..ed4fc95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,13 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@astrojs/mdx": "^3.1.5", - "@astrojs/netlify": "^5.5.2", - "@astrojs/node": "^8.3.3", + "@astrojs/mdx": "^3.1.7", + "@astrojs/netlify": "^5.5.3", + "@astrojs/node": "^8.3.4", "@astrojs/partytown": "^2.1.2", "@astrojs/react": "^3.6.2", "@astrojs/sitemap": "^3.1.6", - "@astrojs/tailwind": "^5.1.0", + "@astrojs/tailwind": "^5.1.1", "@mantine/core": "^7.12.2", "@mantine/form": "^7.12.2", "@mantine/hooks": "^7.12.2", @@ -23,7 +23,7 @@ "@tanstack/react-query": "^5.56.1", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", - "astro": "^4.15.4", + "astro": "^4.15.9", "astro-robots-txt": "^1.0.0", "firebase": "^10.13.1", "react": "^18.2.0", @@ -32,7 +32,8 @@ "react-icons": "^5.3.0", "react-qrcode-logo": "^3.0.0", "sass": "^1.77.8", - "tailwindcss": "^3.3.5" + "tailwindcss": "^3.3.5", + "zustand": "^5.0.0-rc.2" }, "devDependencies": { "daisyui": "^4.12.10", @@ -99,9 +100,9 @@ } }, "node_modules/@astrojs/mdx": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.5.tgz", - "integrity": "sha512-Fu6oShqcDpi0D1b2/3Pg3ao1I+Q2YqKhFsSsuDzn0YhdGrry5oUyABUyCyGq/OayP2P/34Vwj+GCQ/n9h8FlTQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.7.tgz", + "integrity": "sha512-8lGdCt+S0TrZgQpbcP3fQJc4cTeacAirtz9TpAMtHCWrQGW8slKt3WG4/0N+bhZgYRC4h5AT5drzFz+y3wvmsg==", "dependencies": { "@astrojs/markdown-remark": "5.2.0", "@mdx-js/mdx": "^3.0.1", @@ -126,9 +127,9 @@ } }, "node_modules/@astrojs/netlify": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@astrojs/netlify/-/netlify-5.5.2.tgz", - "integrity": "sha512-J8a5Uz04156i8WN38iLQSLKAUKNJH+cGNbizRLoVdqRcfHY5cTwnZzXSSjjrvNNmErk0wsHlmJEA3SYXqCqXEw==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@astrojs/netlify/-/netlify-5.5.3.tgz", + "integrity": "sha512-MDbbJY/Qp02WY9TFusXGA9TFSfaRwc/nlyYhk0YZ2ll2KW2DKrXLCJLC17kdhGqKDyg6w4P6juOOgbcGEpfaUw==", "dependencies": { "@astrojs/internal-helpers": "0.4.1", "@astrojs/underscore-redirects": "^0.3.4", @@ -142,11 +143,11 @@ } }, "node_modules/@astrojs/node": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.3.tgz", - "integrity": "sha512-idrKhnnPSi0ABV+PCQsRQqVNwpOvVDF/+fkwcIiE8sr9J8EMvW9g/oyAt8T4X2OBJ8FUzYPL8klfCdG7r0eB5g==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.4.tgz", + "integrity": "sha512-xzQs39goN7xh9np9rypGmbgZj3AmmjNxEMj9ZWz5aBERlqqFF3n8A/w/uaJeZ/bkHS60l1BXVS0tgsQt9MFqBA==", "dependencies": { - "send": "^0.18.0", + "send": "^0.19.0", "server-destroy": "^1.0.1" }, "peerDependencies": { @@ -202,16 +203,16 @@ } }, "node_modules/@astrojs/tailwind": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@astrojs/tailwind/-/tailwind-5.1.0.tgz", - "integrity": "sha512-BJoCDKuWhU9FT2qYg+fr6Nfb3qP4ShtyjXGHKA/4mHN94z7BGcmauQK23iy+YH5qWvTnhqkd6mQPQ1yTZTe9Ig==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@astrojs/tailwind/-/tailwind-5.1.1.tgz", + "integrity": "sha512-LwurA10uIKcGRxQP2R81RvAnBT0WPKzBntXZBF4hrAefDgM5Uumn0nsGr6tdIjSARgYz4X+Cq/Vh78t3bql3yw==", "dependencies": { - "autoprefixer": "^10.4.15", - "postcss": "^8.4.28", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.45", "postcss-load-config": "^4.0.2" }, "peerDependencies": { - "astro": "^3.0.0 || ^4.0.0", + "astro": "^3.0.0 || ^4.0.0 || ^5.0.0-beta.0", "tailwindcss": "^3.0.24" } }, @@ -2160,9 +2161,9 @@ } }, "node_modules/@oslojs/encoding": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-0.4.1.tgz", - "integrity": "sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -2898,9 +2899,9 @@ } }, "node_modules/astro": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/astro/-/astro-4.15.4.tgz", - "integrity": "sha512-wqy+m3qygt9DmCSqMsckxyK4ccCUFtti2d/WlLkEpAlqHgyDIg20zRTLHO2v/H4YeSlJ8sAcN0RW2FhOeYbINg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/astro/-/astro-4.15.9.tgz", + "integrity": "sha512-51oXq9qrZ5OPWYmEXt1kGrvWmVeWsx28SgBTzi2XW6iwcnW/wC5ONm6ol6qBGSCF93tQvZplXvuzpaw1injECA==", "dependencies": { "@astrojs/compiler": "^2.10.3", "@astrojs/internal-helpers": "0.4.1", @@ -2909,7 +2910,7 @@ "@babel/core": "^7.25.2", "@babel/plugin-transform-react-jsx": "^7.25.2", "@babel/types": "^7.25.6", - "@oslojs/encoding": "^0.4.1", + "@oslojs/encoding": "^1.0.0", "@rollup/pluginutils": "^5.1.0", "@types/babel__core": "^7.20.5", "@types/cookie": "^0.6.0", @@ -2922,7 +2923,7 @@ "common-ancestor-path": "^1.0.1", "cookie": "^0.6.0", "cssesc": "^3.0.0", - "debug": "^4.3.6", + "debug": "^4.3.7", "deterministic-object-hash": "^2.0.2", "devalue": "^5.0.0", "diff": "^5.2.0", @@ -2948,19 +2949,18 @@ "ora": "^8.1.0", "p-limit": "^6.1.0", "p-queue": "^8.0.1", - "path-to-regexp": "^6.2.2", "preferred-pm": "^4.0.0", "prompts": "^2.4.2", "rehype": "^13.0.1", "semver": "^7.6.3", - "shiki": "^1.16.1", + "shiki": "^1.16.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "tinyexec": "^0.3.0", "tsconfck": "^3.1.3", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", - "vite": "^5.4.2", + "vite": "^5.4.3", "vitefu": "^1.0.2", "which-pm": "^3.0.0", "xxhash-wasm": "^1.0.2", @@ -6799,11 +6799,6 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, - "node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" - }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -7784,9 +7779,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9278,6 +9273,34 @@ "zod": "^3" } }, + "node_modules/zustand": { + "version": "5.0.0-rc.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0-rc.2.tgz", + "integrity": "sha512-o2Nwuvnk8vQBX7CcHL8WfFkZNJdxB/VKeWw0tNglw8p4cypsZ3tRT7rTRTDNeUPFS0qaMBRSKe+fVwL5xpcE3A==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 15774e9..a702adf 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,13 @@ "author": "", "license": "ISC", "dependencies": { - "@astrojs/mdx": "^3.1.5", - "@astrojs/netlify": "^5.5.2", - "@astrojs/node": "^8.3.3", + "@astrojs/mdx": "^3.1.7", + "@astrojs/netlify": "^5.5.3", + "@astrojs/node": "^8.3.4", "@astrojs/partytown": "^2.1.2", "@astrojs/react": "^3.6.2", "@astrojs/sitemap": "^3.1.6", - "@astrojs/tailwind": "^5.1.0", + "@astrojs/tailwind": "^5.1.1", "@mantine/core": "^7.12.2", "@mantine/form": "^7.12.2", "@mantine/hooks": "^7.12.2", @@ -27,7 +27,7 @@ "@tanstack/react-query": "^5.56.1", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", - "astro": "^4.15.4", + "astro": "^4.15.9", "astro-robots-txt": "^1.0.0", "firebase": "^10.13.1", "react": "^18.2.0", @@ -36,7 +36,8 @@ "react-icons": "^5.3.0", "react-qrcode-logo": "^3.0.0", "sass": "^1.77.8", - "tailwindcss": "^3.3.5" + "tailwindcss": "^3.3.5", + "zustand": "^5.0.0-rc.2" }, "devDependencies": { "daisyui": "^4.12.10", diff --git a/public/assets/vectors/pin.svg b/public/assets/vectors/pin.svg index 3bcd148..f9e90dd 100644 --- a/public/assets/vectors/pin.svg +++ b/public/assets/vectors/pin.svg @@ -1,3 +1,3 @@ - + diff --git a/public/assets/vectors/time.svg b/public/assets/vectors/time.svg index b0175e1..7c36279 100644 --- a/public/assets/vectors/time.svg +++ b/public/assets/vectors/time.svg @@ -1,10 +1,10 @@ - + - + diff --git a/src/components/Common/Navbar.astro b/src/components/Common/Navbar.astro index 31c249a..9308a5b 100644 --- a/src/components/Common/Navbar.astro +++ b/src/components/Common/Navbar.astro @@ -18,9 +18,9 @@ const translationIcon = await ImportSvg("translation"); const links = [ { link: translatePath(""), name: t("nav.home") }, - //{ link: translatePath("/schedule"), name: t("nav.schedule") }, - // { link: translatePath("/sessions"), name: t("nav.sessions") }, - // { link: translatePath("/speakers"), name: t("nav.speakers") }, + { link: translatePath("/schedule"), name: t("nav.schedule") }, + { link: translatePath("/sessions"), name: t("nav.sessions") }, + { link: translatePath("/speakers"), name: t("nav.speakers") }, { link: translatePath("/location"), name: t("nav.location") }, { link: translatePath("/faq"), name: t("nav.faq") }, { link: translatePath("/team"), name: t("nav.team") }, diff --git a/src/components/Home/Jumbo.astro b/src/components/Home/Jumbo.astro index e1fb930..7623598 100644 --- a/src/components/Home/Jumbo.astro +++ b/src/components/Home/Jumbo.astro @@ -15,6 +15,7 @@ const t = useTranslations(lang);

{ WebsiteConfig.EVENT_START.toLocaleDateString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, day: "numeric", month: "long", year: "numeric", diff --git a/src/components/Home/RandomSpeakerList.tsx b/src/components/Home/RandomSpeakerList.tsx index a16ae2e..358ecdd 100644 --- a/src/components/Home/RandomSpeakerList.tsx +++ b/src/components/Home/RandomSpeakerList.tsx @@ -1,9 +1,12 @@ import type { Speaker } from "../../data/types/sessionize"; +import { getLangFromUrl, useTranslatedPath, useTranslations } from "../../i18n/utils"; -const SpeakerPreviewElement = ({ speaker }: { speaker: Speaker }) => ( - { + const lang = getLangFromUrl(new URL(location.href)); + const getPath = useTranslatedPath(lang); + return

@@ -18,7 +21,7 @@ const SpeakerPreviewElement = ({ speaker }: { speaker: Speaker }) => (

{speaker.tagLine}

-) +} export const RandomSpeakerList = ({ speakers }:{ speakers:Speaker[] }) => { return <>{speakers.sort(() => Math.random() - 0.5).slice(0, 4).map((s) => ( diff --git a/src/components/Home/SpeakerPreview.astro b/src/components/Home/SpeakerPreview.astro index ead4085..e061baa 100644 --- a/src/components/Home/SpeakerPreview.astro +++ b/src/components/Home/SpeakerPreview.astro @@ -1,19 +1,24 @@ --- import { getSpeakers } from "../../data/api/sessionize_api"; +import { getLangFromUrl, useTranslatedPath, useTranslations } from "../../i18n/utils"; import { RandomSpeakerList } from "./RandomSpeakerList"; const speakers = await getSpeakers(); +const lang = getLangFromUrl(Astro.url); +const t = useTranslations(lang); +const getPath = useTranslatedPath(lang); + ---
-

Speakers

+

{t("info.speakers")}

See all Speakers{t("speaker.seeAll")}
diff --git a/src/components/Schedule/Pages/ScheduleList.astro b/src/components/Schedule/Pages/ScheduleList.astro index 01acf33..14a2b03 100644 --- a/src/components/Schedule/Pages/ScheduleList.astro +++ b/src/components/Schedule/Pages/ScheduleList.astro @@ -1,201 +1,55 @@ --- -import ScheduleCard from "../ScheduleCard.astro"; import { getLangFromUrl, useTranslations } from "../../../i18n/utils"; import { getSchedule } from "../../../data/api/sessionize_api"; +import ScheduleTab from "./ScheduleTab.astro"; -const schedule = (await getSchedule()).map((s) => { - s.rooms = s.rooms.map((r) => { - r.sessions = r.sessions.map((si) => { - if (si.title.indexOf("42!") != -1){ - si.endsAt = "2024-10-26T14:35:00Z" - } - return si - }); - return r - }); - s.timeSlots = s.timeSlots.map((ts) => { - ts.rooms = ts.rooms.map((r) => { - if (r.session.title.indexOf("42!") != -1){ - r.session.endsAt = "2024-10-26T14:35:00Z" - } - return r - }); - return ts - }) - return s -}); +/* + - 51235:"Frontend" + - 51236:"Mobile" + - 51237:"Cloud" + - 53346:"Soft skill" + - 53347:"AI" + - 53348:"WS I" + - 53349:"WS II" + - 53350:"WS III" +*/ + +const schedule = await getSchedule() const lang = getLangFromUrl(Astro.url); const t = useTranslations(lang); +const tab1Rooms = [51235, 51236, 51237, 53347, 53346]; +const tab2Rooms = [53348, 53349, 53350]; + ---
- -{ - schedule.map((s) => { - const totalScheduleCols = s.rooms.length; - const totalScheduleRows = s.timeSlots.length; - let skipPadding: {[key:string]:number} = s.rooms.map((room) => ({[room.id]:0})).reduce((a,b)=>({...a,...b}),{}) - return ( -
-

- {new Date(s.date).toLocaleDateString("en-US", { - day: "numeric", - month: "long", - weekday: "long", - })} -

- {/* Some classes are created manually due to tilewind issues */} -
- {s.timeSlots.map((ts,ts_idx) => { - - const hasServiceSession = ts.rooms.some( - (tsr) => tsr.session.isServiceSession, - ); - - const sessionsInTimeSlot = ts.rooms.map((tsr) => { - const endDate = new Date(tsr.session.endsAt); - endDate.setSeconds(0) - endDate.setMilliseconds(0) - const slots = !hasServiceSession? ( - //Function that calculate the rows to take for this session - (()=>{ - //Calculate the space to take (how many timeSlot takes this session (until a service session)) - let session_len = 1 - let last_is_service = false - for (let i = ts_idx+1; i < s.timeSlots.length; i++){ - //No sessions - if (s.timeSlots[i].rooms.length == 0) continue - //Take time from one of the sessions - //Get next start date - const next_date = new Date(s.timeSlots[i].rooms[0].session.startsAt) - next_date.setSeconds(0) - next_date.setMilliseconds(0) - //If it's a service session, can't take this space - if (s.timeSlots[i].rooms.some( (tsr) => tsr.session.isServiceSession)){ - last_is_service = true - continue //We need to check if replicate this session for the next timeSlot that is not a service session - } - if (last_is_service){ //We stopped at a service session and need to check if replicate this session in next timeSlots - if (next_date < endDate){ - s.timeSlots[i].rooms.push(tsr) //Replicate - } - break - } - //Continue to get space until this session ends - if (next_date < endDate){ - session_len ++ - }else{ - break - } - } - return session_len - })() - ) : 1; - if (slots > 1){ - skipPadding[tsr.id.toString()] = slots-1 - } - return { - data: tsr, - html:
- -
- }; - }); - - const orderedSessions = ( - !hasServiceSession? - s.rooms.map( - (room) => { - let session = sessionsInTimeSlot.find((target) => room.id == target.data.id) - if (!session){ - if (skipPadding[room.id.toString()]){ - skipPadding[room.id.toString()]-- - return null - } - return
- } - return session?.html - } - ).filter((ele)=>ele!=null) : sessionsInTimeSlot.map((session) => session.html) - ) - - return [ -
-

{ts.slotStart.substring(0, 5)}

-
, - ...orderedSessions - ]; - })} -
-
- ); - }) - } +
+ +
+ +
+ + +
+ +
+
+ {schedule.length == 0?

{t("scheduling.noschedule")}

:null} - +
\ No newline at end of file diff --git a/src/components/Schedule/Pages/ScheduleTab.astro b/src/components/Schedule/Pages/ScheduleTab.astro new file mode 100644 index 0000000..8ff20aa --- /dev/null +++ b/src/components/Schedule/Pages/ScheduleTab.astro @@ -0,0 +1,155 @@ +--- +import type { ScheduleDay } from "../../../data/types/sessionize"; +import { getLangFromUrl } from "../../../i18n/utils"; +import ScheduleCard from "../ScheduleCard.astro"; +import { capitalizeFirstLetter } from "../../../react/utils"; +import { WebsiteConfig } from "../../../config"; + +interface Props { + schedule: ScheduleDay[]; + rooms?: number[]; +} + +const lang = getLangFromUrl(Astro.url); +const { schedule, rooms } = Astro.props; + +const calcSlotsTaken = (timeSlots, tsr, ts_idx) => { + const endDate = new Date(tsr.session.endsAt); + endDate.setSeconds(0) + endDate.setMilliseconds(0) + //Calculate the space to take (how many timeSlot takes this session (until a service session)) + let session_len = 1; + let last_is_service = false; + for (let i = ts_idx+1; i < timeSlots.length; i++){ + //No sessions + if (timeSlots[i].rooms.length == 0) continue + //Take time from one of the sessions + //Get next start date + const next_date = new Date(timeSlots[i].rooms[0].session.startsAt) + next_date.setSeconds(0) + next_date.setMilliseconds(0) + //If it's a service session, can't take this space + if (timeSlots[i].rooms.some( (tsr) => tsr.session.isServiceSession)){ + last_is_service = true + continue //We need to check if replicate this session for the next timeSlot that is not a service session + } + if (last_is_service){ //We stopped at a service session and need to check if replicate this session in next timeSlots + if (next_date < endDate){ + timeSlots[i].rooms.push(tsr) //Replicate + } + break + } + //Continue to get space until this session ends + if (next_date < endDate){ + session_len ++ + }else{ + break + } + } + return session_len + } + + const isServiceTimeSlot = (ts) => ts.rooms.some((tsr) => tsr.session.isServiceSession); + +--- +
+ {schedule.map((s) => { + const roomsSelected = rooms?s.rooms.filter((r) => rooms.includes(r.id)):s.rooms + const timeSlotSelected = s.timeSlots.filter((ts) => ts.rooms.some((tsr) => roomsSelected.map(r => r.id).includes(tsr.id)) || isServiceTimeSlot(ts)); + const totalScheduleCols = roomsSelected.length; + let skipPadding: {[key:string]:number} = roomsSelected.map((room) => ({[room.id]:0})).reduce((a,b)=>({...a,...b}),{}); + return <> +
+

+ {capitalizeFirstLetter(new Date(s.date).toLocaleDateString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, + day: "numeric", + month: "long", + weekday: "long", + }))} +

+ {/* Some classes are created manually due to tilewind issues */} +
+ {timeSlotSelected.map((ts,ts_idx) => { + + const hasServiceSession = isServiceTimeSlot(ts) + + const sessionsInTimeSlot = ts.rooms.map((tsr) => { + const slots = !hasServiceSession? calcSlotsTaken(timeSlotSelected, tsr, ts_idx) : 1; + if (slots > 1){ + skipPadding[tsr.id.toString()] = slots-1 + } + return { + data: tsr, + html: <> +
+ +
+ , + }; + }); + + const orderedSessions = ( + !hasServiceSession? + roomsSelected.map( + (room) => { + let session = sessionsInTimeSlot.find((target) => room.id == target.data.id) + if (!session){ + if (skipPadding[room.id.toString()]){ + skipPadding[room.id.toString()]-- + return null + } + return <>
+ } + return session?.html + } + ).filter((ele)=>ele!=null) : sessionsInTimeSlot.map((session) => session.html) + ) + + return [ +
+

{ts.slotStart}

+
, + ...orderedSessions + ]; + })} +
+
+ + }) + } + +
\ No newline at end of file diff --git a/src/components/Schedule/ScheduleCard.astro b/src/components/Schedule/ScheduleCard.astro index a5cf74f..aaca5c4 100644 --- a/src/components/Schedule/ScheduleCard.astro +++ b/src/components/Schedule/ScheduleCard.astro @@ -1,5 +1,6 @@ --- import type { ScheduleSlotRoom } from '../../data/types/sessionize'; +import { getLangFromUrl, useTranslatedPath, useTranslations } from '../../i18n/utils'; interface Props { @@ -7,6 +8,9 @@ interface Props { } const { value } = Astro.props; +const lang = getLangFromUrl(Astro.url); +const t = useTranslations(lang); +const getPath = useTranslatedPath(lang); const hasSpeakers = value.session.info && value.session.info.speakers; @@ -16,14 +20,16 @@ const url = !value.session.isServiceSession --- -{!value.session.isServiceSession &&

{value.name}

} + {!value.session.isServiceSession &&

{value.name}

}

{value.session.title}

+
+ {value.session.isServiceSession &&

{t("session.room")}: {value.name}

}
{ hasSpeakers && diff --git a/src/components/Sessions/Pages/SessionDetail.astro b/src/components/Sessions/Pages/SessionDetail.astro index 913e887..2b03a22 100644 --- a/src/components/Sessions/Pages/SessionDetail.astro +++ b/src/components/Sessions/Pages/SessionDetail.astro @@ -5,6 +5,8 @@ import { getLangFromUrl, useTranslatedPath, useTranslations } from '../../../i18 import AddToCalendar from '../../Common/AddToCalendar.astro'; import BaseLayout from '../../Common/BaseLayout.astro'; import SessionTopic from '../SessionTopic.astro'; +import { capitalizeFirstLetter } from "../../../react/utils"; +import { WebsiteConfig } from '../../../config'; interface Props { entry: SessionInfo; @@ -30,33 +32,24 @@ const dateEnd = new Date(entry.endsAt); const isScheduled = dateStart.getTime() != 0; -var date = dateStart.toLocaleDateString("en-US", { +var date = capitalizeFirstLetter(dateStart.toLocaleDateString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, day: "numeric", month: "short", -}); +})); -const start = dateStart.toLocaleTimeString("en-US", { +const start = dateStart.toLocaleTimeString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, hour: "numeric", minute: "numeric", }); -const end = dateEnd.toLocaleTimeString("en-US", { +const end = dateEnd.toLocaleTimeString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, hour: "numeric", minute: "numeric", }); -function formatDate(date: Date) { - const year = date.getUTCFullYear(); - const month = date.getUTCMonth() + 1; - const day = date.getUTCDate(); - const hours = date.getUTCHours(); - const minutes = date.getUTCMinutes(); - - return `${year}${month}${day > 9 ? day : "0" + day}T${ - hours > 9 ? hours : "0" + hours - }${minutes > 9 ? minutes : "0" + minutes}00Z`; -} - const pageTitle = entry.title; const pageDesc = entry.description; --- @@ -92,7 +85,7 @@ const pageDesc = entry.description; {entry.topics.map((t) => )}
-

{entry.room}

+

{t("session.room")}: {entry.room}

{ isScheduled && (

diff --git a/src/components/Sessions/SessionCard.astro b/src/components/Sessions/SessionCard.astro index 134e81b..62874e7 100644 --- a/src/components/Sessions/SessionCard.astro +++ b/src/components/Sessions/SessionCard.astro @@ -14,7 +14,9 @@ const dateStart = new Date(session.startsAt); const dateEnd = new Date(session.endsAt); const duration = dateEnd.getTime() - dateStart.getTime(); -const durationMinutes = duration / 60000; +const minDuration = Math.floor(duration / (1000*60)); +const durationHours = Math.floor(minDuration / 60); +const durationMinutes = minDuration%60 const lang = getLangFromUrl(Astro.url); const getPath = useTranslatedPath(lang); @@ -23,7 +25,7 @@ const t = useTranslations(lang); ---

{session.title}

@@ -47,12 +49,15 @@ const t = useTranslations(lang); ) } { - durationMinutes > 0 && ( + minDuration > 0 && (
session duration
-
{durationMinutes} {t("sessions.shortMinutes")}
+
+ {durationHours == 0 ? null : `${durationHours} ${t("sessions.shortHours")}`} + {durationMinutes == 0 ? null : `${durationMinutes} ${t("sessions.shortMinutes")}`} +
) } diff --git a/src/components/Speakers/Pages/SpeakerDetail.astro b/src/components/Speakers/Pages/SpeakerDetail.astro index e0c4377..6f24fee 100644 --- a/src/components/Speakers/Pages/SpeakerDetail.astro +++ b/src/components/Speakers/Pages/SpeakerDetail.astro @@ -70,7 +70,8 @@ const pageTitle = `${speaker.fullName} @ ${WebsiteConfig.DEVFEST_NAME}`; const dateStart = new Date(session.startsAt); const dateEnd = new Date(session.endsAt); - const date = dateStart.toLocaleDateString("en-US", { + const date = dateStart.toLocaleDateString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, month: "long", day: "numeric", }); diff --git a/src/config.ts b/src/config.ts index 577221d..cde38d9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -22,6 +22,7 @@ export class WebsiteConfig { public static readonly EVENT_START : Date = new Date('2024-10-26'); public static readonly EVENT_END : Date = new Date('2024-10-26'); + public static readonly EVENT_TIMEZONE : string = 'Europe/Rome'; public static readonly EVENT_LOCATION_NAME : String = 'Polythecnic of Bari'; public static readonly EVENT_LOCATION_CITY : String = 'Bari'; public static readonly EVENT_LOCATION_ADDRESS : String = 'Via Edoardo Orabona 4'; diff --git a/src/data/api/authentication_api.ts b/src/data/api/authentication_api.ts new file mode 100644 index 0000000..0d71292 --- /dev/null +++ b/src/data/api/authentication_api.ts @@ -0,0 +1,11 @@ +import type { CheckTokenResponse, SignupResponse } from "../types/authentication"; + +export class AuthenticationApi { + async checkToken(token: string): Promise { + return { status: true, errorMessage: null }; + } + + async signInWithEmailAndPassword(email: string, password: string): Promise { + return { status: true, errorMessage: null }; + } +} \ No newline at end of file diff --git a/src/data/api/firebase_api.ts b/src/data/api/firebase_api.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/data/api/sessionize_api.ts b/src/data/api/sessionize_api.ts index e6d325d..bb663c2 100644 --- a/src/data/api/sessionize_api.ts +++ b/src/data/api/sessionize_api.ts @@ -1,3 +1,4 @@ +import { WebsiteConfig } from "../../config"; import type { ScheduleDay, SessionInfo, Speaker } from "../types/sessionize"; const API_ID = "1rh747m6" @@ -19,12 +20,15 @@ export async function getSchedule(): Promise> { schedule.forEach( day => day.timeSlots.forEach( - slot => slot.rooms.forEach( - room => { - const sessionInfoFound = sessionsInfo.find((_s) => _s.id == room.session.id); - room.session.info = sessionInfoFound; - }, - ), + (slot, slot_idx) => { + day.timeSlots[slot_idx].slotStart = new Date(slot.rooms[0].session.startsAt).toLocaleString("it", {timeZone: WebsiteConfig.EVENT_TIMEZONE, hour:"numeric", minute:"numeric"}) + slot.rooms.forEach( + room => { + const sessionInfoFound = sessionsInfo.find((_s) => _s.id == room.session.id); + room.session.info = sessionInfoFound; + }, + ) + } ), ); diff --git a/src/data/repositories/authentication_repository.ts b/src/data/repositories/authentication_repository.ts new file mode 100644 index 0000000..514fe58 --- /dev/null +++ b/src/data/repositories/authentication_repository.ts @@ -0,0 +1,25 @@ +import { AuthenticationApi } from "../api/authentication_api"; +import type { SignUpException } from "../types/authentication"; + +export class AuthenticationRepository { + api: AuthenticationApi; + + constructor() { + this.api = new AuthenticationApi(); + } + + async checkToken(token: string): Promise { + const result = await this.api.checkToken(token); + return result.status; + } + + async signInWithEmailAndPassword(email: string, password: string): Promise { + const result = await this.api.signInWithEmailAndPassword(email, password); + + if (!result.status) { + throw { + message: result.errorMessage + } as SignUpException; + } + } +} \ No newline at end of file diff --git a/src/data/types/authentication.ts b/src/data/types/authentication.ts new file mode 100644 index 0000000..28adf07 --- /dev/null +++ b/src/data/types/authentication.ts @@ -0,0 +1,13 @@ +export type CheckTokenResponse = { + status: boolean; + errorMessage: string | null; +} + +export type SignupResponse = { + status: boolean; + errorMessage: string | null; +} + +export type SignUpException = { + message: string; +} \ No newline at end of file diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index 061e2c7..f2571ac 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -31,6 +31,7 @@ export const ui = { 'community.cta': 'Join us', 'sessions.listTitle': 'Sessions', 'sessions.shortMinutes': 'mins', + 'sessions.shortHours': 'hrs', 'sessions.toBeAnnunced': 'To be annunced', 'session.detailTitle': 'Session details', 'session.speakers': 'Speakers', @@ -40,6 +41,7 @@ export const ui = { 'speakers.detailTitle': 'Speaker details', 'speakers.sessionList': 'Sessions', 'scheduling.noschedule': 'Schedule not available', + 'session.room': 'Room', }, it: { 'nav.home': 'Home', @@ -57,7 +59,7 @@ export const ui = { 'info.speakers': 'Speaker', 'info.tracks': 'Track', 'info.categories': 'Categorie', - 'speaker.seeAll': 'Vedi tutti gli speaker', + 'speaker.seeAll': 'Tutti gli speaker', 'hero.ticketsAvailable': 'BIGLIETTI DISPONIBILI', 'ticket.title': 'Prenota ora il tuo biglietto', 'ticket.free': 'GRATIS', @@ -65,6 +67,7 @@ export const ui = { 'community.cta': 'Unisciti', 'sessions.listTitle': 'Sessioni', 'sessions.shortMinutes': 'min', + 'sessions.shortHours': 'ore', 'sessions.toBeAnnunced': 'Da annuncare', 'session.detailTitle': 'Dettagli sessione', 'session.speakers': 'Speaker', @@ -74,5 +77,6 @@ export const ui = { 'speakers.detailTitle': 'Dettagli speaker', 'speakers.sessionList': 'Sessioni', 'scheduling.noschedule': 'Schedule non disponibile', + 'session.room': 'Aula', }, } as const; \ No newline at end of file diff --git a/src/pages/404.astro b/src/pages/404.astro index c9a6ca4..1bc6f83 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,13 +1,10 @@ --- -// Welcome to Astro! Everything between these triple-dash code fences import Footer from "../components/Common/Footer.astro"; import Navbar from "../components/Common/Navbar.astro"; import PageHead from "../components/Common/PageHead.astro"; --- - diff --git a/src/pages/app.astro b/src/pages/app.astro index 9d5f3c9..946fd83 100644 --- a/src/pages/app.astro +++ b/src/pages/app.astro @@ -5,9 +5,9 @@ import { PageComponent } from "../react/PageComponent"; - + -
+
diff --git a/src/pages/en/404.astro b/src/pages/en/404.astro index ef11eca..1dfbf8b 100644 --- a/src/pages/en/404.astro +++ b/src/pages/en/404.astro @@ -1,5 +1,4 @@ --- -// Welcome to Astro! Everything between these triple-dash code fences import Footer from "../../components/Common/Footer.astro"; import Navbar from "../../components/Common/Navbar.astro"; @@ -7,8 +6,6 @@ import PageHead from "../../components/Common/PageHead.astro"; --- - diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro index 3c9b2e5..cc5c5fe 100644 --- a/src/pages/en/index.astro +++ b/src/pages/en/index.astro @@ -18,8 +18,6 @@ const lang = getLangFromUrl(Astro.url); const getPath = useTranslatedPath(lang); --- - @@ -41,7 +39,7 @@ const getPath = useTranslatedPath(lang); > - +

diff --git a/src/pages/index.astro b/src/pages/index.astro index 50f0199..91e76b1 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,5 +1,4 @@ --- -// Welcome to Astro! Everything between these triple-dash code fences import Footer from "../components/Common/Footer.astro"; import Navbar from "../components/Common/Navbar.astro"; @@ -19,8 +18,6 @@ const lang = getLangFromUrl(Astro.url); const getPath = useTranslatedPath(lang); --- - @@ -41,7 +38,7 @@ const getPath = useTranslatedPath(lang); - +

diff --git a/src/pages/login.astro b/src/pages/login.astro index d800524..bb34688 100644 --- a/src/pages/login.astro +++ b/src/pages/login.astro @@ -5,9 +5,9 @@ import { PageComponent } from "../react/PageComponent"; - + -

+
diff --git a/src/pages/redirect/[url_encoded].astro b/src/pages/redirect/[url_encoded].astro index b1a7a27..9ee1e1d 100644 --- a/src/pages/redirect/[url_encoded].astro +++ b/src/pages/redirect/[url_encoded].astro @@ -57,18 +57,19 @@ const t = useTranslations(lang); some magic sprinkled in to help you build great templates. --> - + -
+

{ WebsiteConfig.EVENT_START.toLocaleDateString(lang, { + timeZone: WebsiteConfig.EVENT_TIMEZONE, day: "numeric", month: "long", year: "numeric", diff --git a/src/pages/signup.astro b/src/pages/signup.astro index baa7b49..cea1911 100644 --- a/src/pages/signup.astro +++ b/src/pages/signup.astro @@ -5,9 +5,9 @@ import { PageComponent } from "../react/PageComponent"; - + -

+
diff --git a/src/pages/ticket.astro b/src/pages/ticket.astro index 70ada61..7a1154c 100644 --- a/src/pages/ticket.astro +++ b/src/pages/ticket.astro @@ -8,13 +8,11 @@ const lang = "it" const t = useTranslations(lang); --- - - + -
+