diff --git a/package.json b/package.json index a0720f2..02dd743 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "w3pn-web", "type": "module", - "version": "1.2.2", + "version": "1.2.3", "scripts": { "dev": "astro dev", "start": "astro dev", diff --git a/src/components/EventItem.astro b/src/components/EventItem.astro index 1b35f0e..4977406 100644 --- a/src/components/EventItem.astro +++ b/src/components/EventItem.astro @@ -22,22 +22,32 @@ const status = eventStatus(item)
{nameRenderer(item)} + {item.issue && + #{item.issue} + }
{item.type === "hackathon" && HACKATHON} {item.type === "summit" && SUMMIT} + {item.type === "online-summit" && ONLINE} {item.type === "privacy-corner" && ↴ PC} {item.tags && item.tags.includes("sfe") && SFE}
- -
- {item.city}, {item.country.toUpperCase()} - {item.coincidence && -  - {ccRenderer(item)} - } -
+ {item.type !== 'online-summit' && + +
+ {item.city}, {item.country.toUpperCase()} + {item.coincidence && +  - {ccRenderer(item)} + } +
+ } + {item.type === 'online-summit' && + +
Global
+ }
@@ -78,18 +88,21 @@ const status = eventStatus(item)
Date: {dateFormat(item.date)} {item.days ? ' - ' + dateFormat(dateEnd(item.date, item.days)) + ` (${item.days} days)` : ''}
- Venue: {item.place && || "TBD"} + {item.type !== 'online-summit' && +
Venue: {item.place && || "TBD"}
+ } {item.place && item['place-address'] && @ {item['place-address']} }
Status: {status.title}
-
Lead: {item.lead || 'n/a'}
+ -
+
+ {item.links?.rsvp && - + } {item.links?.web && diff --git a/src/components/EventsPage.astro b/src/components/EventsPage.astro new file mode 100644 index 0000000..4126e8f --- /dev/null +++ b/src/components/EventsPage.astro @@ -0,0 +1,147 @@ +--- + +import BaseLayout from '../layouts/base.astro'; +import core from '../core.json'; +import EventItem from '../components/EventItem.astro'; +import { isFuture } from 'date-fns'; +import { types, countryNames } from '../lib/events.js'; + +const { type: selectedType } = Astro.props; +const { country: selectedCountry } = Astro.props; + +const typeObj = selectedType ? types.find(t => t.id === selectedType) : null +const countryObj = selectedCountry ? { name: countryNames[selectedCountry] } : null + +let title = 'Events'; +if (selectedType) { + title = typeObj.plural +} +if (selectedCountry) { + title = 'Events in ' + countryObj.name +} + +let events = core.events; + +if (selectedType) { + events = core.events.filter(ev => ev.type === selectedType) +} +if (selectedCountry) { + events = core.events.filter(ev => ev.country === selectedCountry) +} + +function eventsFilter (year, future=true) { + return function (x) { + if (!x.date.match(new RegExp(`^${year}`))) { + return false + } + const isDate = x.date.match(/^\d{4}-\d{2}-\d{2}$/) + if (!isDate) { + return false + } + return future ? isFuture(new Date(x.date)) : !isFuture(new Date(x.date)) + } +} + +const pastYears = [...new Set(events.map(e => e.date.match(/^(\d{4})/)[1]))]; +const upcoming = events.filter(x => x.date.match(/^2024/)) + +const past = {} +let pastTotal = 0 +for (const year of pastYears.reverse()) { + past[year] = events.filter(eventsFilter(year, false)).reverse() + pastTotal += past[year].length +} + +let places = [{ id: '', country: 'All countries', num: core.events.length }]; +for (const ev of core.events) { + const found = places.find(p => p.country === ev.country) + if (found) { + found.num++; + continue; + } + if (!ev.country) { + continue; + } + places.push({ + id: ev.country?.toLowerCase(), + country: ev.country, + num: 1, + }) +} +places = places.sort((x, y) => x.num < y.num ? 1 : -1) +--- + + + +
+ + + + + + {upcoming.length > 0 && +
+

Upcoming {title} ({upcoming.length})

+
+ {upcoming.map((event) => ( + + ))} +
+
+ } + + {pastTotal > 0 && +
+

Past {title} ({events.length-upcoming.length})

+ {pastYears.map((year) => ( + past[year].length > 0 && +

{year} ({past[year].length})

+
+ {past[year]?.map((event) => ( + + ))} +
+ ))} +
+ } + +

+ Source repository +

+
+ + + +
\ No newline at end of file diff --git a/src/contributors.json b/src/contributors.json index 0745b5b..2bf7cf1 100644 --- a/src/contributors.json +++ b/src/contributors.json @@ -59,7 +59,7 @@ "received_events_url": "https://api.github.com/users/burningtree/received_events", "type": "User", "site_admin": false, - "contributions": 765 + "contributions": 766 }, { "login": "EclecticSamurai", diff --git a/src/core.json b/src/core.json index e3fd296..d86920d 100644 --- a/src/core.json +++ b/src/core.json @@ -870,7 +870,10 @@ "name-extension": "Q2", "date": "2024-06-23", "lead": "Tree", - "slots": 8 + "slots": 8, + "links": { + "rsvp": "https://lu.ma/w3pn-os24q2" + } }, { "id": "m24bcn", diff --git a/src/lib/events.js b/src/lib/events.js index 1aad46e..1f5b912 100644 --- a/src/lib/events.js +++ b/src/lib/events.js @@ -1,5 +1,30 @@ import { format, compareAsc, addDays, isFuture } from 'date-fns'; +export const types = [ + { id: "", plural: 'All events'}, + { id: "meetup", name: 'Meetup', plural: 'Meetups' }, + { id: "summit", name: 'Summit', plural: 'Summits' }, + { id: "privacy-corner", name: 'Privacy Corner', plural: 'Privacy Corners' }, + { id: "online-summit", name: 'Online Summit', plural: 'Online Summits' }, +] + +export const countryNames = { + cz: 'Czechia', + it: 'Italy', + de: 'Germany', + es: 'Spain', + si: 'Slovenia', + dk: 'Denmark', + pl: 'Poland', + be: 'Belgium', + pt: 'Portugal', + ee: 'Estonia', + nl: 'Netherlands', + ro: 'Romania', + gr: 'Greece', + th: 'Thailand', +} + export function dateInfo (item) { const isDate = item.date.match(/^\d{4}-\d{2}-\d{2}$/) const future = isDate && !isFuture(new Date(item.date)); @@ -45,6 +70,9 @@ export function nameRenderer (item, full = false) { case 'privacy-corner': return `Privacy Corner at `+ (item.coincidenceFull ? item.coincidenceFull : `${item.coincidence} ${date.year}`) break; + case 'online-summit': + return "ONLINE Summit" + (item['name-extension'] ? ' ' + item['name-extension'] : '') + (full ? ` ${date.year}` : ''); + break; } } diff --git a/src/pages/event/[id].astro b/src/pages/event/[id].astro index fca7291..bbfff90 100644 --- a/src/pages/event/[id].astro +++ b/src/pages/event/[id].astro @@ -30,19 +30,27 @@ const ext = findExt(EventsExt, item)

W3PN {nameRenderer(item, true)}

- -
- {item.city}, {item.country.toUpperCase()} - {item.coincidence && -  - {ccRenderer(item)} - } -
+ {item.type !== 'online-summit' && + +
+ {item.city}, {item.country.toUpperCase()} + {item.coincidence && +  - {ccRenderer(item)} + } +
+ } + {item.type === 'online-summit' && + +
Online
+ }
Date: {dateFormat(item.date)} {item.days ? ' - ' + dateFormat(dateEnd(item.date, item.days)) + ` (${item.days} days)` : ''}
- Venue: {item.place && || "TBD"} + {item.type !== 'online-summit' && +
Venue: {item.place && || "TBD"}
+ } {item.place && item['place-address'] && @ {item['place-address']} diff --git a/src/pages/events.astro b/src/pages/events.astro index ad5ced7..0fd6d79 100644 --- a/src/pages/events.astro +++ b/src/pages/events.astro @@ -1,82 +1,7 @@ --- -import BaseLayout from '../layouts/base.astro'; -import core from '../core.json'; -import EventItem from '../components/EventItem.astro'; -import { isFuture } from 'date-fns'; - -const events = core.events; - -function eventsFilter (year, future=true) { - return function (x) { - if (!x.date.match(new RegExp(`^${year}`))) { - return false - } - const isDate = x.date.match(/^\d{4}-\d{2}-\d{2}$/) - if (!isDate) { - return false - } - return future ? isFuture(new Date(x.date)) : !isFuture(new Date(x.date)) - } -} - -const currentYear = "2024"; -const pastYears = [ 2023, 2024 ]; -const upcoming = events.filter(x => x.date.match(/^2024/)) - -const past = {} -for (const year of pastYears.reverse()) { - past[year] = events.filter(eventsFilter(year, false)).reverse() -} +import EventsPage from '../components/EventsPage.astro'; --- - - -
- - - -

Upcoming ({upcoming.length})

- -
- {upcoming.map((event) => ( - - ))} -
- -

Past events ({events.length-upcoming.length})

- {pastYears.map((year) => ( - past[year].length > 0 && -

{year} ({past[year].length})

-
- {past[year]?.map((event) => ( - - ))} -
- ))} - -

- Source repository -

-
- - - -
\ No newline at end of file + \ No newline at end of file diff --git a/src/pages/events/[type].astro b/src/pages/events/[type].astro new file mode 100644 index 0000000..a581912 --- /dev/null +++ b/src/pages/events/[type].astro @@ -0,0 +1,14 @@ +--- + +import EventsPage from '../../components/EventsPage.astro'; +import { types } from '../../lib/events.js'; + +const { type } = Astro.params; + +export async function getStaticPaths() { + return types.filter(obj => obj.id).map(obj => ({ params: { type: obj.id }})); +} + +--- + + \ No newline at end of file diff --git a/src/pages/events/country/[country].astro b/src/pages/events/country/[country].astro new file mode 100644 index 0000000..64a5fbf --- /dev/null +++ b/src/pages/events/country/[country].astro @@ -0,0 +1,24 @@ +--- + +import EventsPage from '../../../components/EventsPage.astro'; +import { types } from '../../../lib/events.js'; +import core from '../../../core.json'; + +const { country } = Astro.params; + +export async function getStaticPaths() { + const countries = [] + for (const ev of core.events) { + if (!ev.country) { + continue + } + if (!countries.includes(ev.country)) { + countries.push(ev.country) + } + } + return countries.map(country => ({ params: { country }})); +} + +--- + + \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index 206546a..0e8e1ee 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -8,9 +8,11 @@ import talks from '../talks.json'; import explorer from '../explorer.json'; import dbRepo from '../db-repo.json'; import { isPast, format } from 'date-fns'; +import EventItem from '../components/EventItem.astro'; const events = core.events; +const upcomingEvents = [] let eventsPast = 0 let eventsUpcoming = 0 for (const ev of events) { @@ -19,12 +21,23 @@ for (const ev of events) { future = false } if (future) { + upcomingEvents.push(ev) eventsUpcoming++ } else { eventsPast++ } } +const featuredEvents = [] +for (const e of upcomingEvents) { + if (featuredEvents.length > 2) { + break; + } + if (['summit', 'meetup', 'online-summit'].includes(e.type) && + e.links?.rsvp && !featuredEvents.find(ex => ex.type === e.type)) { + featuredEvents.push(e) + } +} --- @@ -80,11 +93,21 @@ for (const ev of events) {
-

Featured Events

- +

Featured Upcoming Events

+
+ +
+ {featuredEvents.map((event) => ( + + ))} +
+ +

Latest Articles