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 [
+
,
+ ...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 && (
-
{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);
---
-
-
+
-
+