Initial commit: ANOUMA website with Payload CMS, WebRTC meetings, and booking system
- Next.js 16 App Router site with the ANOUMA design system - Payload CMS (PostgreSQL) for offers, events, posts and page content - WebRTC video-call system with custom signaling server - SMTP email reminders and booking-request notifications - Customer accounts, calendar-based availability, and booking workflow
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { OFFER_CATEGORIES } from "@/collections/Offers";
|
||||
import type { Offer } from "@/payload-types";
|
||||
|
||||
export type ImageMood =
|
||||
| "plum"
|
||||
| "dustyrose"
|
||||
| "moss"
|
||||
| "caramel"
|
||||
| "mauve"
|
||||
| "sand"
|
||||
| "rose"
|
||||
| "peach";
|
||||
|
||||
// Purely a presentation fallback for offers/events without an uploaded photo
|
||||
// yet — content itself always comes from the CMS.
|
||||
const moodBySlug: Record<string, ImageMood> = {
|
||||
prozessbegleitung: "plum",
|
||||
"doula-begleitung": "dustyrose",
|
||||
erdenkinder: "moss",
|
||||
maedchenkreis: "caramel",
|
||||
"singen-im-kreis": "sand",
|
||||
"singen-fuer-schwangere": "peach",
|
||||
"mama-baby-singkreis": "rose",
|
||||
};
|
||||
|
||||
const moodByCategory: Record<string, ImageMood> = {
|
||||
prozessbegleitung: "plum",
|
||||
"doula-begleitung": "dustyrose",
|
||||
kindergruppen: "moss",
|
||||
singkreise: "rose",
|
||||
};
|
||||
|
||||
export function moodForOffer(offer: Pick<Offer, "slug" | "category">): ImageMood {
|
||||
return (offer.slug ? moodBySlug[offer.slug] : undefined) ?? moodByCategory[offer.category] ?? "mauve";
|
||||
}
|
||||
|
||||
export type OfferCategoryGroup = {
|
||||
category: (typeof OFFER_CATEGORIES)[number]["value"];
|
||||
label: string;
|
||||
href: string;
|
||||
offers: Offer[];
|
||||
};
|
||||
|
||||
const categoryHref: Record<string, string> = {
|
||||
prozessbegleitung: "/angebote/prozessbegleitung",
|
||||
"doula-begleitung": "/angebote/doula-begleitung",
|
||||
kindergruppen: "/angebote#kindergruppen",
|
||||
singkreise: "/angebote/singkreise",
|
||||
};
|
||||
|
||||
/**
|
||||
* Groups the flat `offers` collection into the four nav/overview sections.
|
||||
* Private offers (e.g. "Einzelbegleitung") are deliberately excluded — they
|
||||
* stay reachable only via their own direct booking link.
|
||||
*/
|
||||
export function groupOffersByCategory(offers: Offer[]): OfferCategoryGroup[] {
|
||||
const publicOffers = offers.filter((offer) => offer.visibility !== "private");
|
||||
return OFFER_CATEGORIES.map(({ value, label }) => ({
|
||||
category: value,
|
||||
label,
|
||||
href: categoryHref[value] ?? "/angebote",
|
||||
offers: publicOffers
|
||||
.filter((offer) => offer.category === value)
|
||||
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)),
|
||||
})).filter((group) => group.offers.length > 0);
|
||||
}
|
||||
Reference in New Issue
Block a user