Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions app/[locale]/events/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ArrowLeft, Calendar, Clock, ExternalLink, MapPin } from "lucide-react";
import type { Metadata } from "next";
import Image from "next/image";
import { notFound } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { getTranslations, setRequestLocale } from "next-intl/server";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

Expand Down Expand Up @@ -105,7 +105,9 @@ export default async function EventPage({
}: {
params: Promise<{ slug: string; locale: string }>;
}) {
const { slug } = await params;
const { slug, locale } = await params;
setRequestLocale(locale);

const t = await getTranslations("eventDetail");
const event = getEventBySlug(slug);

Expand All @@ -123,16 +125,29 @@ export default async function EventPage({
<section className="relative h-[60vh] max-h-[600px] min-h-[420px] w-full overflow-hidden">
{event.imageUrl ? (
<>
<Image src={event.imageUrl} alt="" fill className="object-cover" priority />
<Image
src={event.imageUrl}
alt=""
fill
priority
fetchPriority="high"
sizes="100vw"
className="object-cover"
/>
<div
className={`absolute inset-0 ${isEventPast ? "bg-gray-900/30" : "bg-purple-950/20"}`}
/>
</>
) : (
<>
<div
className="absolute inset-0 bg-cover bg-center opacity-20"
style={{ backgroundImage: "url('/images/wallpaper.png')" }}
<Image
src="/images/wallpaper.png"
alt=""
fill
priority
fetchPriority="high"
sizes="100vw"
className="object-cover object-center opacity-20"
/>
<div className="pointer-events-none absolute inset-0 flex select-none items-center justify-center overflow-hidden">
<span className="whitespace-nowrap text-[12rem] font-bold leading-none text-white/[0.04] md:text-[16rem]">
Expand Down
18 changes: 13 additions & 5 deletions app/[locale]/events/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArrowLeft } from "lucide-react";
import type { Metadata } from "next";
import Image from "next/image";
import { getTranslations } from "next-intl/server";
import { getTranslations, setRequestLocale } from "next-intl/server";

import { EventCard } from "@/components/event-card";
import { ICalFeedButton } from "@/components/ical-feed-button";
Expand Down Expand Up @@ -34,7 +34,10 @@ export async function generateMetadata({
};
}

export default async function EventsPage() {
export default async function EventsPage({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
setRequestLocale(locale);

const t = await getTranslations("eventsPage");
const { upcomingEvents, pastEvents } = getEventsByDate();

Expand All @@ -44,9 +47,14 @@ export default async function EventsPage() {

{/* Header */}
<section className="section-spacing relative w-full overflow-hidden sm:px-6 lg:px-8">
<div
className="absolute inset-0 z-0 bg-cover bg-center opacity-20"
style={{ backgroundImage: "url('/images/wallpaper.png')" }}
<Image
src="/images/wallpaper.png"
alt=""
fill
priority
fetchPriority="high"
sizes="100vw"
className="z-0 object-cover object-center opacity-20"
/>
<div className="relative z-10 mx-auto max-w-5xl">
<Link href="/" className="text-gray-hover mb-6 inline-flex items-center">
Expand Down
12 changes: 11 additions & 1 deletion app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Metadata } from "next";
import { JetBrains_Mono, Rubik } from "next/font/google";
import { notFound } from "next/navigation";
import { NextIntlClientProvider } from "next-intl";
import { getMessages, getTranslations } from "next-intl/server";
import { getMessages, getTranslations, setRequestLocale } from "next-intl/server";
import type React from "react";

import Footer from "@/components/footer";
Expand Down Expand Up @@ -117,6 +117,12 @@ export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}

// The static pages under this tree split events into upcoming/past with today's
// date, so without revalidation that split freezes at build time — and deploys only
// happen on merges, which can be weeks apart. Hourly ISR lets an event flip to past
// (and its JSON-LD offer expire, see buildOffers) without waiting for the next deploy.
export const revalidate = 3600;

export default async function LocaleLayout({
children,
params,
Expand All @@ -130,6 +136,10 @@ export default async function LocaleLayout({
notFound();
}

// Opts this route tree into static rendering; without it next-intl renders
// every locale route dynamically.
setRequestLocale(locale);

const messages = await getMessages();

return (
Expand Down
38 changes: 25 additions & 13 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArrowRight, Calendar } from "lucide-react";
import type { Metadata } from "next";
import Image from "next/image";
import { getTranslations } from "next-intl/server";
import { getTranslations, setRequestLocale } from "next-intl/server";

import FeaturedEvents from "@/components/featured-events";
import { ICalFeedButton } from "@/components/ical-feed-button";
Expand Down Expand Up @@ -32,7 +32,10 @@ export async function generateMetadata({
};
}

export default async function Home() {
export default async function Home({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
setRequestLocale(locale);

const t = await getTranslations();

return (
Expand All @@ -41,9 +44,14 @@ export default async function Home() {

{/* Hero Section */}
<section className="relative flex min-h-[80vh] w-full flex-col items-center justify-center overflow-hidden px-4 py-20">
<div
className="absolute inset-0 z-0 bg-cover bg-center opacity-40"
style={{ backgroundImage: "url('/images/wallpaper.png')" }}
<Image
src="/images/wallpaper.png"
alt=""
fill
priority
fetchPriority="high"
sizes="100vw"
className="z-0 object-cover object-center opacity-40"
/>
<div className="relative z-10 mx-auto max-w-5xl text-center">
<ScrollLogo src="/images/logo.png" alt="C++ Serbia Logo" width={162} height={180} />
Expand All @@ -54,17 +62,18 @@ export default async function Home() {
{t("hero.subtitle")}
</p>
<div className="relative z-10 flex flex-wrap justify-center gap-4">
<Button size="lg" className="gradient-brand-button text-white">
<Link href="/events" className="flex-start gap-2">
<Button size="lg" className="gradient-brand-button text-white" asChild>
<Link href="/events">
{t("hero.upcomingEvents")} <Calendar className="h-5 w-5" />
</Link>
</Button>
<Button
variant="outline"
size="lg"
className="border-purple-500 text-purple-400 hover:bg-purple-950 hover:text-purple-300"
asChild
>
<Link href="#join" className="flex-start gap-2">
<Link href="#join">
{t("hero.joinCommunity")} <ArrowRight className="h-5 w-5" />
</Link>
</Button>
Expand Down Expand Up @@ -111,8 +120,8 @@ export default async function Home() {
<FeaturedEvents limit={3} />

<div className="mt-12 flex flex-col items-center gap-6">
<Button size="lg" className="gradient-brand-button text-white">
<Link href="/events" className="flex items-center gap-2">
<Button size="lg" className="gradient-brand-button text-white" asChild>
<Link href="/events">
{t("featuredEvents.viewAll")} <Calendar className="h-5 w-5" />
</Link>
</Button>
Expand All @@ -127,9 +136,12 @@ export default async function Home() {

{/* Join Community Section */}
<section id="join" className="section-spacing relative">
<div
className="absolute inset-0 z-0 bg-cover bg-center opacity-10"
style={{ backgroundImage: "url('/images/wallpaper.png')" }}
<Image
src="/images/wallpaper.png"
alt=""
fill
sizes="100vw"
className="z-0 object-cover object-center opacity-10"
/>
<div className="relative z-10 mx-auto max-w-5xl">
<h2 className="mb-2 text-center text-3xl font-bold text-purple-300 md:text-4xl">
Expand Down
2 changes: 1 addition & 1 deletion components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default async function Footer() {
</div>
</div>

<div className="mt-12 border-t border-purple-900/40 pt-6 text-center text-sm text-gray-500">
<div className="mt-12 border-t border-purple-900/40 pt-6 text-center text-sm text-gray-400">
<p>{t("copyright", { year: getCurrentYear() })}</p>
</div>
</div>
Expand Down
26 changes: 18 additions & 8 deletions components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,21 @@ export default function Navbar() {
<LanguageSwitcher />
<ScriptToggle />
</div>
<Button size="sm" className="gradient-brand-button ml-2 text-white">
<Button size="sm" className="gradient-brand-button ml-2 text-white" asChild>
<Link href="/events" className="nav-link">
<Calendar className="h-4 w-4" /> {t("upcomingEvents")}
</Link>
</Button>
</nav>

{/* Mobile Menu Button */}
<button className="p-2 text-white md:hidden" onClick={() => setIsMenuOpen(!isMenuOpen)}>
<button
className="p-2 text-white md:hidden"
onClick={() => setIsMenuOpen(!isMenuOpen)}
aria-label={isMenuOpen ? t("closeMenu") : t("openMenu")}
aria-expanded={isMenuOpen}
aria-controls="mobile-nav"
>
{isMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
Expand All @@ -63,7 +69,10 @@ export default function Navbar() {
{isMenuOpen && (
<div className="fixed inset-0 top-16 z-40 md:hidden">
<div className="absolute inset-0 bg-[#0c0c1d]/95 backdrop-blur-lg backdrop-saturate-150" />
<nav className="relative z-10 flex flex-col items-center gap-6 bg-[#0c0c1d]/90 p-8 text-white backdrop-blur-lg backdrop-saturate-150">
<nav
id="mobile-nav"
className="relative z-10 flex flex-col items-center gap-6 bg-[#0c0c1d]/90 p-8 text-white backdrop-blur-lg backdrop-saturate-150"
>
<Link
href="/"
className="text-lg font-medium text-white transition-colors hover:text-purple-300"
Expand All @@ -89,11 +98,12 @@ export default function Navbar() {
<LanguageSwitcher />
<ScriptToggle />
</div>
<Button
className="gradient-brand-button mt-4 w-full text-white"
onClick={() => setIsMenuOpen(false)}
>
<Link href="/events" className="flex-center w-full gap-2">
<Button className="gradient-brand-button mt-4 w-full text-white" asChild>
<Link
href="/events"
className="flex-center w-full gap-2"
onClick={() => setIsMenuOpen(false)}
>
<Calendar className="h-5 w-5" /> {t("upcomingEvents")}
</Link>
</Button>
Expand Down
54 changes: 0 additions & 54 deletions components/ui/accordion.tsx

This file was deleted.

Loading
Loading