feat: display multi organization in event detail#304
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 33 minutes and 47 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 Walkthrough总览本PR为事件页面引入多个主办组织的支持,包括一个新的组织卡片组件以及相应的多语言UI文本(支持英文、俄文、简体中文和繁体中文),同时更新GitHub Actions工作流中的Docker工具版本。 变更
预期代码审查工作量🎯 3 (Moderate) | ⏱️ ~25 minutes 可能相关的PR
诗歌
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
📦 Next.js Bundle Analysis for furrycons-siteThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
356.46 KB (🟡 +210 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
One Page Changed Size
The following page changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load | % of Budget (350 KB) |
|---|---|---|---|
/[organization]/[slug] |
12.62 KB |
369.07 KB | 105.45% (🟡 +0.13%) |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/- <0.01%" it means that there was a change in bundle size, but it is a trivial enough amount that it can be ignored.
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/deploy-prod-cn.yml (1)
1-62:⚠️ Potential issue | 🟠 MajorPR 标题与实际变更内容不一致。
PR 标题为 "feat: display multi organization in event detail"(功能:在活动详情中显示多个组织),但实际的代码变更仅包含 CI/CD 工作流中 Docker GitHub Actions 的版本升级。这两个文件中的所有变更都是基础设施相关的依赖项升级,与多组织显示功能或活动详情无关。
请确认:
- 是否推送了错误的分支?
- 是否缺少实现多组织显示功能的代码文件?
- 或者 PR 标题/描述是否需要更新以反映实际的变更内容(例如:"chore: upgrade Docker GitHub Actions versions")?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/deploy-prod-cn.yml around lines 1 - 62, PR title "feat: display multi organization in event detail" doesn't match the changes (only CI workflow updates: jobs build-image, docker-smoke, push-and-notify and steps like "Login to Qcloud Hongkong Container Registry" and "Push tags"); either update the PR title/body to accurately describe this chore (e.g., "chore: upgrade Docker GitHub Actions versions / update CI workflows") or add the missing feature commits that implement the multi-organization display (ensure you include the relevant frontend/backend files and mention the feature-specific functions/components in the commit), and verify you pushed the correct branch before merging.
🧹 Nitpick comments (1)
src/components/event/EventOrganizationCard.tsx (1)
60-75: 切换按钮在orgList.length <= 1时是死代码,但仍建议禁用状态处理以防边界情况。当前通过
showOrgSwitcher控制整体显示,逻辑正确。可选建议:为 prev/next 按钮添加disabled状态或当orgList.length === 1时不渲染按钮组(已做),并考虑键盘左右方向键快捷切换以提升可访问性。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/event/EventOrganizationCard.tsx` around lines 60 - 75, The prev/next buttons in EventOrganizationCard are effectively dead when orgList.length <= 1 but lack explicit disabled state and keyboard support; update the rendering of the IoChevronBack/IoChevronForward buttons (the elements using onClick handlers goToPrev and goToNext) to include a disabled attribute and appropriate aria-disabled when orgList.length <= 1, add a visual disabled style class to match existing styles, and wire a keyboard handler on the parent (or the component) to call goToPrev/goToNext on ArrowLeft/ArrowRight so keyboard users can switch organizations; keep the existing showOrgSwitcher guard but ensure the disabled state and aria attributes are present for accessibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/deploy-prod-cn.yml:
- Line 48: The workflow currently references docker/login-action@v4; before
upgrading, verify your self-hosted/production runners meet the Node24/Actions
Runner v2.327.1+ requirement, test the login step end-to-end against your
registries (ECR, Docker Hub, etc.), and validate that any custom
scripts/extensions tolerate the action's ESM migration; also check compatibility
of updated dependencies (`@actions/core` -> 3.0.0 and `@docker/actions-toolkit` ->
0.77.0) or pin to a prior minor version of docker/login-action if your
environment cannot be upgraded yet.
In @.github/workflows/reusable-docker-build.yml:
- Line 50: The workflow now references docker/build-push-action@v7 which
introduced breaking changes (Node 24 requirement, removed env vars
DOCKER_BUILD_NO_SUMMARY and DOCKER_BUILD_EXPORT_RETENTION_DAYS, ESM migration,
and dependency upgrades); to fix, either pin the action to the last v6 release
or update the repository to meet v7 requirements: ensure your Actions Runner is
>= v2.327.1, remove/replace any usage of DOCKER_BUILD_NO_SUMMARY and
DOCKER_BUILD_EXPORT_RETENTION_DAYS with DOCKER_BUILD_SUMMARY=false, test and
adapt any code that relies on CommonJS to the action’s ESM behavior, and
validate any integrations that depended on previous
`@actions/core/`@docker/actions-toolkit behavior before switching to
docker/build-push-action@v7.
In `@src/components/event/EventOrganizationCard.tsx`:
- Around line 94-118: The two Link components that both navigate to
`/${organization.slug}` are inconsistent: remove the target="_blank" from the
top Link so both open in the same tab, and move the analytics call from the
inner button to the outer Link's onClick (so tracking always fires) — update the
Link wrapping the button to add onClick={() => sendTrack({...})} and keep the
button as a plain element; if you decide to keep opening in a new tab instead,
apply target="_blank" and rel="noopener noreferrer" to both Links instead;
adjust usages of Link, sendTrack, organization.slug, OrganizationStatus and t
accordingly.
- Around line 52-54: The hard-coded Chinese label in EventOrganizationCard
(inside the JSX branch guarded by showOrgSwitcher) should be replaced with a
i18n lookup: add a translation key event.hostSwitchIndex (with placeholders like
{{current}} and {{total}}) to each of the four common.json locale files, then
call t('event.hostSwitchIndex', { current: activeIndex + 1, total:
orgList.length }) in the component instead of the literal string so the
component uses localized text; keep the same JSX structure and import/use the
existing t() from your i18n hook/context.
- Around line 29-33: orgList can contain duplicates and undefined, and
organization uses a non-null assertion that can still be undefined; fix by
building orgList from props.event.organization and props.event.organizations
after filtering out null/undefined and deduplicating by a stable key (slug or
id), e.g., dedupe by slug/id, then set showOrgSwitcher = dedupedList.length > 1,
compute organization = dedupedList[activeIndex] ?? dedupedList[0] (without using
!) and ensure activeIndex is clamped/reset to 0 if it is out of bounds after
dedupe; if dedupedList is empty, return early (or render a safe placeholder) to
avoid accessing organization.logoUrl/slug.
- Line 84: The alt text in the EventOrganizationCard is hardcoded as
`${organization.name}'s logo`; change it to use the existing i18n key
organization.logoAlt instead — call the translation function (e.g., t or i18n.t)
inside EventOrganizationCard to produce the alt value and pass organization.name
as the name variable (e.g., t('organization.logoAlt', { name: organization.name
})), then set alt to that translated string so localized punctuation/wording is
used.
In `@src/pages/`[organization]/[slug].tsx:
- Around line 74-78: The host display currently concatenates names with a
hard-coded Chinese delimiter and may duplicate event.organization if it's also
present in event.organizations; update the rendering in the component that calls
t("event.hostBy", ...) to (1) build the hostName using Intl.ListFormat (fallback
to locale-appropriate separator) instead of the literal "、" so it localizes for
en/ru/etc., (2) deduplicate names by creating a unique list from
event.organization?.name plus event.organizations.map(o => o.name) before
formatting, and (3) consistently use optional chaining on event.organization
(e.g., event.organization?.name) and guard the whole block so it won’t throw
when organization is missing; pass the formatted, deduped hostName into
t("event.hostBy", { hostName }).
In `@src/types/event.ts`:
- Line 85: EventSchema 将 organizations 定为必填并且使用 EventSchema.parse()
严格校验,这会在后端未对历史事件返回 organizations 时导致 getEventDetail 抛错并触发 404;请将 EventSchema 中的
organizations 字段改为可选(例如从 z.array(OrganizationSchema) 改为
z.array(OrganizationSchema).optional() 或
z.array(...).nullable(),视需返回形态),并更新任何依赖位置(如 EventSchema.parse() 的调用处和
pages/[organization]/[slug].tsx 中对 event.organizations 的访问)以做兼容性处理,或确认并保证后端
internal/website/event/detail 接口对所有事件均返回 organizations 数组后再保留必填约束。
---
Outside diff comments:
In @.github/workflows/deploy-prod-cn.yml:
- Around line 1-62: PR title "feat: display multi organization in event detail"
doesn't match the changes (only CI workflow updates: jobs build-image,
docker-smoke, push-and-notify and steps like "Login to Qcloud Hongkong Container
Registry" and "Push tags"); either update the PR title/body to accurately
describe this chore (e.g., "chore: upgrade Docker GitHub Actions versions /
update CI workflows") or add the missing feature commits that implement the
multi-organization display (ensure you include the relevant frontend/backend
files and mention the feature-specific functions/components in the commit), and
verify you pushed the correct branch before merging.
---
Nitpick comments:
In `@src/components/event/EventOrganizationCard.tsx`:
- Around line 60-75: The prev/next buttons in EventOrganizationCard are
effectively dead when orgList.length <= 1 but lack explicit disabled state and
keyboard support; update the rendering of the IoChevronBack/IoChevronForward
buttons (the elements using onClick handlers goToPrev and goToNext) to include a
disabled attribute and appropriate aria-disabled when orgList.length <= 1, add a
visual disabled style class to match existing styles, and wire a keyboard
handler on the parent (or the component) to call goToPrev/goToNext on
ArrowLeft/ArrowRight so keyboard users can switch organizations; keep the
existing showOrgSwitcher guard but ensure the disabled state and aria attributes
are present for accessibility.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b45edb1d-4990-4ff4-b49d-48c923a2a23a
📒 Files selected for processing (9)
.github/workflows/deploy-prod-cn.yml.github/workflows/reusable-docker-build.ymlpublic/locales/en/common.jsonpublic/locales/ru/common.jsonpublic/locales/zh-Hans/common.jsonpublic/locales/zh-Hant/common.jsonsrc/components/event/EventOrganizationCard.tsxsrc/pages/[organization]/[slug].tsxsrc/types/event.ts
| const orgList = [props.event.organization, ...props.event.organizations]; | ||
| const [activeIndex, setActiveIndex] = useState(0); | ||
| const showOrgSwitcher = orgList.length > 1; | ||
|
|
||
| const organization = orgList[activeIndex] ?? orgList[0]!; |
There was a problem hiding this comment.
orgList 可能重复且存在空值风险。
orgList = [props.event.organization, ...props.event.organizations]未去重。若后端在organizations中已包含主办方本身,切换器会出现相同主办方重复出现的条目。organization = orgList[activeIndex] ?? orgList[0]!使用了非空断言,但若event.organization为空且event.organizations为空,orgList[0]仍为undefined,下方organization.logoUrl、organization.slug等访问将抛错。
建议按 slug/id 去重并对空情形提前返回:
♻️ 建议修改
- const orgList = [props.event.organization, ...props.event.organizations];
+ const orgList = [props.event.organization, ...(props.event.organizations ?? [])]
+ .filter((o): o is NonNullable<typeof o> => !!o)
+ .filter((o, i, arr) => arr.findIndex((x) => x.slug === o.slug) === i);
+ if (orgList.length === 0) return null;📝 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.
| const orgList = [props.event.organization, ...props.event.organizations]; | |
| const [activeIndex, setActiveIndex] = useState(0); | |
| const showOrgSwitcher = orgList.length > 1; | |
| const organization = orgList[activeIndex] ?? orgList[0]!; | |
| const orgList = [props.event.organization, ...(props.event.organizations ?? [])] | |
| .filter((o): o is NonNullable<typeof o> => !!o) | |
| .filter((o, i, arr) => arr.findIndex((x) => x.slug === o.slug) === i); | |
| if (orgList.length === 0) return null; | |
| const [activeIndex, setActiveIndex] = useState(0); | |
| const showOrgSwitcher = orgList.length > 1; | |
| const organization = orgList[activeIndex] ?? orgList[0]!; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/event/EventOrganizationCard.tsx` around lines 29 - 33, orgList
can contain duplicates and undefined, and organization uses a non-null assertion
that can still be undefined; fix by building orgList from
props.event.organization and props.event.organizations after filtering out
null/undefined and deduplicating by a stable key (slug or id), e.g., dedupe by
slug/id, then set showOrgSwitcher = dedupedList.length > 1, compute organization
= dedupedList[activeIndex] ?? dedupedList[0] (without using !) and ensure
activeIndex is clamped/reset to 0 if it is out of bounds after dedupe; if
dedupedList is empty, return early (or render a safe placeholder) to avoid
accessing organization.logoUrl/slug.
📦 Next.js Bundle Analysis for furrycons-siteThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
356.46 KB (🟡 +217 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
One Page Changed Size
The following page changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load | % of Budget (350 KB) |
|---|---|---|---|
/[organization]/[slug] |
12.6 KB |
369.06 KB | 105.45% (🟡 +0.12%) |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/- <0.01%" it means that there was a change in bundle size, but it is a trivial enough amount that it can be ignored.
📦 Next.js Bundle Analysis for furrycons-siteThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
356.46 KB (🟡 +212 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
One Page Changed Size
The following page changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load | % of Budget (350 KB) |
|---|---|---|---|
/[organization]/[slug] |
12.6 KB |
369.06 KB | 105.45% (🟡 +0.12%) |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/- <0.01%" it means that there was a change in bundle size, but it is a trivial enough amount that it can be ignored.
Summary by CodeRabbit
发布说明
新功能
本地化支持
基础设施