web: add api route for compact event listing for app

This commit is contained in:
2024-11-21 22:04:20 +01:00
parent fd88683ee6
commit ff0f3846e9
2 changed files with 94 additions and 0 deletions

View File

@ -1 +1,2 @@
GRAPHQL_ENDPOINT=https://cms.neuf.no/api/graphql/
URL=http://localhost:3000

View File

@ -0,0 +1,93 @@
import { NextRequest, NextResponse } from "next/server";
import { getClient } from "@/app/client";
import {
eventsOverviewQuery,
getSingularEvents,
getFutureOccurrences,
EventFragment,
EventCategory,
EventOrganizer,
} from "@/lib/event";
import { VenueFragment } from "@/gql/graphql";
type CompactEvent = {
id: string;
slug: string;
title: string;
subtitle: string;
nextOccurrence: {
id: string;
start: string;
end?: string;
venue: {
id: string;
slug: string;
title: string;
preposition: string;
url: string;
};
};
};
type ResponseData = {
events: CompactEvent[];
total: number;
};
const whitelistFilter = (obj: Record<string, any>, whitelist: string[]) =>
Object.entries(obj)
.filter(([key, value]) => whitelist.includes(key))
.reduce(
(obj: Record<string, any>, [key, value]) => ((obj[key] = value), obj),
{}
);
export async function GET(req: NextRequest, res: NextResponse<ResponseData>) {
const searchParams = req.nextUrl.searchParams;
const view = searchParams.get("view");
if (view !== "compact-app") {
return NextResponse.json(
{ error: "must provide valid view parameter" },
{ status: 400 }
);
}
const { data, error } = await getClient().query(eventsOverviewQuery, {});
if (error) {
throw new Error(error.message);
}
if (
!data?.index ||
!data?.events?.futureEvents ||
!data?.eventCategories ||
!data?.eventOrganizers ||
!data?.venues
) {
throw new Error("Failed to fetch events");
}
const futureEvents = (data?.events?.futureEvents ?? []) as EventFragment[];
const eventCategories = (data?.eventCategories ?? []) as EventCategory[];
const eventOrganizers = (data?.eventOrganizers ?? []) as EventOrganizer[];
const venues = (data?.venues ?? []) as VenueFragment[];
const keepKeys = ["id", "slug", "title", "subtitle", "occurrence"];
const compactEvents = futureEvents.map((event) => {
const futureOccurrences = getFutureOccurrences(event);
const nextOccurrence = futureOccurrences.length
? futureOccurrences[0]
: null;
return {
url: `${process.env.URL}/arrangementer/${event.slug}`,
nextOccurrence: nextOccurrence,
...whitelistFilter(event, keepKeys),
};
});
return NextResponse.json(
{ events: compactEvents, total: compactEvents.length },
{ status: 200 }
);
}