diff --git a/prisma/migrations/20250128101452_cascading_news_event_deletions/migration.sql b/prisma/migrations/20250128101452_cascading_news_event_deletions/migration.sql new file mode 100644 index 0000000..99f7c02 --- /dev/null +++ b/prisma/migrations/20250128101452_cascading_news_event_deletions/migration.sql @@ -0,0 +1,5 @@ +-- DropForeignKey +ALTER TABLE "Event" DROP CONSTRAINT "Event_newsPostId_fkey"; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_newsPostId_fkey" FOREIGN KEY ("newsPostId") REFERENCES "NewsPost"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c644704..a16dbe5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -79,7 +79,7 @@ model Event { location String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - NewsPost NewsPost? @relation(fields: [newsPostId], references: [id]) + NewsPost NewsPost? @relation(fields: [newsPostId], references: [id], onDelete: Cascade) newsPostId Int? } diff --git a/src/components/Calendar/Calendar.module.scss b/src/components/Calendar/Calendar.module.scss new file mode 100644 index 0000000..b39c458 --- /dev/null +++ b/src/components/Calendar/Calendar.module.scss @@ -0,0 +1,33 @@ +.eventsList { + list-style-type: none; +} + +.centered { + display: flex; + flex-direction: column; +} + +.upcomingEventsTitle { + margin-top: 0.4rem; + margin-bottom: 0; + font-size: 1.5rem; +} + +.ongoingText, +.ongoingBullet { + font-size: var(--text-small); + font-weight: normal; +} + +.ongoingText { + color: var(--link-color); +} + +.upcomingEventTitle { + margin-top: 0.3rem; + font-size: var(--text-normal); +} + +.upcomingEventDetails { + font-size: var(--text-small); +} diff --git a/src/components/Calendar/Calendar.scss b/src/components/Calendar/Calendar.scss index a7b787c..f219573 100644 --- a/src/components/Calendar/Calendar.scss +++ b/src/components/Calendar/Calendar.scss @@ -55,8 +55,3 @@ } padding-bottom: 0.5rem; } - -.centered { - display: flex; - flex-direction: column; -} diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 36d25b3..180a5d8 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -4,13 +4,16 @@ import ActionLink from '../ActionButton/ActionLink'; import CalendarClient from './CalendarClient'; import i18nService from '@/services/i18nService'; import { getAllEvents } from '@/actions/events'; +import styles from './Calendar.module.scss'; +import EventService from '@/services/eventService'; const Calendar = async ({ locale }: { locale: string }) => { const l = i18nService.getLocale(locale); const events = await getAllEvents(); + const nextEvents = await EventService.getUpcoming(3); return ( - +

{l.events.events}

@@ -20,6 +23,33 @@ const Calendar = async ({ locale }: { locale: string }) => { > {l.events.subscribe} +

{l.events.comingEvents}

+
    + {nextEvents.map((event) => { + const ongoing = event.startTime < new Date(); + return ( +
  • +

    + {l.en ? event.titleEn : event.titleSv} + {ongoing && ( + <> + + + {l.events.ongoing} + + + )} +

    +

    + {i18nService.formatDate(event.startTime, true)} -{' '} + {i18nService.formatTime(event.endTime)} + {event.location && ' • ' + event.location} +

    +
  • + ); + })} + {nextEvents.length === 0 &&

    {l.events.noEvents}

    } +
); }; diff --git a/src/dictionaries/en.json b/src/dictionaries/en.json index 16b359b..82b6e90 100644 --- a/src/dictionaries/en.json +++ b/src/dictionaries/en.json @@ -99,6 +99,7 @@ }, "events": { "events": "Events", + "noEvents": "No events to show", "start": "Start", "end": "End", "fullDay": "Full day", @@ -106,7 +107,9 @@ "add": "Add event", "remove": "Remove event", "empty": "No events connected", - "subscribe": "Subscribe" + "subscribe": "Subscribe", + "comingEvents": "Coming Events", + "ongoing": "Ongoing" }, "groups": { "members": "Current members", diff --git a/src/dictionaries/sv.json b/src/dictionaries/sv.json index 55ef799..e56d8ac 100644 --- a/src/dictionaries/sv.json +++ b/src/dictionaries/sv.json @@ -99,6 +99,7 @@ }, "events": { "events": "Evenemang", + "noEvents": "Inga evenemang att visa", "start": "Start", "end": "Slut", "fullDay": "Heldag", @@ -106,7 +107,9 @@ "add": "Lägg till evenemang", "remove": "Ta bort evenemang", "empty": "Inga evenemang kopplade", - "subscribe": "Prenumerera" + "subscribe": "Prenumerera", + "comingEvents": "Kommande evenemang", + "ongoing": "Pågående" }, "groups": { "members": "Nuvarande medlemmar", diff --git a/src/services/eventService.ts b/src/services/eventService.ts index bbf8b6b..dc056e5 100644 --- a/src/services/eventService.ts +++ b/src/services/eventService.ts @@ -5,6 +5,21 @@ export default class EventService { return new Date(d).setHours(0, 0, 0, 0) - d.getTimezoneOffset() * 60 * 1000; } + static async getUpcoming(max: number = 3) { + const now = new Date(); + return await prisma.event.findMany({ + where: { + endTime: { + gt: now + } + }, + orderBy: { + startTime: 'asc' + }, + take: max + }); + } + static async getAll() { return await prisma.event.findMany(); }