Update agenda Page - #39
Conversation
WalkthroughReplaces inline agenda rendering in the agenda page with a new AgendaSection component. The page now renders a streamlined hero and delegates agenda display to the component. AgendaSection provides a presentational, localized agenda grid with RTL handling, static data, and translation-driven labels. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant NextApp as Next.js App Router
participant AgendaPage as Agenda Page
participant AgendaSection as AgendaSection (Client)
User->>NextApp: Navigate /[locale]/agenda
NextApp->>AgendaPage: Render with locale, translations
AgendaPage-->>AgendaSection: Render component
AgendaSection->>AgendaSection: Load t() and locale via next-intl
AgendaSection->>AgendaSection: Map static agendaItems, apply RTL order
AgendaSection-->>User: Display agenda grid with localized labels
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/[locale]/agenda/page.tsx (1)
5-12: Fix Props typing; avoid awaiting non-Promise paramsNext.js passes
paramsas a plain object. Typing it as a Promise and awaiting it is misleading. Simplify the type and dropawait.-type Props = { - params: Promise<{ locale: Locale }>; -}; +type Props = { + params: { locale: Locale }; +}; export default async function AgendaPage({ params }: Props) { - const { locale } = await params; + const { locale } = params; const t = await getTranslations("Agenda");
🧹 Nitpick comments (5)
src/app/[locale]/agenda/page.tsx (1)
24-35: Localize hero title instead of hardcoding stringsMove hero title parts to translations to keep all copy in i18n files and ease future localization.
- <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> + <h1 className="text-5xl md:text-7xl font-bold mb-4"> + <span className="text-gray-900 dark:text-white font-bold"> + {t("heroTitle.part1")} + </span> + <span className="text-primary font-bold"> + {t("heroTitle.part2")} + </span> + </h1>src/components/AgendaSection.tsx (4)
9-19: Type agenda items to remove brittle casts and improve safetyDefine a literal union for
typeand a typedAgendaItemso you don’t need the long string-literal cast in the title lookup.+type AgendaType = + | "registration" | "exhibition" | "opening" + | "session1" | "break1" | "session2" | "break2" | "session3" | "closing"; +type AgendaItem = { id: 1|2|3|4|5|6|7|8|9; type: AgendaType; duration: string }; - const agendaItems = [ + const agendaItems: ReadonlyArray<AgendaItem> = [Then you can simplify the title lookup to:
- {t(`agendaItems.${item.type}` as "agendaItems.registration" | ... | "agendaItems.closing")} + {t(`agendaItems.${item.type}`)}
30-34: Localize the header descriptionHardcoded EN/AR strings bypass your translation files and make adding more locales harder. Move this copy to i18n.
- {locale === 'ar' - ? 'اكتشف جدولنا المنسق بعناية من المحاضرات الملهمة وورش العمل التفاعلية' - : 'Discover our carefully curated schedule of inspiring talks and interactive workshops' - } + {t("description")}
55-73: Translate labels “Time” and “Duration”Keep labels in the dictionary for consistency and future locales.
- {locale === 'ar' ? 'الوقت' : 'Time'} + {t("timeLabel")} @@ - {locale === 'ar' ? 'المدة' : 'Duration'} + {t("durationLabel")}
5-8: Reduce repetition with a boolean flagDerive
isArabiconce and reuse to simplify className conditionals.- const locale = useLocale(); + const locale = useLocale(); + const isArabic = locale === 'ar'; @@ - <div className={`grid ... ${locale === 'ar' ? 'rtl' : 'ltr'}`}> + <div className={`grid ... ${isArabic ? 'rtl' : 'ltr'}`}>Also applies to: 30-71
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/app/[locale]/agenda/page.tsx(2 hunks)src/components/AgendaSection.tsx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/AgendaSection.tsx (3)
src/components/EventDetails.tsx (1)
EventDetails(6-82)src/components/AboutUs.tsx (1)
AboutUs(6-94)src/components/FeaturesGrid.tsx (1)
FeaturesGrid(6-36)
src/app/[locale]/agenda/page.tsx (1)
src/components/AgendaSection.tsx (1)
AgendaSection(5-82)
🔇 Additional comments (5)
src/app/[locale]/agenda/page.tsx (2)
21-44: Good extraction to a presentational componentImporting and rendering
AgendaSectionkeeps this server page lean and improves separation of concerns. The layout layering with the overlay andz-indexlooks correct.
37-39: LGTM on server-side translation usageUsing
getTranslations("Agenda")on the server for the subtitle is appropriate.src/components/AgendaSection.tsx (3)
1-4: Correct client boundary and intl hooksMarking the component as client and using
useTranslations/useLocaleis appropriate.
61-63: Nice: dir-aware time valuesSetting
diron the time slot ensures correct glyph ordering. Good attention to detail.
1-81: Verify translation keys in all locale files
Ensure each locale JSON (e.g., en.json, ar.json) defines:
- Agenda.title, Agenda.description, Agenda.heroSubtitle
- Agenda.agendaItems keys: registration, exhibition, opening, session1, break1, session2, break2, session3, closing
- Agenda.timeSlots.slot1 through slot9
- Agenda.timeLabel, Agenda.durationLabel
| <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 | ||
| }} | ||
| > |
There was a problem hiding this comment.
🛠️ 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.
| <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.
Summary by CodeRabbit
New Features
Refactor