Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR updates the member-facing experience by redesigning the Member Journey page (new layout, internal events UI, alumni section, CTA visuals) and making the Member Network page data-driven via a new /api/network-logos endpoint backed by NocoDB.
Changes:
- Redesign
app/member-journey/page.tsxwith a new timeline layout, department “mindmap”, revamped internal events section, alumni testimonials, and new CTA visuals. - Add a new API route
app/api/network-logos/route.tsand updateapp/member-network/page.tsxto fetch/render categorized logos. - Add new public assets (CTA SVGs + Cambridge aerial image) and supporting global CSS for the new visuals/animations.
Reviewed changes
Copilot reviewed 5 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| public/cta-right.svg | Adds decorative CTA SVG asset. |
| public/cta-left.svg | Adds decorative CTA SVG asset. |
| public/cambridge-aerial.webp | Adds Cambridge aerial image used on Member Journey page. |
| components/Navigation.tsx | Simplifies community submenu items by removing arrow icon markup. |
| app/member-network/page.tsx | Fetches network logos from new API and renders grouped logo grid with next/image. |
| app/member-journey/page.tsx | Major UI rewrite: new timeline cards, mindmap departments, internal events UI, alumni cards, CTA visuals. |
| app/globals.css | Adds .outline-text-dark and mindmap line dash animation styling. |
| app/api/network-logos/route.ts | New endpoint fetching and transforming NocoDB records into UI-friendly logo objects. |
| {(() => { | ||
| // Finops, Events, Marketing, Partnerships, People | ||
| // Arc: left, center-left, center, center-right, right | ||
| const positions: React.CSSProperties[] = [ |
There was a problem hiding this comment.
React.CSSProperties is used here, but React isn't imported in this file, so TypeScript will fail with "Cannot find namespace 'React'". Import type CSSProperties from react (or import React) and type positions as CSSProperties[] instead.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a dynamic Next.js API route to fetch/transform network logos from NocoDB; introduces CSS utilities for outlined text and animated dashed SVG lines; updates member-journey and member-network to use dynamic logos and revised assets/behaviors; adjusts navigation and several CTAs; adds a redirect page and TypeScript build cache. Changes
Sequence DiagramsequenceDiagram
participant Browser as Browser/Client
participant MemberPage as MemberNetworkPage
participant APIRoute as /api/network-logos
participant NocoDB as NocoDB API
Browser->>MemberPage: Request page
MemberPage->>MemberPage: set loading state
MemberPage->>APIRoute: GET /api/network-logos
APIRoute->>APIRoute: read env (NOCODB_API_TOKEN, TABLE_ID)
APIRoute->>NocoDB: fetch ?limit=1000 (header: xc-token)
NocoDB-->>APIRoute: 200 OK + records
APIRoute->>APIRoute: transform records -> NetworkLogo[] (extract signedPath/path/url or ui-avatars fallback)
APIRoute-->>MemberPage: 200 JSON NetworkLogo[]
MemberPage->>MemberPage: group by category, update state (loading=false)
MemberPage->>Browser: render categorized logo sections (images)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/member-journey/page.tsx (1)
37-37:⚠️ Potential issue | 🔴 CriticalFix case-sensitive image path to prevent 404 errors on production.
The code references
/internalevents.png(lowercasei), but the actual file isInternalevents.png(capitalI). Linux filesystems are case-sensitive, so this will fail to load on production.Update line 37:
-const placeholderImage = "/internalevents.png" +const placeholderImage = "/Internalevents.png"Also update the
onErrorhandlers at lines 598 and 616 to use the correct case.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` at line 37, The image path is using the wrong case causing 404s on case-sensitive filesystems: update the const placeholderImage definition (placeholderImage) to reference "/Internalevents.png" (capital I) and also update the two image onError handlers that fall back to the placeholder (the onError callbacks used near the image render code) to use the same "/Internalevents.png" value so all occurrences consistently reference the correctly-cased filename.
🧹 Nitpick comments (6)
app/member-network/page.tsx (1)
8-8:export const dynamichas no effect in client components.Since this file uses
"use client", thedynamicexport is ignored. This directive only affects Server Components and Route Handlers. The client-side fetch inuseEffectalready ensures dynamic behavior.🔧 Proposed fix - remove unused export
"use client" import { useState, useEffect } from "react" import Script from "next/script" import Image from "next/image" import Hero from "@/components/Hero" -export const dynamic = 'force-dynamic' - interface NetworkLogo {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-network/page.tsx` at line 8, Remove the unused Server Component directive by deleting the exported constant "dynamic" (export const dynamic = 'force-dynamic') from the client component in this file; since the file is marked "use client" the dynamic export has no effect and can be removed to avoid confusion and dead code — locate the export named dynamic in this module (page.tsx) and remove it.app/api/network-logos/route.ts (1)
54-64: Hardcoded limit of 1000 records may be insufficient.If the network logos table grows beyond 1000 entries, logos will be silently truncated. Consider implementing pagination or documenting this limitation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/api/network-logos/route.ts` around lines 54 - 64, The fetch call that queries `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0` hardcodes limit=1000 which will truncate results if the table grows; update the handler in route.ts to implement pagination (iterate with offset and limit until fewer than limit records returned) or accept a query param to page through results, using the same fetch call pattern (NOCODB_BASE_URL, NOCODB_NETWORK_LOGOS_TABLE_ID) repeatedly and concatenating records before returning; alternatively document the 1000-record limitation if pagination is not desired.app/globals.css (1)
106-114: RenamedashFlowtodash-flowfor kebab-case consistency.Stylelint flagged that keyframe names should follow kebab-case convention.
🔧 Proposed fix
.mindmap-line { stroke-dasharray: 12 8; - animation: dashFlow 1s linear infinite; + animation: dash-flow 1s linear infinite; } -@keyframes dashFlow { +@keyframes dash-flow { 0% { stroke-dashoffset: 20; } 100% { stroke-dashoffset: 0; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/globals.css` around lines 106 - 114, Rename the keyframes identifier from "dashFlow" to kebab-case "dash-flow" and update any references: change the `@keyframes` declaration name and the animation usage on .mindmap-line (animation: dashFlow 1s linear infinite) to animation: dash-flow 1s linear infinite; ensure the stroke-dashoffset keyframes remain the same and search for any other occurrences of "dashFlow" to update them as well.app/member-journey/page.tsx (2)
251-259: Unused navigation functionshandlePrevImgandhandleNextImg.These functions are defined but never called in the JSX. If image navigation was intentionally removed, these should be cleaned up.
🧹 Remove unused code
- const handlePrevImg = () => { - if (!activeImages || activeImages.length <= 1) return - setEventImgIdx(prev => (prev - 1 + activeImages.length) % activeImages.length) - } - - const handleNextImg = () => { - if (!activeImages || activeImages.length <= 1) return - setEventImgIdx(prev => (prev + 1) % activeImages.length) - }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 251 - 259, handlePrevImg and handleNextImg are defined but never used; either remove these unused functions or hook them up to the image navigation UI. If you remove them, delete the handlePrevImg and handleNextImg functions (and any related unused state like setEventImgIdx only if it's truly unused). If you intend to keep navigation, wire handlePrevImg and handleNextImg to the JSX navigation controls (e.g., prev/next buttons) so they call setEventImgIdx and use activeImages length as already implemented. Ensure references to activeImages and setEventImgIdx remain consistent with the existing state hooks when making the change.
7-7:export const dynamichas no effect in client components.Same as
member-network/page.tsx- this directive is ignored in"use client"files.🔧 Proposed fix
"use client" import { useState, useEffect, useRef, useCallback, type CSSProperties } from 'react' import Script from 'next/script' import Hero from "@/components/Hero" -export const dynamic = 'force-dynamic' - interface TimelineEvent {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` at line 7, The file exports a client-only directive 'export const dynamic' which is ignored in components marked "use client"; remove the redundant export (the 'export const dynamic' symbol) from member-journey/page.tsx (same change as in member-network/page.tsx) or convert the component to a server component if you need that dynamic behavior—ensure you only keep 'export const dynamic' in true server components, not in files that begin with "use client".tsconfig.tsbuildinfo (1)
1-1: Addtsconfig.tsbuildinfoto.gitignore.This auto-generated TypeScript incremental build metadata file should not be tracked in version control. It causes unnecessary merge conflicts and noisy diffs with each build, yet provides no benefit since TypeScript regenerates it automatically.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tsconfig.tsbuildinfo` at line 1, The repo is tracking the auto-generated TypeScript incremental file tsconfig.tsbuildinfo; remove it from version control and ignore future changes by adding tsconfig.tsbuildinfo to .gitignore and running git rm --cached tsconfig.tsbuildinfo (then commit the updated .gitignore and removal) so TypeScript can regenerate it locally without noisy diffs or merge conflicts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/api/network-logos/route.ts`:
- Around line 22-28: The constructed logoUrl can produce a double slash when
logo.signedPath or logo.path begins with '/', so change the concatenation in the
block that sets logoUrl (the branches referencing logo.signedPath, logo.path and
NOCODB_BASE_URL) to normalize the path first: either remove any leading slashes
from logo.signedPath/logo.path (e.g., trimLeft('/')/replace) before joining with
NOCODB_BASE_URL or build the URL with a proper URL join (e.g., new URL(path,
NOCODB_BASE_URL).toString()) to ensure a single slash between base and path.
In `@app/member-journey/page.tsx`:
- Around line 786-789: The "Apply Now" button in app/member-journey/page.tsx
currently has no action; add navigation behavior by turning the button into a
Next.js Link or attaching an onClick that routes to the application page (e.g.,
"/apply" or the correct route) so clicks navigate to the form; locate the JSX
for the button (the element with className "px-8 py-3 bg-brand-pink...") and
replace or wrap it with Link from 'next/link' or use useRouter().push inside an
onClick handler to perform the navigation.
- Line 378: Remove the duplicate conflicting Tailwind margin classes by editing
the JSX div that currently has className="space-y-3 mt-4 mt-0" (and the other
similar occurrence later) so only the intended margin-top remains (choose either
mt-0 or mt-4) — locate the div with className containing "space-y-3 mt-4 mt-0"
and remove the unwanted mt-* token to eliminate the merge artifact.
---
Outside diff comments:
In `@app/member-journey/page.tsx`:
- Line 37: The image path is using the wrong case causing 404s on case-sensitive
filesystems: update the const placeholderImage definition (placeholderImage) to
reference "/Internalevents.png" (capital I) and also update the two image
onError handlers that fall back to the placeholder (the onError callbacks used
near the image render code) to use the same "/Internalevents.png" value so all
occurrences consistently reference the correctly-cased filename.
---
Nitpick comments:
In `@app/api/network-logos/route.ts`:
- Around line 54-64: The fetch call that queries
`${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`
hardcodes limit=1000 which will truncate results if the table grows; update the
handler in route.ts to implement pagination (iterate with offset and limit until
fewer than limit records returned) or accept a query param to page through
results, using the same fetch call pattern (NOCODB_BASE_URL,
NOCODB_NETWORK_LOGOS_TABLE_ID) repeatedly and concatenating records before
returning; alternatively document the 1000-record limitation if pagination is
not desired.
In `@app/globals.css`:
- Around line 106-114: Rename the keyframes identifier from "dashFlow" to
kebab-case "dash-flow" and update any references: change the `@keyframes`
declaration name and the animation usage on .mindmap-line (animation: dashFlow
1s linear infinite) to animation: dash-flow 1s linear infinite; ensure the
stroke-dashoffset keyframes remain the same and search for any other occurrences
of "dashFlow" to update them as well.
In `@app/member-journey/page.tsx`:
- Around line 251-259: handlePrevImg and handleNextImg are defined but never
used; either remove these unused functions or hook them up to the image
navigation UI. If you remove them, delete the handlePrevImg and handleNextImg
functions (and any related unused state like setEventImgIdx only if it's truly
unused). If you intend to keep navigation, wire handlePrevImg and handleNextImg
to the JSX navigation controls (e.g., prev/next buttons) so they call
setEventImgIdx and use activeImages length as already implemented. Ensure
references to activeImages and setEventImgIdx remain consistent with the
existing state hooks when making the change.
- Line 7: The file exports a client-only directive 'export const dynamic' which
is ignored in components marked "use client"; remove the redundant export (the
'export const dynamic' symbol) from member-journey/page.tsx (same change as in
member-network/page.tsx) or convert the component to a server component if you
need that dynamic behavior—ensure you only keep 'export const dynamic' in true
server components, not in files that begin with "use client".
In `@app/member-network/page.tsx`:
- Line 8: Remove the unused Server Component directive by deleting the exported
constant "dynamic" (export const dynamic = 'force-dynamic') from the client
component in this file; since the file is marked "use client" the dynamic export
has no effect and can be removed to avoid confusion and dead code — locate the
export named dynamic in this module (page.tsx) and remove it.
In `@tsconfig.tsbuildinfo`:
- Line 1: The repo is tracking the auto-generated TypeScript incremental file
tsconfig.tsbuildinfo; remove it from version control and ignore future changes
by adding tsconfig.tsbuildinfo to .gitignore and running git rm --cached
tsconfig.tsbuildinfo (then commit the updated .gitignore and removal) so
TypeScript can regenerate it locally without noisy diffs or merge conflicts.
🪄 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: 761ba0f1-f25a-4d08-ada4-898e3487d85a
⛔ Files ignored due to path filters (10)
public/cta-left.svgis excluded by!**/*.svgpublic/cta-right.svgis excluded by!**/*.svgpublic/member-journey-hero.jpgis excluded by!**/*.jpgpublic/member-startup-visit.jpgis excluded by!**/*.jpgpublic/member-workshops.pngis excluded by!**/*.pngpublic/monthly-event.jpgis excluded by!**/*.jpgpublic/more-dsc04524.jpgis excluded by!**/*.jpgpublic/more-img4955.jpgis excluded by!**/*.jpgpublic/more-isar-unfiltered.jpgis excluded by!**/*.jpgpublic/more-workshops.pngis excluded by!**/*.png
📒 Files selected for processing (7)
app/api/network-logos/route.tsapp/globals.cssapp/member-journey/page.tsxapp/member-network/page.tsxcomponents/Navigation.tsxpublic/cambridge-aerial.webptsconfig.tsbuildinfo
| if (logo.signedPath) { | ||
| logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`; | ||
| } else if (logo.path) { | ||
| logoUrl = `${NOCODB_BASE_URL}/${logo.path}`; | ||
| } else if (logo.url) { | ||
| logoUrl = logo.url; | ||
| } |
There was a problem hiding this comment.
Potential double-slash in constructed logo URLs.
If logo.signedPath or logo.path already starts with /, the resulting URL will have a double slash (e.g., https://ndb.startmunich.de//path/to/logo).
🔧 Proposed fix
if (record.Logo && Array.isArray(record.Logo) && record.Logo[0]) {
const logo = record.Logo[0];
if (logo.signedPath) {
- logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`;
+ logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath.replace(/^\//, '')}`;
} else if (logo.path) {
- logoUrl = `${NOCODB_BASE_URL}/${logo.path}`;
+ logoUrl = `${NOCODB_BASE_URL}/${logo.path.replace(/^\//, '')}`;
} else if (logo.url) {
logoUrl = logo.url;
}
}📝 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.
| if (logo.signedPath) { | |
| logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`; | |
| } else if (logo.path) { | |
| logoUrl = `${NOCODB_BASE_URL}/${logo.path}`; | |
| } else if (logo.url) { | |
| logoUrl = logo.url; | |
| } | |
| if (logo.signedPath) { | |
| logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath.replace(/^\//, '')}`; | |
| } else if (logo.path) { | |
| logoUrl = `${NOCODB_BASE_URL}/${logo.path.replace(/^\//, '')}`; | |
| } else if (logo.url) { | |
| logoUrl = logo.url; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/api/network-logos/route.ts` around lines 22 - 28, The constructed logoUrl
can produce a double slash when logo.signedPath or logo.path begins with '/', so
change the concatenation in the block that sets logoUrl (the branches
referencing logo.signedPath, logo.path and NOCODB_BASE_URL) to normalize the
path first: either remove any leading slashes from logo.signedPath/logo.path
(e.g., trimLeft('/')/replace) before joining with NOCODB_BASE_URL or build the
URL with a proper URL join (e.g., new URL(path, NOCODB_BASE_URL).toString()) to
ensure a single slash between base and path.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/member-journey/page.tsx (1)
704-710:⚠️ Potential issue | 🟡 MinorMissing
onErrorfallback for hovered event images.The auto-rotating event images (line 751) and "more" images (line 690) have
onErrorhandlers, but hovered event images don't. This inconsistency could result in broken images.🔧 Proposed fix
<img key={eventImages[eventImageIndex]?.src} src={eventImages[eventImageIndex]?.src} alt={eventImages[eventImageIndex]?.title} className="w-full h-full object-cover fade-swap" + onError={(e) => { (e.target as HTMLImageElement).src = '/internalevents.png' }} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 704 - 710, Add an onError handler to the hovered event image element (the <img> using eventImages[eventImageIndex]?.src and key/title) to mirror the behavior used by the auto-rotating and "more" images: call the same image error handler used elsewhere (the handler used for auto-rotating/"more" images, e.g., handleImageError/onEventImageError) so the component replaces the broken src with the fallback or marks the image as errored; this ensures the hovered image (key eventImages[eventImageIndex]?.src, alt eventImages[eventImageIndex]?.title, className "fade-swap") will not render broken images.
🧹 Nitpick comments (1)
app/member-journey/page.tsx (1)
543-576: Mindmap positions are tightly coupled to exactly 5 departments.The hardcoded
positionsarray has exactly 5 entries matching the currentdepartmentsarray. If departments are added or removed, this will silently fail or produce incorrect layouts.💡 Consider adding a guard or generating positions dynamically
// Option 1: Add a runtime check if (departments.length !== positions.length) { console.warn(`Mindmap positions (${positions.length}) don't match departments (${departments.length})`) } // Option 2: Or define positions alongside department data🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 543 - 576, The positions array in the block that renders departments (the const positions and its use in departments.map) is hardcoded for exactly five items; add a safeguard and/or dynamic position generation: check that departments.length equals positions.length and log/warn (or fallback) if not, and preferably replace the fixed const positions with a small helper (e.g., generatePositions(count) or computeArcPositions) that returns an array of CSSProperties for any departments.length and then use style={generatedPositions[i]} inside the departments.map; update the rendering code to use the generated positions and fall back to centered stacking if generation fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/globals.css`:
- Around line 100-114: Rename the keyframes identifier from dashFlow to
dash-flow to satisfy the keyframes-name-pattern rule and update the animation
reference in the .mindmap-line rule accordingly; specifically, rename the
`@keyframes` dashFlow declaration to `@keyframes` dash-flow and change the animation
property on .mindmap-line (animation: dashFlow 1s linear infinite) to use
dash-flow.
In `@app/member-journey/page.tsx`:
- Around line 581-602: The mobile department cards (rendered in the
departments.map loop inside the lg:hidden container) are missing padding causing
content to touch borders; update the outer card container element (the div with
className "relative bg-white/5 border border-white/10 overflow-hidden") used for
each dept to include the same padding as desktop (e.g., add p-5) so the dept
icon, name, description and responsibilities inside the map (dept, resp) have
consistent spacing.
- Around line 308-311: The updateScroll function can divide by zero when
scrollWidth === clientWidth; change updateScroll to compute a denominator =
scrollWidth - clientWidth and if denominator <= 0 set setScrollProgress(0) (or
clamp to 0) else compute setScrollProgress(scrollLeft / denominator), and
optionally clamp the result to [0,1]; reference the updateScroll function and
the variables scrollLeft, scrollWidth, clientWidth and setScrollProgress when
making the change.
---
Outside diff comments:
In `@app/member-journey/page.tsx`:
- Around line 704-710: Add an onError handler to the hovered event image element
(the <img> using eventImages[eventImageIndex]?.src and key/title) to mirror the
behavior used by the auto-rotating and "more" images: call the same image error
handler used elsewhere (the handler used for auto-rotating/"more" images, e.g.,
handleImageError/onEventImageError) so the component replaces the broken src
with the fallback or marks the image as errored; this ensures the hovered image
(key eventImages[eventImageIndex]?.src, alt eventImages[eventImageIndex]?.title,
className "fade-swap") will not render broken images.
---
Nitpick comments:
In `@app/member-journey/page.tsx`:
- Around line 543-576: The positions array in the block that renders departments
(the const positions and its use in departments.map) is hardcoded for exactly
five items; add a safeguard and/or dynamic position generation: check that
departments.length equals positions.length and log/warn (or fallback) if not,
and preferably replace the fixed const positions with a small helper (e.g.,
generatePositions(count) or computeArcPositions) that returns an array of
CSSProperties for any departments.length and then use
style={generatedPositions[i]} inside the departments.map; update the rendering
code to use the generated positions and fall back to centered stacking if
generation fails.
🪄 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: 2c648255-434d-4f57-ba13-ea5f5dc9665a
📒 Files selected for processing (4)
app/globals.cssapp/member-journey/page.tsxcomponents/Navigation.tsxtsconfig.tsbuildinfo
✅ Files skipped from review due to trivial changes (2)
- components/Navigation.tsx
- tsconfig.tsbuildinfo
| .outline-text-dark { | ||
| -webkit-text-stroke: 2px #00002c; | ||
| -webkit-text-fill-color: transparent; | ||
| paint-order: stroke fill; | ||
| } | ||
|
|
||
| .mindmap-line { | ||
| stroke-dasharray: 12 8; | ||
| animation: dashFlow 1s linear infinite; | ||
| } | ||
|
|
||
| @keyframes dashFlow { | ||
| 0% { stroke-dashoffset: 20; } | ||
| 100% { stroke-dashoffset: 0; } | ||
| } |
There was a problem hiding this comment.
Keyframes name should use kebab-case per Stylelint rule.
The animation name dashFlow violates the keyframes-name-pattern rule. Rename to dash-flow for consistency.
🔧 Proposed fix
.mindmap-line {
stroke-dasharray: 12 8;
- animation: dashFlow 1s linear infinite;
+ animation: dash-flow 1s linear infinite;
}
- `@keyframes` dashFlow {
+ `@keyframes` dash-flow {
0% { stroke-dashoffset: 20; }
100% { stroke-dashoffset: 0; }
}📝 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.
| .outline-text-dark { | |
| -webkit-text-stroke: 2px #00002c; | |
| -webkit-text-fill-color: transparent; | |
| paint-order: stroke fill; | |
| } | |
| .mindmap-line { | |
| stroke-dasharray: 12 8; | |
| animation: dashFlow 1s linear infinite; | |
| } | |
| @keyframes dashFlow { | |
| 0% { stroke-dashoffset: 20; } | |
| 100% { stroke-dashoffset: 0; } | |
| } | |
| .outline-text-dark { | |
| -webkit-text-stroke: 2px `#00002c`; | |
| -webkit-text-fill-color: transparent; | |
| paint-order: stroke fill; | |
| } | |
| .mindmap-line { | |
| stroke-dasharray: 12 8; | |
| animation: dash-flow 1s linear infinite; | |
| } | |
| `@keyframes` dash-flow { | |
| 0% { stroke-dashoffset: 20; } | |
| 100% { stroke-dashoffset: 0; } | |
| } |
🧰 Tools
🪛 Stylelint (17.5.0)
[error] 111-111: Expected keyframe name "dashFlow" to be kebab-case (keyframes-name-pattern)
(keyframes-name-pattern)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/globals.css` around lines 100 - 114, Rename the keyframes identifier from
dashFlow to dash-flow to satisfy the keyframes-name-pattern rule and update the
animation reference in the .mindmap-line rule accordingly; specifically, rename
the `@keyframes` dashFlow declaration to `@keyframes` dash-flow and change the
animation property on .mindmap-line (animation: dashFlow 1s linear infinite) to
use dash-flow.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/member-journey/page.tsx (1)
705-711:⚠️ Potential issue | 🟡 MinorMissing
onErrorfallback on hovered event image.The hovered event image display lacks an
onErrorhandler, while the "moreImages" grid (line 691) and auto-rotating display (line 748) both have fallbacks. This inconsistency could result in broken images when hovering over events with failed image loads.🔧 Proposed fix
<img key={eventImages[eventImageIndex]?.src} src={eventImages[eventImageIndex]?.src} alt={eventImages[eventImageIndex]?.title} className="w-full h-full object-cover fade-swap" + onError={(e) => { (e.target as HTMLImageElement).src = '/internalevents.png' }} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 705 - 711, The hovered event image at the <img> using eventImages[eventImageIndex] lacks an onError fallback; add an onError handler to that <img> (the same one rendering eventImages[eventImageIndex]?.src with className "fade-swap") that replaces the failed src with the same fallback used by the "moreImages" grid and the auto-rotating display (or a shared placeholder variable), and ensure the handler avoids an infinite loop (e.g., only replace once or check current src before swapping).
🧹 Nitpick comments (1)
app/member-journey/page.tsx (1)
505-505: Consider making mindmap height more responsive.The fixed
900pxheight and-100pxnegative margin may cause layout issues on smaller desktop screens or if content changes. Consider using viewport-relative units or flexbox/grid for more robust sizing.- <div className="relative w-full" style={{ height: '900px', marginBottom: '-100px' }}> + <div className="relative w-full min-h-[700px] lg:min-h-[900px]" style={{ marginBottom: '-100px' }}>Alternatively, investigate why the negative margin is needed—it often indicates a spacing issue that could be solved at a parent level.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` at line 505, The inline style on the div rendered in page.tsx (the element with className "relative w-full") uses a fixed height: '900px' and marginBottom: '-100px' which is brittle; replace the fixed pixel height and negative margin with a responsive approach — e.g., use minHeight or height in viewport units (like minHeight: '60vh' or height: '70vh'), or switch the container to a flex or grid layout that lets the element grow/shrink (adjust parent container styles instead of using negative margin), and remove the negative margin once the parent spacing is fixed so the component adapts on smaller screens.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@app/member-journey/page.tsx`:
- Around line 705-711: The hovered event image at the <img> using
eventImages[eventImageIndex] lacks an onError fallback; add an onError handler
to that <img> (the same one rendering eventImages[eventImageIndex]?.src with
className "fade-swap") that replaces the failed src with the same fallback used
by the "moreImages" grid and the auto-rotating display (or a shared placeholder
variable), and ensure the handler avoids an infinite loop (e.g., only replace
once or check current src before swapping).
---
Nitpick comments:
In `@app/member-journey/page.tsx`:
- Line 505: The inline style on the div rendered in page.tsx (the element with
className "relative w-full") uses a fixed height: '900px' and marginBottom:
'-100px' which is brittle; replace the fixed pixel height and negative margin
with a responsive approach — e.g., use minHeight or height in viewport units
(like minHeight: '60vh' or height: '70vh'), or switch the container to a flex or
grid layout that lets the element grow/shrink (adjust parent container styles
instead of using negative margin), and remove the negative margin once the
parent spacing is fixed so the component adapts on smaller screens.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ab043521-b2dd-4444-9a22-d4ff99dd5ffe
📒 Files selected for processing (1)
app/member-journey/page.tsx
There was a problem hiding this comment.
♻️ Duplicate comments (1)
app/member-journey/page.tsx (1)
559-580:⚠️ Potential issue | 🟡 MinorMobile department cards are still missing padding.
The mobile fallback cards lack padding, causing content to touch the card borders. The desktop mindmap cards use
p-5(line 537), but the mobile version at line 563 doesn't have any padding applied.🔧 Proposed fix
<div className="lg:hidden space-y-4"> {departments.map((dept) => ( <div key={dept.id} - className="relative bg-white/5 border border-white/10 overflow-hidden" + className="relative bg-white/5 border border-white/10 overflow-hidden p-5" >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 559 - 580, The mobile department cards rendered in the departments.map callback (inside the "lg:hidden space-y-4" block) are missing padding so content touches the card borders; update the card container (the div keyed by dept.id with classes "relative bg-white/5 border border-white/10 overflow-hidden") to include the same padding as desktop (e.g., add p-5) so the icon, title, description, and responsibility list have consistent spacing; ensure you only modify that card div class string in the component rendering departments so desktop behavior (lg:...) remains unchanged.
🧹 Nitpick comments (1)
app/member-journey/page.tsx (1)
682-688: MissingonErrorfallback for hovered event images.The hovered event image (line 683-688) lacks an
onErrorhandler, unlike the "more" images (line 668) and auto-rotating images (line 707) which both fall back to/internalevents.png. This inconsistency could result in broken images if a local asset fails to load.🔧 Proposed fix
<img key={eventImages[eventImageIndex]?.src} src={eventImages[eventImageIndex]?.src} alt={eventImages[eventImageIndex]?.title} className="w-full h-full object-cover fade-swap" + onError={(e) => { (e.target as HTMLImageElement).src = '/internalevents.png' }} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 682 - 688, The hovered event image img rendering using eventImages[eventImageIndex] is missing an onError fallback; update the img element (the one using key={eventImages[eventImageIndex]?.src} src={eventImages[eventImageIndex]?.src} alt={eventImages[eventImageIndex]?.title} className="...fade-swap") to include an onError handler that sets the image src to '/internalevents.png' (matching the fallback used for the "more" images and auto-rotating images) and ensure it guards against infinite loops by only replacing the src once.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/member-journey/page.tsx`:
- Around line 559-580: The mobile department cards rendered in the
departments.map callback (inside the "lg:hidden space-y-4" block) are missing
padding so content touches the card borders; update the card container (the div
keyed by dept.id with classes "relative bg-white/5 border border-white/10
overflow-hidden") to include the same padding as desktop (e.g., add p-5) so the
icon, title, description, and responsibility list have consistent spacing;
ensure you only modify that card div class string in the component rendering
departments so desktop behavior (lg:...) remains unchanged.
---
Nitpick comments:
In `@app/member-journey/page.tsx`:
- Around line 682-688: The hovered event image img rendering using
eventImages[eventImageIndex] is missing an onError fallback; update the img
element (the one using key={eventImages[eventImageIndex]?.src}
src={eventImages[eventImageIndex]?.src}
alt={eventImages[eventImageIndex]?.title} className="...fade-swap") to include
an onError handler that sets the image src to '/internalevents.png' (matching
the fallback used for the "more" images and auto-rotating images) and ensure it
guards against infinite loops by only replacing the src once.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 781bc720-04bc-4b79-a939-cf49ccf59d33
⛔ Files ignored due to path filters (1)
public/Builder_Weekend.jpgis excluded by!**/*.jpg
📒 Files selected for processing (7)
app/apply/page.tsxapp/join-start/2026/page.tsxapp/member-journey/page.tsxapp/members/page.tsxapp/startups/page.tsxcomponents/Navigation.tsxtsconfig.tsbuildinfo
✅ Files skipped from review due to trivial changes (3)
- app/members/page.tsx
- app/join-start/2026/page.tsx
- tsconfig.tsbuildinfo
🚧 Files skipped from review as they are similar to previous changes (1)
- components/Navigation.tsx
569e653 to
b42a19f
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
app/globals.css (1)
106-114:⚠️ Potential issue | 🟡 MinorRename
dashFlowto kebab-case to satisfy lint.Line 108 and Line 111 still use
dashFlow, which violates the configured keyframe naming rule and can fail stylelint.🔧 Proposed fix
.mindmap-line { stroke-dasharray: 12 8; - animation: dashFlow 1s linear infinite; + animation: dash-flow 1s linear infinite; } - `@keyframes` dashFlow { + `@keyframes` dash-flow { 0% { stroke-dashoffset: 20; } 100% { stroke-dashoffset: 0; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/globals.css` around lines 106 - 114, The keyframe name dashFlow violates the kebab-case rule; rename the keyframe to a kebab-case identifier (e.g., dash-flow) and update the .mindmap-line animation property to use the new name so both the `@keyframes` rule and the animation reference match (update the `@keyframes` declaration and the animation: dashFlow → animation: dash-flow in the .mindmap-line rule).app/api/network-logos/route.ts (1)
22-26:⚠️ Potential issue | 🟡 MinorNormalize attachment paths before joining URL base.
Line 23 and Line 25 can emit double slashes when incoming paths already start with
/.🔧 Proposed fix
if (logo.signedPath) { - logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`; + logoUrl = `${NOCODB_BASE_URL}/${String(logo.signedPath).replace(/^\/+/, '')}`; } else if (logo.path) { - logoUrl = `${NOCODB_BASE_URL}/${logo.path}`; + logoUrl = `${NOCODB_BASE_URL}/${String(logo.path).replace(/^\/+/, '')}`; } else if (logo.url) { logoUrl = logo.url; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/api/network-logos/route.ts` around lines 22 - 26, The URL concatenation can produce double slashes when logo.signedPath or logo.path begins with a leading slash; update the logic that builds logoUrl (the branches checking logo.signedPath and logo.path which append to NOCODB_BASE_URL) to normalize the attachment path first—strip any leading slashes (or use a URL/path-join helper) before joining with NOCODB_BASE_URL so the resulting logoUrl is never formed with "//" between base and path; leave the logo.url branch unchanged.app/member-journey/page.tsx (1)
559-564:⚠️ Potential issue | 🟡 MinorAdd padding to mobile department cards for consistent spacing.
On mobile, content sits against the border because the card wrapper lacks padding.
🔧 Proposed fix
- className="relative bg-white/5 border border-white/10 overflow-hidden" + className="relative bg-white/5 border border-white/10 overflow-hidden p-5"Based on learnings: Applies to **/*.{tsx,ts} : Implement responsive design.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-journey/page.tsx` around lines 559 - 564, The mobile department cards rendered in the departments.map loop (the element with className "lg:hidden space-y-4" and each card div with className "relative bg-white/5 border border-white/10 overflow-hidden") lack inner padding; update the card wrapper (the mapped div with key={dept.id}) to include responsive padding classes (for example add "px-4 py-3" or "p-4 sm:p-6 lg:p-0") so that on small screens the content has consistent spacing while preserving existing lg behavior.
🧹 Nitpick comments (1)
app/member-network/page.tsx (1)
10-15: Avoid duplicating theNetworkLogocontract in client and API code.This interface mirrors the API route shape exactly; keeping two copies increases drift risk. Consider moving it to a shared
lib/typesmodule and importing from there.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/member-network/page.tsx` around lines 10 - 15, The interface NetworkLogo is duplicated between client and API; extract NetworkLogo into a single shared types module, export it, then replace the local interface declaration with an import of NetworkLogo in both the client code (where it currently appears) and the API route that uses the same shape; ensure the shared module is exported correctly and update any imports/usages to reference the shared NetworkLogo type to prevent drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/api/network-logos/route.ts`:
- Around line 55-64: The NocoDB fetch call (the request built with
NOCODB_BASE_URL, NOCODB_NETWORK_LOGOS_TABLE_ID and NOCODB_API_TOKEN) lacks an
abort/timeout and can hang; add an AbortController, pass its signal into the
fetch options, start a timer (e.g., using setTimeout) that calls
controller.abort() after a reasonable timeout (e.g., 5–10s), and clear the timer
when the fetch completes; ensure you catch the abort error and handle it (return
a 504 or appropriate error) so the route handler does not hang.
In `@app/member-journey/page.tsx`:
- Around line 683-688: The hovered-event image tag is missing an onError
fallback so broken URLs render a broken tile; update the <img> (the element
rendering eventImages[eventImageIndex]?.src with className "fade-swap") to
include an onError handler that replaces the image src with a known fallback
(e.g., a DEFAULT_EVENT_IMAGE or a safe placeholder URL) and removes or clears
the handler to avoid infinite loops; ensure you reference eventImages and
eventImageIndex in the handler so the fallback only applies to this renderer.
In `@app/member-network/page.tsx`:
- Around line 27-45: The code assumes the API response in fetchLogos is an array
and directly calls setLogos(data), which will make logos.reduce crash if the
payload is malformed; update fetchLogos to validate the payload before calling
setLogos by checking Array.isArray(data) (and optionally that each item matches
the expected NetworkLogo shape: has id/name/url/category) and if invalid log a
warning and call setLogos([]) or filter to a safe array; ensure the rest of the
component (grouped, logos.reduce) operates on this validated array so reduce
cannot throw.
---
Duplicate comments:
In `@app/api/network-logos/route.ts`:
- Around line 22-26: The URL concatenation can produce double slashes when
logo.signedPath or logo.path begins with a leading slash; update the logic that
builds logoUrl (the branches checking logo.signedPath and logo.path which append
to NOCODB_BASE_URL) to normalize the attachment path first—strip any leading
slashes (or use a URL/path-join helper) before joining with NOCODB_BASE_URL so
the resulting logoUrl is never formed with "//" between base and path; leave the
logo.url branch unchanged.
In `@app/globals.css`:
- Around line 106-114: The keyframe name dashFlow violates the kebab-case rule;
rename the keyframe to a kebab-case identifier (e.g., dash-flow) and update the
.mindmap-line animation property to use the new name so both the `@keyframes` rule
and the animation reference match (update the `@keyframes` declaration and the
animation: dashFlow → animation: dash-flow in the .mindmap-line rule).
In `@app/member-journey/page.tsx`:
- Around line 559-564: The mobile department cards rendered in the
departments.map loop (the element with className "lg:hidden space-y-4" and each
card div with className "relative bg-white/5 border border-white/10
overflow-hidden") lack inner padding; update the card wrapper (the mapped div
with key={dept.id}) to include responsive padding classes (for example add "px-4
py-3" or "p-4 sm:p-6 lg:p-0") so that on small screens the content has
consistent spacing while preserving existing lg behavior.
---
Nitpick comments:
In `@app/member-network/page.tsx`:
- Around line 10-15: The interface NetworkLogo is duplicated between client and
API; extract NetworkLogo into a single shared types module, export it, then
replace the local interface declaration with an import of NetworkLogo in both
the client code (where it currently appears) and the API route that uses the
same shape; ensure the shared module is exported correctly and update any
imports/usages to reference the shared NetworkLogo type to prevent drift.
🪄 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: 5b069433-9c81-4e7d-93f2-9722cb99e125
⛔ Files ignored due to path filters (11)
public/Builder_Weekend.jpgis excluded by!**/*.jpgpublic/cta-left.svgis excluded by!**/*.svgpublic/cta-right.svgis excluded by!**/*.svgpublic/member-journey-hero.jpgis excluded by!**/*.jpgpublic/member-startup-visit.jpgis excluded by!**/*.jpgpublic/member-workshops.pngis excluded by!**/*.pngpublic/monthly-event.jpgis excluded by!**/*.jpgpublic/more-dsc04524.jpgis excluded by!**/*.jpgpublic/more-img4955.jpgis excluded by!**/*.jpgpublic/more-isar-unfiltered.jpgis excluded by!**/*.jpgpublic/more-workshops.pngis excluded by!**/*.png
📒 Files selected for processing (11)
app/api/network-logos/route.tsapp/apply/page.tsxapp/globals.cssapp/join-start/2026/page.tsxapp/member-journey/page.tsxapp/member-network/page.tsxapp/members/page.tsxapp/startups/page.tsxcomponents/Navigation.tsxpublic/cambridge-aerial.webptsconfig.tsbuildinfo
✅ Files skipped from review due to trivial changes (5)
- app/join-start/2026/page.tsx
- components/Navigation.tsx
- app/members/page.tsx
- app/apply/page.tsx
- tsconfig.tsbuildinfo
| const response = await fetch( | ||
| `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`, | ||
| { | ||
| headers: { | ||
| 'xc-token': NOCODB_API_TOKEN, | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| cache: 'no-store', | ||
| } | ||
| ); |
There was a problem hiding this comment.
Add a timeout to the NocoDB fetch to prevent hanging requests.
The current external call has no abort path. If NocoDB stalls, this route can hang until platform-level timeout.
⏱️ Proposed fix
- const response = await fetch(
- `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`,
- {
- headers: {
- 'xc-token': NOCODB_API_TOKEN,
- 'Content-Type': 'application/json',
- },
- cache: 'no-store',
- }
- );
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 8000);
+ const response = await fetch(
+ `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`,
+ {
+ headers: {
+ 'xc-token': NOCODB_API_TOKEN,
+ 'Content-Type': 'application/json',
+ },
+ cache: 'no-store',
+ signal: controller.signal,
+ }
+ );
+ clearTimeout(timeout);📝 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 response = await fetch( | |
| `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`, | |
| { | |
| headers: { | |
| 'xc-token': NOCODB_API_TOKEN, | |
| 'Content-Type': 'application/json', | |
| }, | |
| cache: 'no-store', | |
| } | |
| ); | |
| const controller = new AbortController(); | |
| const timeout = setTimeout(() => controller.abort(), 8000); | |
| const response = await fetch( | |
| `${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_NETWORK_LOGOS_TABLE_ID}/records?limit=1000&offset=0`, | |
| { | |
| headers: { | |
| 'xc-token': NOCODB_API_TOKEN, | |
| 'Content-Type': 'application/json', | |
| }, | |
| cache: 'no-store', | |
| signal: controller.signal, | |
| } | |
| ); | |
| clearTimeout(timeout); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/api/network-logos/route.ts` around lines 55 - 64, The NocoDB fetch call
(the request built with NOCODB_BASE_URL, NOCODB_NETWORK_LOGOS_TABLE_ID and
NOCODB_API_TOKEN) lacks an abort/timeout and can hang; add an AbortController,
pass its signal into the fetch options, start a timer (e.g., using setTimeout)
that calls controller.abort() after a reasonable timeout (e.g., 5–10s), and
clear the timer when the fetch completes; ensure you catch the abort error and
handle it (return a 504 or appropriate error) so the route handler does not
hang.
| const data = await res.json() | ||
| setLogos(data) | ||
| } catch (err) { | ||
| console.error("Error fetching network logos:", err) | ||
| setError("Failed to load network logos") | ||
| } finally { | ||
| setLoading(false) | ||
| } | ||
| } | ||
| fetchLogos() | ||
| }, []) | ||
|
|
||
| // Group by Type | ||
| const categories = Array.from(new Set(companies.map(c => c.type))) | ||
| .sort((a, b) => companies.filter(c => c.type === b).length - companies.filter(c => c.type === a).length) | ||
|
|
||
| if (loading) { | ||
| return ( | ||
| <main className="min-h-screen bg-[#00002c] py-12 px-4 sm:px-6 lg:px-8"> | ||
| <div className="max-w-7xl mx-auto text-center"> | ||
| <p className="text-2xl font-bold text-white">Loading member network...</p> | ||
| </div> | ||
| </main> | ||
| ) | ||
| } | ||
| // Group logos by category | ||
| const grouped = logos.reduce<Record<string, NetworkLogo[]>>((acc, logo) => { | ||
| const cat = logo.category || "Other" | ||
| if (!acc[cat]) acc[cat] = [] | ||
| acc[cat].push(logo) | ||
| return acc | ||
| }, {}) |
There was a problem hiding this comment.
Validate API payload shape before storing state.
Line 28 trusts res.json() as an array, but Line 40 requires an array (reduce). A malformed 200-response will crash rendering.
🛡️ Proposed fix
- const data = await res.json()
- setLogos(data)
+ const data: unknown = await res.json()
+ if (!Array.isArray(data)) {
+ throw new Error("Invalid network logos payload")
+ }
+ setLogos(data as NetworkLogo[])📝 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 data = await res.json() | |
| setLogos(data) | |
| } catch (err) { | |
| console.error("Error fetching network logos:", err) | |
| setError("Failed to load network logos") | |
| } finally { | |
| setLoading(false) | |
| } | |
| } | |
| fetchLogos() | |
| }, []) | |
| // Group by Type | |
| const categories = Array.from(new Set(companies.map(c => c.type))) | |
| .sort((a, b) => companies.filter(c => c.type === b).length - companies.filter(c => c.type === a).length) | |
| if (loading) { | |
| return ( | |
| <main className="min-h-screen bg-[#00002c] py-12 px-4 sm:px-6 lg:px-8"> | |
| <div className="max-w-7xl mx-auto text-center"> | |
| <p className="text-2xl font-bold text-white">Loading member network...</p> | |
| </div> | |
| </main> | |
| ) | |
| } | |
| // Group logos by category | |
| const grouped = logos.reduce<Record<string, NetworkLogo[]>>((acc, logo) => { | |
| const cat = logo.category || "Other" | |
| if (!acc[cat]) acc[cat] = [] | |
| acc[cat].push(logo) | |
| return acc | |
| }, {}) | |
| const data: unknown = await res.json() | |
| if (!Array.isArray(data)) { | |
| throw new Error("Invalid network logos payload") | |
| } | |
| setLogos(data as NetworkLogo[]) | |
| } catch (err) { | |
| console.error("Error fetching network logos:", err) | |
| setError("Failed to load network logos") | |
| } finally { | |
| setLoading(false) | |
| } | |
| } | |
| fetchLogos() | |
| }, []) | |
| // Group logos by category | |
| const grouped = logos.reduce<Record<string, NetworkLogo[]>>((acc, logo) => { | |
| const cat = logo.category || "Other" | |
| if (!acc[cat]) acc[cat] = [] | |
| acc[cat].push(logo) | |
| return acc | |
| }, {}) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/member-network/page.tsx` around lines 27 - 45, The code assumes the API
response in fetchLogos is an array and directly calls setLogos(data), which will
make logos.reduce crash if the payload is malformed; update fetchLogos to
validate the payload before calling setLogos by checking Array.isArray(data)
(and optionally that each item matches the expected NetworkLogo shape: has
id/name/url/category) and if invalid log a warning and call setLogos([]) or
filter to a safe array; ensure the rest of the component (grouped, logos.reduce)
operates on this validated array so reduce cannot throw.
Summary by CodeRabbit
New Features
UI/UX
Style
Chores