Docker-Images bauen und veroeffentlichen / build-and-push (push) Failing after 1m32s
36 lines
1.7 KiB
TypeScript
36 lines
1.7 KiB
TypeScript
import type { PublicCampFacts } from "@/lib/camp";
|
|
import { appUrl } from "@/lib/env";
|
|
import type { PublicPricing } from "@/lib/public-page";
|
|
|
|
/**
|
|
* Strukturierte Veranstaltungsdaten (schema.org/Event) — nur, wenn Termin,
|
|
* Ort und Veranstalter bestaetigt sind und der Live-Verkauf laeuft.
|
|
* Unbestaetigte Angaben erscheinen nie in Suchmaschinen.
|
|
*/
|
|
export function EventJsonLd({ facts, pricing }: { facts: PublicCampFacts; pricing: PublicPricing }) {
|
|
if (!facts.startDate || !facts.location || !facts.organizer || pricing.mode !== "live" || !pricing.checkoutOpen || pricing.currentCents === null) {
|
|
return null;
|
|
}
|
|
const data = {
|
|
"@context": "https://schema.org",
|
|
"@type": "Event",
|
|
name: "ARTISTA MODELCAMP 2027",
|
|
startDate: facts.startDate,
|
|
...(facts.endDate ? { endDate: facts.endDate } : {}),
|
|
eventAttendanceMode: "https://schema.org/OfflineEventAttendanceMode",
|
|
eventStatus: "https://schema.org/EventScheduled",
|
|
location: { "@type": "Place", name: facts.location, address: { "@type": "PostalAddress", addressCountry: "IT", ...(facts.region ? { addressRegion: facts.region } : {}) } },
|
|
organizer: { "@type": "Organization", name: facts.organizer.name, email: facts.organizer.email },
|
|
offers: {
|
|
"@type": "Offer",
|
|
price: (pricing.currentCents / 100).toFixed(2),
|
|
priceCurrency: "EUR",
|
|
availability: "https://schema.org/InStock",
|
|
url: appUrl("/#preis"),
|
|
},
|
|
};
|
|
// JSON.stringify + Ersetzen von "<" verhindert, dass Inhalte das
|
|
// Script-Element vorzeitig schliessen.
|
|
return <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data).replace(/</g, "\\u003c") }} />;
|
|
}
|