Skip to content

Commit 6b125b8

Browse files
committed
add pinia/nuxt
update the sponsors page grouped by year
1 parent a9962ec commit 6b125b8

File tree

7 files changed

+126
-79
lines changed

7 files changed

+126
-79
lines changed

packages/frontendmu-nuxt/components/site/MeetupSponsors.vue

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,71 @@
11
<script setup lang="ts">
2-
import type { Sponsor } from '@/utils/types'
2+
import { computed } from 'vue'
3+
import { storeToRefs } from 'pinia'
4+
import { useSponsorStore } from '../../store/sponsorStore'
5+
import type { Sponsor } from '../../store/sponsorStore'
6+
import Card from '@/components/base/Card.vue'
37
4-
function sponsorLogoUrl(sponsor: Sponsor) {
5-
return `https://directus.frontend.mu/assets/${sponsor.Sponsor_id.Logo.filename_disk}`
6-
}
7-
8-
const { allSponsors } = useMeetups({})
8+
const sponsorStore = useSponsorStore()
9+
const sortedMeetupsByYear = computed(() => sponsorStore.getMeetupsGroupedByYearSorted)
910
10-
const sponsorTypeMap: { [key: string]: string } = {
11-
lunch: 'Lunch Sponsor',
12-
venue: 'Venue Sponsor',
11+
function sponsorLogoUrl(sponsor: Sponsor) {
12+
if (typeof sponsor.logo === 'string') {
13+
return `https://directus.frontend.mu/assets/${sponsor.logo}`
14+
}
15+
return ''
1316
}
1417
15-
function sponsorClassList(sponsor: Sponsor) {
16-
return [
17-
sponsor.Sponsor_id.darkbg ? 'bg-verse-900/90 text-verse-100' : 'bg-white text-verse-800',
18-
'p-2 items-center shadow-md relative rounded-lg flex flex-wrap justify-center gap-4 text-xs',
19-
]
18+
function isRecentSponsorship(meetups: { date: string }[]): boolean {
19+
if (!meetups.length)
20+
return false
21+
// Get most recent event date
22+
const mostRecent = meetups.reduce((max, m) => m.date > max ? m.date : max, '')
23+
if (!mostRecent)
24+
return false
25+
const eventDate = new Date(mostRecent)
26+
const now = new Date()
27+
const diffMonths = (now.getFullYear() - eventDate.getFullYear()) * 12 + (now.getMonth() - eventDate.getMonth())
28+
return diffMonths <= 6
2029
}
2130
</script>
2231

2332
<template>
24-
<div class="grid lg:grid-cols-7 md:gap-8 md:grid-cols-3 grid-cols-2 gap-4 auto-rows-auto">
25-
<!-- <template v-for="sponsor in allSponsors" :key="sponsor.Sponsor_id">
26-
<img class="h-16 w-20 md:w-auto object-contain md:object-cover" :src="sponsorLogoUrl(sponsor)"
27-
:alt="sponsor.Sponsor_id.Name" :title="sponsor.Sponsor_id.Name" :width="sponsor.Sponsor_id.Logo.width"
28-
:height="sponsor.Sponsor_id.Logo.height">
29-
</template> -->
30-
31-
<template
32-
v-for="sponsor in allSponsors"
33-
:key="sponsor.Sponsor_id"
34-
>
35-
<div :class="sponsorClassList(sponsor)">
36-
<NuxtLink
37-
:to="`/meetup/${sponsor.Events_id}`"
38-
class="absolute inset-0"
39-
>
40-
<span class="sr-only">
41-
{{ sponsor.Sponsor_id.Name }}
42-
</span>
43-
</NuxtLink>
44-
<img
45-
class="w-full object-contain md:object-cover"
46-
:src="sponsorLogoUrl(sponsor)"
47-
:alt="sponsor.Sponsor_id.Name"
48-
:title="sponsor.Sponsor_id.Name"
49-
:width="sponsor.Sponsor_id.Logo.width"
50-
:height="sponsor.Sponsor_id.Logo.height"
51-
>
52-
53-
<!-- <div class="flex flex-col text-md font-bold gap-1 md:gap-4">
54-
<div v-for="sponsorType in sponsor.Sponsor_id?.Sponsor_type" :key="sponsorType"
55-
class="flex flex-col items-center bg-gray-200/10 border-gray-500/10 border-2 p-2 rounded-md">
56-
<p class="text-left md:uppercase font-semibold md:font-black opacity-70 cursor-help text-xs md:text-md"
57-
:title="`${sponsor.Sponsor_id.Name} sponsored the ${sponsorType} for this meetup`">
58-
{{ sponsorTypeMap[sponsorType] }}
59-
</p>
60-
</div>
61-
</div> -->
33+
<div>
34+
<div v-for="[year, meetups] in sortedMeetupsByYear" :key="year" class="mb-12">
35+
<h2 class="text-4xl font-bold text-verse-600 dark:text-verse-100 mb-6 border-b border-verse-200/10 pb-2">
36+
{{ year }}
37+
</h2>
38+
<div class="grid lg:grid-cols-4 md:grid-cols-2 grid-cols-1 gap-8">
39+
<div v-for="item in meetups" :key="`${item.meetup.id}-${item.sponsor.id}`" class="flex flex-col gap-4 bg-white/50 overflow-hidden dark:bg-verse-100/10 dark:backdrop-blur-sm p-4 shadow-lg sm:rounded-lg">
40+
<div class="flex flex-col items-center gap-2 flex-1 relative">
41+
<img
42+
:src="sponsorLogoUrl(item.sponsor)"
43+
:alt="item.sponsor.name"
44+
class="h-20 max-h-24 w-full object-contain mb-2 rounded-md p-2"
45+
:class="item.sponsor.darkbg ? 'dark:bg-verse-900 bg-gray-500' : 'bg-white'"
46+
>
47+
<div class="font-semibold text-lg text-center sr-only">
48+
{{ item.sponsor.name }}
49+
</div>
50+
<template v-if="item.sponsor.website && isRecentSponsorship([item.meetup])">
51+
<a :href="item.sponsor.website" target="_blank" rel="noopener" class="absolute top-0 left-0 w-full h-full text-blue-600 underline text-xs opacity-0">{{ item.sponsor.website }}</a>
52+
</template>
53+
</div>
54+
<div class="flex flex-col gap-2 mt-2">
55+
<div class="bg-verse-100 dark:bg-verse-800 rounded-md p-3 flex flex-col gap-1">
56+
<div class="text-sm font-semibold text-verse-700 dark:text-verse-200">
57+
<NuxtLink :to="`/meetup/${item.meetup.id}`" class="hover:underline">
58+
{{ item.meetup.title }}
59+
</NuxtLink>
60+
</div>
61+
<div class="text-xs text-gray-500 flex gap-2">
62+
<span>{{ item.meetup.date }}</span>
63+
</div>
64+
</div>
65+
</div>
66+
</div>
6267
</div>
63-
</template>
68+
</div>
6469
</div>
6570
</template>
6671

packages/frontendmu-nuxt/nuxt.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export default defineNuxtConfig({
2525
'shadcn-nuxt',
2626
'@nuxt/image',
2727
'@nuxt/content',
28+
'@pinia/nuxt',
2829
],
2930

3031
eslint: {

packages/frontendmu-nuxt/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@nuxt/image": "^1.7.0",
2121
"@nuxtjs/color-mode": "^3.4.2",
2222
"@nuxtjs/seo": "2.0.0-rc.16",
23+
"@pinia/nuxt": "^0.11.0",
2324
"@vueuse/core": "^10.11.0",
2425
"class-variance-authority": "^0.7.0",
2526
"clsx": "^2.1.1",

packages/frontendmu-nuxt/pages/sponsors.vue

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
2-
import sponsorTypes from "../../frontendmu-data/data/sponsors.js";
3-
import { vTransitionName } from "@/utils/helpers";
2+
import sponsorTypes from '../../frontendmu-data/data/sponsors.js'
3+
import { vTransitionName } from '@/utils/helpers'
44
5-
const title = "Our sponsors";
6-
const description = "";
5+
const title = 'Our sponsors'
6+
const description = ''
77
</script>
88

99
<template>
@@ -18,10 +18,12 @@ const description = "";
1818
class="underline hover:bg-verse-50 dark:bg-verse-950"
1919
title="Please reach out to us via email"
2020
>
21-
please reach out to the organizers here</a
22-
>.
21+
please reach out to the organizers here</a>.
2322
</p>
2423
</div>
24+
<div>
25+
<SiteMeetupSponsors />
26+
</div>
2527
<div class="grid gap-20 pt-12 md:grid-cols-2">
2628
<template v-for="sponsorType in sponsorTypes" :key="sponsorType.title">
2729
<div class="flex flex-col justify-between">
@@ -54,7 +56,7 @@ const description = "";
5456
class="w-48 h-52 object-contain"
5557
:src="`/img/sponsors/${sponsor.logo}`"
5658
:style="vTransitionName('sponsor-name', sponsor.name)"
57-
/>
59+
>
5860
<div v-else>
5961
<span class="text-2xl font-bold">{{ sponsor.name }}</span>
6062
</div>
@@ -71,21 +73,6 @@ const description = "";
7173
</div>
7274
</template>
7375
</div>
74-
<div>
75-
<div class="space-y-5 sm:mx-auto sm:space-y-2 py-4">
76-
<h3
77-
class="text-3xl font-bold tracking-tight text-center md:text-left sm:text-4xl sm:tracking-tight text-verse-500 dark:text-verse-200"
78-
>
79-
Past meetup sponsors
80-
</h3>
81-
<p class="max-w-2xl text-xl text-verse-600 dark:text-verse-200">
82-
These wonderful companies have sponsored our meetups in the past.
83-
We're grateful for their support.
84-
</p>
85-
</div>
86-
87-
<SiteMeetupSponsors />
88-
</div>
8976
</div>
9077
</ContentBlock>
9178
</template>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createPinia } from 'pinia'
2+
import { defineNuxtPlugin } from '#app'
3+
4+
export default defineNuxtPlugin((nuxtApp) => {
5+
const pinia = createPinia()
6+
nuxtApp.vueApp.use(pinia)
7+
})

packages/frontendmu-nuxt/store/sponsorStore.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,37 @@ export const useSponsorStore = defineStore('sponsor', {
6969
sponsorYear.meetups.push(meetup)
7070
}
7171
}
72+
// After grouping, sort meetups descending by date for each sponsor/year
73+
Object.values(grouped).forEach((entries) => {
74+
entries.forEach((entry) => {
75+
entry.meetups.sort((a, b) => b.date.localeCompare(a.date))
76+
})
77+
})
7278
return grouped
7379
},
80+
81+
// 4c. Group all meetups by year, globally sorted by date descending (not grouped by sponsor)
82+
getMeetupsGroupedByYearSorted(): [string, Array<{ sponsor: Sponsor, meetup: SponsorMeetup }>] [] {
83+
const grouped: Record<string, Array<{ sponsor: Sponsor, meetup: SponsorMeetup }>> = {}
84+
for (const sponsor of this.sponsors) {
85+
for (const meetup of sponsor.meetups) {
86+
const year = getYear(meetup.date)
87+
if (!year) continue
88+
if (!grouped[year]) grouped[year] = []
89+
grouped[year].push({ sponsor, meetup })
90+
}
91+
}
92+
// Sort meetups by date descending for each year
93+
Object.values(grouped).forEach(arr => arr.sort((a, b) => b.meetup.date.localeCompare(a.meetup.date)))
94+
// Return as a sorted array of [year, meetups[]]
95+
return Object.entries(grouped).sort((a, b) => b[0].localeCompare(a[0]))
96+
},
97+
98+
// 4b. Same as above, but returns a sorted array of [year, entries] pairs, descending by year
99+
getSponsorsEventsGroupedByYearSorted(): [string, { sponsor: Sponsor, meetups: SponsorMeetup[] }[]][] {
100+
const grouped = this.getSponsorsEventsGroupedByYear as Record<string, { sponsor: Sponsor, meetups: SponsorMeetup[] }[]>
101+
return Object.entries(grouped).sort((a, b) => b[0].localeCompare(a[0]))
102+
},
74103
// 5. Get sponsors for a specific year
75104
getSponsorsForYear: state => (year: string) => {
76105
return state.sponsors.filter(sponsor =>

pnpm-lock.yaml

Lines changed: 21 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)