Skip to content
Open
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
144 changes: 27 additions & 117 deletions src/app/[locale]/agenda/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type Locale } from "~/i18n/routing";
import { getTranslations } from "next-intl/server";
import { AgendaSection } from "~/components/AgendaSection";

type Props = {
params: Promise<{ locale: Locale }>;
Expand All @@ -9,128 +10,37 @@ type Props = {
export default async function AgendaPage({ params }: Props) {
const { locale } = await params;
const t = await getTranslations("Agenda");

const agendaItems = [
{ id: 1, type: "registration", duration: "1h 30m" },
{ id: 2, type: "exhibition", duration: "30m" },
{ id: 3, type: "ceremony", duration: "50m" },
{ id: 4, type: "session", duration: "1h" },
{ id: 5, type: "break", duration: "30m" },
{ id: 6, type: "session", duration: "1h 25m" },
{ id: 7, type: "break", duration: "15m" },
{ id: 8, type: "session", duration: "1h" },
{ id: 9, type: "closing", duration: "15m" }
];

const getItemTitle = (item: typeof agendaItems[0]): string => {
if (item.type === 'ceremony') return t("agendaItems.opening");
if (item.type === 'session') {
if (item.id === 4) return t("agendaItems.session1");
if (item.id === 6) return t("agendaItems.session2");
return t("agendaItems.session3");
}
if (item.type === 'break') {
if (item.id === 5) return t("agendaItems.break1");
return t("agendaItems.break2");
}
return t(`agendaItems.${item.type}` as "agendaItems.registration" | "agendaItems.exhibition" | "agendaItems.closing");
};

return (
<main
className="relative min-h-screen bg-gradient-to-b from-background via-background/95 to-background overflow-hidden"
style={{
backgroundImage: "url('/pattern1.svg')",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat"
}}
>
{/* Dark overlay for text readability */}
<div className="absolute inset-0 bg-background/60 z-0"></div>

{/* Main content container */}
<div className="relative z-10 container mx-auto px-4 py-8">
<div className="flex flex-col items-center justify-center min-h-screen py-16 px-4">
{/* Hero section with the main title */}
<div className="text-center mb-16 w-full">
<h1 className="text-5xl md:text-7xl font-bold mb-4">
{locale === 'ar' ? (
<>
<span className="text-white font-bold">ما بعد </span>
<span className="text-primary font-bold">اللحظة</span>
</>
) : (
<>
<span className="text-white font-bold">Beyond The </span>
<span className="text-primary font-bold">Moment</span>
</>
)}
</h1>
<h2 className="text-3xl md:text-4xl font-light text-muted-foreground mb-6">
{t("heroSubtitle")}
</h2>
</div>

{/* Main agenda timeline section */}
<div className="w-full max-w-4xl">
<div className="bg-card/40 backdrop-blur-sm rounded-2xl p-6 md:p-8 border border-border shadow-2xl">
{/* Agenda header with title and TEDx logo */}
<div className="flex items-center justify-between mb-8">
<h3 className="text-2xl md:text-3xl font-bold text-foreground">
{t("title")}
</h3>
<div className="text-primary font-bold text-lg md:text-xl hover:scale-110 transition-transform duration-300 cursor-pointer">
TEDx
</div>
</div>
return (
<main className="tedx-animated-bg relative flex min-h-screen flex-col items-center justify-center overflow-hidden text-gray-900 dark:text-white">
{/* Overlay for text readability */}
<div className="absolute inset-0 z-0 bg-white/20 dark:bg-black/40"></div>

{/* Timeline with agenda items */}
<div className="relative">
{/* Vertical timeline line with gradient */}
<div className="absolute left-6 md:left-8 top-0 bottom-0 w-0.5 bg-gradient-to-b from-primary via-primary/80 to-primary/60"></div>

{/* List of agenda items */}
<div className="space-y-4 md:space-y-6">
{agendaItems.map((item) => (
<div
key={item.id}
className="group relative transition-all duration-300 hover:scale-102"
>
{/* Individual agenda item */}
<div className="flex items-start relative">
{/* Red X symbol marker if we can get the x symbol from them it will be better */}
<div className="flex-shrink-0 mr-4 md:mr-6 z-10 relative group-hover:scale-110 transition-all duration-300">
<span className="text-primary text-2xl md:text-3xl font-bold">×</span>
</div>

{/* Content area for the agenda item */}
<div className="flex-1 group-hover:bg-white/5 p-3 md:p-4 rounded-lg transition-all duration-300">
{/* Item title with hover effect to lock nice */}
<h4 className="text-base md:text-lg font-medium text-white dark:text-white text-gray-900 mb-2 group-hover:text-red-300 dark:group-hover:text-red-300 group-hover:text-primary transition-colors duration-300">
{getItemTitle(item)}
</h4>

{/* Item metadata (duration and time slot) */}
<div className="flex items-center space-x-3 md:space-x-4 text-xs text-gray-400 dark:text-gray-400">
{/* Duration badge */}
<span className="bg-red-500/20 dark:bg-red-500/20 bg-red-100 dark:bg-red-500/20 text-red-700 dark:text-red-300 px-2 py-1 rounded-full">
{item.duration}
</span>
{/* Time slot badge */}
<span className="bg-white/10 dark:bg-white/10 bg-gray-100 dark:bg-white/10 text-gray-700 dark:text-white px-2 py-1 rounded-full">
{t(`timeSlots.slot${item.id}` as "timeSlots.slot1" | "timeSlots.slot2" | "timeSlots.slot3" | "timeSlots.slot4" | "timeSlots.slot5" | "timeSlots.slot6" | "timeSlots.slot7" | "timeSlots.slot8" | "timeSlots.slot9")}
</span>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
<div className="relative z-10 container flex flex-col items-center justify-center px-4 py-16">
{/* Hero section with the main title */}
<div className="text-center space-y-6 min-h-[40vh] flex flex-col justify-center items-center">
<h1 className="text-5xl md:text-7xl font-bold mb-4">
{locale === 'ar' ? (
<>
<span className="text-gray-900 dark:text-white font-bold">ما بعد </span>
<span className="text-primary font-bold">اللحظة</span>
</>
) : (
<>
<span className="text-gray-900 dark:text-white font-bold">Beyond The </span>
<span className="text-primary font-bold">Moment</span>
</>
)}
</h1>
<h2 className="mb-6 text-3xl font-light text-gray-600 dark:text-gray-300">
{t("heroSubtitle")}
</h2>
</div>

{/* Agenda Section */}
<AgendaSection />
</div>
</main>
);
Expand Down
82 changes: 82 additions & 0 deletions src/components/AgendaSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"use client";

import { useTranslations, useLocale } from "next-intl";

export function AgendaSection() {
const t = useTranslations("Agenda");
const locale = useLocale();

const agendaItems = [
{ id: 1, type: "registration", duration: "1h 30m" },
{ id: 2, type: "exhibition", duration: "30m" },
{ id: 3, type: "opening", duration: "50m" },
{ id: 4, type: "session1", duration: "1h" },
{ id: 5, type: "break1", duration: "30m" },
{ id: 6, type: "session2", duration: "1h 25m" },
{ id: 7, type: "break2", duration: "15m" },
{ id: 8, type: "session3", duration: "1h" },
{ id: 9, type: "closing", duration: "15m" }
];

return (
<div className="w-full max-w-6xl">
<div className="bg-gray-100/80 dark:bg-white/10 rounded-3xl p-8 md:p-12 border border-gray-200 dark:border-white/20 shadow-2xl backdrop-blur-sm">
{/* Header */}
<div className="text-center mb-12">
<h3 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">
{t("title")}
</h3>
<p className="text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">
{locale === 'ar'
? 'اكتشف جدولنا المنسق بعناية من المحاضرات الملهمة وورش العمل التفاعلية'
: 'Discover our carefully curated schedule of inspiring talks and interactive workshops'
}
</p>
</div>

{/* Agenda Grid */}
<div className={`grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 md:gap-8 ${locale === 'ar' ? 'rtl' : 'ltr'}`}>
{agendaItems.map((item, index) => (
<div
key={item.id}
className={`flex flex-col gap-4 rounded-xl bg-gray-100/80 dark:bg-white/10 p-6 hover:bg-gray-200/80 dark:hover:bg-white/20 transition-colors border border-gray-200 dark:border-white/20 h-full ${locale === 'ar' ? 'text-right' : 'text-left'}`}
style={{
order: locale === 'ar' ?
(Math.floor(index / 3) * 3) + (2 - (index % 3)) :
index
}}
>
Comment on lines +38 to +48

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

RTL ordering breaks on 1–2 column breakpoints

The manual order calculation assumes 3 columns and will scramble card order on base (1-col) and sm (2-col) grids. Prefer letting the browser handle direction by setting dir, and drop custom ordering.

- <div className={`grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 md:gap-8 ${locale === 'ar' ? 'rtl' : 'ltr'}`}>
+ <div
+   className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 md:gap-8"
+   dir={locale === 'ar' ? 'rtl' : 'ltr'}
+ >
@@
-  style={{
-    order: locale === 'ar' ? 
-      (Math.floor(index / 3) * 3) + (2 - (index % 3)) : 
-      index
-  }}
+  /* no manual order; rely on dir */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className={`grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 md:gap-8 ${locale === 'ar' ? 'rtl' : 'ltr'}`}>
{agendaItems.map((item, index) => (
<div
key={item.id}
className={`flex flex-col gap-4 rounded-xl bg-gray-100/80 dark:bg-white/10 p-6 hover:bg-gray-200/80 dark:hover:bg-white/20 transition-colors border border-gray-200 dark:border-white/20 h-full ${locale === 'ar' ? 'text-right' : 'text-left'}`}
style={{
order: locale === 'ar' ?
(Math.floor(index / 3) * 3) + (2 - (index % 3)) :
index
}}
>
<div
className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 md:gap-8"
dir={locale === 'ar' ? 'rtl' : 'ltr'}
>
{agendaItems.map((item, index) => (
<div
key={item.id}
className={`flex flex-col gap-4 rounded-xl bg-gray-100/80 dark:bg-white/10 p-6 hover:bg-gray-200/80 dark:hover:bg-white/20 transition-colors border border-gray-200 dark:border-white/20 h-full ${locale === 'ar' ? 'text-right' : 'text-left'}`}
>
{/* …card content… */}
</div>
))}
</div>
🤖 Prompt for AI Agents
In src/components/AgendaSection.tsx around lines 38 to 48, the inline style that
computes a manual order assumes 3 columns and breaks layout at 1- and 2-column
breakpoints; remove the style prop that sets order and instead set the
container's direction via a dir attribute (dir={locale === 'ar' ? 'rtl' :
'ltr'}) so the browser handles item ordering natively; keep or adjust the
existing conditional text alignment classes but drop any custom ordering logic
so grid flow remains correct across responsive breakpoints.

{/* Item Title */}
<h4 className={`text-2xl font-bold text-gray-900 dark:text-white flex-1 ${locale === 'ar' ? 'text-right' : 'text-left'}`}>
{t(`agendaItems.${item.type}` as "agendaItems.registration" | "agendaItems.exhibition" | "agendaItems.opening" | "agendaItems.session1" | "agendaItems.break1" | "agendaItems.session2" | "agendaItems.break2" | "agendaItems.session3" | "agendaItems.closing")}
</h4>

{/* Time and Duration */}
<div className={`space-y-3 pt-2 mt-auto ${locale === 'ar' ? 'text-right' : 'text-left'}`}>
{/* Time */}
<div className={`flex items-center justify-between ${locale === 'ar' ? 'flex-row-reverse' : 'flex-row'}`}>
<span className="text-base font-bold text-gray-800 dark:text-gray-200">
{locale === 'ar' ? 'الوقت' : 'Time'}
</span>
<span className={`text-sm font-semibold text-gray-900 dark:text-white bg-gray-200 dark:bg-white/20 px-3 py-1 rounded-lg ${locale === 'ar' ? 'text-right' : 'text-left'}`} dir={locale === 'ar' ? 'rtl' : 'ltr'}>
{t(`timeSlots.slot${item.id}` as "timeSlots.slot1" | "timeSlots.slot2" | "timeSlots.slot3" | "timeSlots.slot4" | "timeSlots.slot5" | "timeSlots.slot6" | "timeSlots.slot7" | "timeSlots.slot8" | "timeSlots.slot9")}
</span>
</div>

{/* Duration */}
<div className={`flex items-center justify-between ${locale === 'ar' ? 'flex-row-reverse' : 'flex-row'}`}>
<span className="text-base font-bold text-gray-800 dark:text-gray-200">
{locale === 'ar' ? 'المدة' : 'Duration'}
</span>
<span className="text-sm font-semibold text-white bg-primary px-3 py-1 rounded-lg shadow-sm">
{item.duration}
</span>
</div>
</div>
</div>
))}
</div>
</div>
</div>
);
}