Skip to content

[#336] Blade/alumni dashboard#406

Merged
DVidal1205 merged 7 commits intomainfrom
blade/alumni-dashboard
Mar 8, 2026
Merged

[#336] Blade/alumni dashboard#406
DVidal1205 merged 7 commits intomainfrom
blade/alumni-dashboard

Conversation

@aidenletourneau
Copy link
Copy Markdown
Contributor

@aidenletourneau aidenletourneau commented Mar 8, 2026

Why

We needed an updated alumni dashboard with new donation options and stats

What

Closes: #336

  • updated donation card with links to multiple tiers of alumni donations
  • new daily image card
  • new knighthacks recap card

Test Plan

Tested ui on mobile and large devices. Tested stripe links.

Checklist

  • Database: No schema changes, OR I have contacted the Development Lead to run db:push before merging
  • Environment Variables: No environment variables changed, OR I have contacted the Development Lead to modify them on Coolify BEFORE merging.

Summary by CodeRabbit

  • New Features

    • Dedicated alumni dashboard with member recap (class year, tenure, events/hackathons, lifetime points)
    • Daily "Day in History" alumni photo with captions
    • Early access volunteer opportunities section listing available forms
  • Improvements

    • Redesigned donation experience with multiple tiers, checkout links, and a details modal
    • Unified member dashboard header, consistent payment/points display, and alumni-specific layout/components

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 8, 2026

📝 Walkthrough

Walkthrough

Adds an alumni-specific dashboard path and three new alumni UI components; fetches past hackathons for alumni; refactors the donation UI into tiered options with a details modal; standardizes dashboard header and consolidates payment/points rendering. (49 words)

Changes

Cohort / File(s) Summary
Alumni UI Components
apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx, apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx, apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx
Added AlumniRecap (computes class year, tenure, event/hackathon aggregates, optional board position), DayInHistory (daily alumni photo selector and display), and EarlyAccessVolunteer (TRPC query for "Alumni" forms and renders form links).
Member Dashboard Logic
apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx
Introduced early isAlumni branching, conditionally fetches hackathons for alumni, includes hackathons in error handling and AlumniRecap props, standardized header text, and unified Payment/Points rendering; added dedicated AlumniDashboard layout composition.
Donation UI Refactor
apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx
Replaced single donate action with a DONATION_OPTIONS array, added DonationDetailsModal and grid of donation option cards; removed previous hover/heart UI and updated icons/imports and layout.
Misc (declarations)
apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx
Exports new AlumniRecap component signature: export function AlumniRecap(...).

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Dashboard as MemberDashboard
    participant Fetcher as DataFetcher
    participant AlumniView as AlumniDashboard
    participant NonAlumniView as NonAlumniDashboard
    participant Recap as AlumniRecap

    User->>Dashboard: Request dashboard
    Dashboard->>Dashboard: Determine isAlumni from member.gradDate
    Dashboard->>Fetcher: Fetch events, dues
    alt isAlumni
        Dashboard->>Fetcher: Fetch past hackathons
        Fetcher-->>Dashboard: Return events, dues, hackathons
        Dashboard->>AlumniView: Render alumni layout
        AlumniView->>Recap: Provide member, events, hackathons, boardPosition
        Recap->>Recap: Compute class year, tenure, counts, most active year
        AlumniView-->>User: Display alumni dashboard (Discord, EarlyAccessVolunteer, MemberInfo, Donate, DayInHistory, AlumniRecap)
    else not alumni
        Fetcher-->>Dashboard: Return events, dues
        Dashboard->>NonAlumniView: Render standard layout
        NonAlumniView-->>User: Display member dashboard (Payment, Points, EventNumber)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • DVidal1205
🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title '[#336] Blade/alumni dashboard' starts with issue number [#336], follows the required format, and clearly describes the main change (alumni dashboard implementation).
Linked Issues check ✅ Passed All code changes fully implement the objectives from issue #336: donation card with Stripe links, daily image card, and KnightHacks recap card are present and integrated into the alumni dashboard.
Out of Scope Changes check ✅ Passed All changes are directly related to the alumni dashboard implementation. File modifications focus on new alumni-specific components and member dashboard integration without unrelated alterations.
No Hardcoded Secrets ✅ Passed All modified files scanned for hardcoded secrets. Only public Stripe checkout URLs found, which are intentionally frontend-facing. No API keys, tokens, or sensitive credentials present.
Validated Env Access ✅ Passed All affected files properly use validated imports from configuration modules instead of direct process.env access, adhering to codebase conventions.
No Typescript Escape Hatches ✅ Passed No TypeScript escape hatches (any, @ts-ignore, @ts-expect-error, non-null assertions) detected in codebase search.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch blade/alumni-dashboard

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aidenletourneau aidenletourneau self-assigned this Mar 8, 2026
@aidenletourneau aidenletourneau added Feature New Feature or Request Blade Change modifies code in Blade app UI Changes modifies code in the global UI package labels Mar 8, 2026
@aidenletourneau aidenletourneau marked this pull request as ready for review March 8, 2026 15:41
@aidenletourneau aidenletourneau added Onboarding Good first issue for onboarding Developers Help Wanted Needs assignment from a Developer Minor Small change - 1 reviewer required labels Mar 8, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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)
apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx (1)

29-63: ⚠️ Potential issue | 🟠 Major

Compare full graduation dates here, not just years.

This keeps some graduates in the member flow after they should flip to alumni. For example, a member with gradDate = 2026-05-01 still returns false on October 1, 2026 because yearsUntilGrad is 0, and the graduate/Post Doctorate branch never flips at all. Reuse an actual hasGraduated check for those branches.

Suggested fix
   const currentDate = new Date();
+  const hasGraduated = gradDateObj < currentDate;
 
   // Check if dates are valid
   if (isNaN(gradDateObj.getTime())) return false;
@@
   if (
     member.levelOfStudy ===
       "Graduate University (Masters, Professional, Doctoral, etc)" ||
     member.levelOfStudy === "Post Doctorate"
   ) {
-    return false;
+    return hasGraduated;
   }
 
-  // If graduation date has passed, they are alumni
-  if (yearsUntilGrad < 0) return true;
-
-  // Current year graduates are still seniors until they actually graduate
-  return false;
+  return hasGraduated;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx`
around lines 29 - 63, calcAlumniStatus currently compares only years; change it
to compare full dates: first parse gradDate into gradDateObj and compute
hasGraduated = gradDateObj.getTime() <= currentDate.getTime() (and return false
if gradDateObj is invalid). For the "Less than Secondary / High School" and
"Secondary / High School" branches, replace the yearsUntilGrad check with a
comparison to a cutoffDate 4 years before today (e.g.
cutoffDate.setFullYear(currentYear - 4)) and return true if gradDateObj <=
cutoffDate. For the graduate/Post Doctorate branch (member.levelOfStudy ===
"Graduate University..." or "Post Doctorate") return true only when hasGraduated
is true (otherwise false). Finally, the general fall-through should return
hasGraduated (true if gradDateObj is in the past, false otherwise). Use the
function name calcAlumniStatus and member.levelOfStudy to locate the changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx`:
- Around line 47-70: getMostActiveYear currently counts both events and
hackathons but returns a label that says "event(s)"; update the returned string
in getMostActiveYear to use a neutral term like "activity/activities" (or
"activity(ies)") instead of "event(s)" so the summary accurately reflects
combined events and hackathons — locate the template literal in
getMostActiveYear that builds `${bestYear} (${bestCount} event${...})` and
change the word "event" to "activity" and adjust pluralization accordingly.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx`:
- Around line 19-22: The current dailyImage selection uses Math.random so it
changes on every render; replace that with a deterministic index derived from
the current date (e.g., use a date string or numeric combination of
getFullYear/getMonth/getDate, or a small hash of new
Date().toISOString().slice(0,10)) and compute index = dateValue %
ALUMNI_PHOTOS.length, then pick ALUMNI_PHOTOS[index] for dailyImage; update the
code that defines dailyImage to remove Math.random and use this date-derived
index so the same image is shown for the entire day.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx`:
- Around line 99-103: The "Donate" links are not uniquely announced; update the
modal checkout link rendered with Button (asChild) and Link so each has a
distinct accessible name by including the tier/amount in the visible text or an
aria-label derived from the option object (e.g., use o.label or o.amount).
Locate the link generation that uses Link href={o.href} and change the Link
content or add aria-label={`Donate — ${o.label} (${o.amount})`} (or similar) so
screen readers announce the specific tier/amount for each Donate action.

---

Outside diff comments:
In
`@apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx`:
- Around line 29-63: calcAlumniStatus currently compares only years; change it
to compare full dates: first parse gradDate into gradDateObj and compute
hasGraduated = gradDateObj.getTime() <= currentDate.getTime() (and return false
if gradDateObj is invalid). For the "Less than Secondary / High School" and
"Secondary / High School" branches, replace the yearsUntilGrad check with a
comparison to a cutoffDate 4 years before today (e.g.
cutoffDate.setFullYear(currentYear - 4)) and return true if gradDateObj <=
cutoffDate. For the graduate/Post Doctorate branch (member.levelOfStudy ===
"Graduate University..." or "Post Doctorate") return true only when hasGraduated
is true (otherwise false). Finally, the general fall-through should return
hasGraduated (true if gradDateObj is in the past, false otherwise). Use the
function name calcAlumniStatus and member.levelOfStudy to locate the changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: f281f832-4516-4358-bce4-1191aad14920

📥 Commits

Reviewing files that changed from the base of the PR and between 5b03b4d and a0d5bb8.

⛔ Files ignored due to path filters (7)
  • apps/blade/public/alumni-recap/2019-crowd.jpg is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/DSC_0125.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_4699.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_6763.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_8131.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/KnightHacks.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/ThankYouAllForAttendingYouAllMeanTheWorldToUs.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx

Comment thread apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx (1)

29-56: Consider handling "I'm not currently a student" explicitly.

The calcAlumniStatus function handles 4 of 11 education levels explicitly and falls through to hasGraduated for the rest. This means someone who selected "I'm not currently a student" with any past graduation date would be marked as alumni.

Per the schema in packages/consts/src/forms/index.ts, other unhandled levels include:

  • "I'm not currently a student"
  • "Code School / Bootcamp"
  • "Undergraduate University (2 year...)" and "(3+ year)"

If this fallthrough behavior is intentional, a brief comment explaining the logic would help future maintainers.

🔧 Optional: Add comment clarifying intent
   if (
     member.levelOfStudy ===
       "Graduate University (Masters, Professional, Doctoral, etc)" ||
     member.levelOfStudy === "Post Doctorate"
   ) {
     return hasGraduated;
   }

+  // All other education levels (undergraduate, bootcamp, vocational, etc.)
+  // are considered alumni if their graduation date has passed
   return hasGraduated;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx`
around lines 29 - 56, The calcAlumniStatus function currently falls through to
hasGraduated for unhandled levelOfStudy values; explicitly handle the "I'm not
currently a student" option by detecting member.levelOfStudy === "I'm not
currently a student" and return false (not alumni), and either also add explicit
branches or a clarifying comment for other levels like "Code School / Bootcamp"
and the two "Undergraduate University" variants to document intended fallthrough
behavior; update the calcAlumniStatus function (and its levelOfStudy checks)
accordingly so the logic is explicit for "I'm not currently a student" and
maintainers see the rationale.
apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx (1)

25-56: Stripe payment links are functional and safe to hardcode. All four links return HTTP 200, confirming they work as expected. Since these are public Stripe checkout URLs (not API keys or secrets), hardcoding them complies with the codebase guidelines. If donation URLs differ across environments (dev/staging/prod), consider moving them to environment variables for easier management—this is optional but helps with environment-specific configuration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx`
around lines 25 - 56, The hardcoded Stripe checkout URLs in DONATION_OPTIONS
should either remain as-is (they are public and safe) or be made
environment-configurable; update the DONATION_OPTIONS initializer in donate.tsx
to source each option.href from environment variables (e.g.,
NEXT_PUBLIC_STRIPE_SUPPORTER_URL, NEXT_PUBLIC_STRIPE_CONTRIBUTOR_URL,
NEXT_PUBLIC_STRIPE_PARTNER_URL, NEXT_PUBLIC_STRIPE_CUSTOM_URL) with the current
hardcoded URL as the fallback, so the app supports differing dev/staging/prod
links while keeping the existing values if env vars are not provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx`:
- Around line 29-56: The calcAlumniStatus function currently falls through to
hasGraduated for unhandled levelOfStudy values; explicitly handle the "I'm not
currently a student" option by detecting member.levelOfStudy === "I'm not
currently a student" and return false (not alumni), and either also add explicit
branches or a clarifying comment for other levels like "Code School / Bootcamp"
and the two "Undergraduate University" variants to document intended fallthrough
behavior; update the calcAlumniStatus function (and its levelOfStudy checks)
accordingly so the logic is explicit for "I'm not currently a student" and
maintainers see the rationale.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx`:
- Around line 25-56: The hardcoded Stripe checkout URLs in DONATION_OPTIONS
should either remain as-is (they are public and safe) or be made
environment-configurable; update the DONATION_OPTIONS initializer in donate.tsx
to source each option.href from environment variables (e.g.,
NEXT_PUBLIC_STRIPE_SUPPORTER_URL, NEXT_PUBLIC_STRIPE_CONTRIBUTOR_URL,
NEXT_PUBLIC_STRIPE_PARTNER_URL, NEXT_PUBLIC_STRIPE_CUSTOM_URL) with the current
hardcoded URL as the fallback, so the app supports differing dev/staging/prod
links while keeping the existing values if env vars are not provided.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 1f3dd851-a3c2-4225-a2f8-07ff20c29a2e

📥 Commits

Reviewing files that changed from the base of the PR and between a0d5bb8 and 27cfd61.

📒 Files selected for processing (4)
  • apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx

@aidenletourneau aidenletourneau force-pushed the blade/alumni-dashboard branch from 27cfd61 to c9d2d53 Compare March 8, 2026 21:58
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx (1)

130-154: Consider adding aria-label to the grid donation buttons for accessibility parity.

The modal links have aria-label={...} (line 102), but the main grid buttons only show {opt.priceLabel} and {opt.name} as visible text. Screen readers will announce both spans, which may suffice—but for consistency with the modal and to explicitly label the action, consider adding an aria-label here too.

♿ Optional: add aria-label for parity
             <Button
               key={opt.name}
               asChild
               variant="outline"
               className="flex min-h-[88px] w-full flex-col items-center justify-center text-center transition-all hover:-translate-y-0.5 hover:shadow-md"
             >
               <Link
                 href={opt.href}
                 target="_blank"
                 rel="noopener noreferrer"
+                aria-label={`Donate — ${opt.name} (${opt.priceLabel})`}
                 className="flex w-full min-w-0 flex-col items-center justify-center text-center"
               >

As per coding guidelines, apps/blade/**: "Accessibility (alt text, ARIA, semantic HTML)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx`
around lines 130 - 154, The donation grid buttons rendered in the
DONATION_OPTIONS.map lack an explicit aria-label for screen readers; add an
aria-label to the interactive element (the Link or the surrounding Button) using
the option data (e.g., combine opt.priceLabel and opt.name into a single
descriptive string like "Donate {opt.name} — {opt.priceLabel}") so it matches
the modal links' accessibility behavior and ensures consistent announcement by
assistive technologies; update the Link/Button in the map to include
aria-label={...} accordingly.
apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx (1)

47-59: Links to forms lack accessible names describing the destination.

Each button links to /forms/${f.slugName}, but screen readers only hear the formatted slug. Consider adding context about the action (e.g., "Fill out [Form Name]").

♿ Optional: improve link accessibility
                 <Button
                   key={f.slugName}
                   asChild
                   variant="outline"
                   className="h-auto w-full justify-between py-3"
                 >
-                  <Link href={`/forms/${f.slugName}`} className="min-w-0">
+                  <Link
+                    href={`/forms/${f.slugName}`}
+                    className="min-w-0"
+                    aria-label={`Fill out ${f.slugName.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" ")} form`}
+                  >

As per coding guidelines, apps/blade/**: "Accessibility (alt text, ARIA, semantic HTML)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx`
around lines 47 - 59, The link text currently renders the formatted slug from
f.slugName but lacks an accessible name describing the action; update the Link
(and its inner content) to include a descriptive accessible label such as
aria-label={`Fill out ${formattedName} form`} or add a visually hidden element
with the text "Fill out [Form Name]" alongside the displayed slug (use the same
formattedName computed from f.slugName). Ensure the aria-label or sr-only text
uses the same capitalization logic (the existing .split("-").map(...).join(" "))
so screen readers announce "Fill out [Form Name]" while visual output remains
unchanged.
apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx (1)

94-116: Hardcoded officer list will require manual updates each term.

Adrian, Carlos, Jason, and Nat are hardcoded. When leadership changes, this file needs a code change and redeploy. Consider fetching officers dynamically or extracting to a config file that non-developers can update.

Would you like me to open an issue to track making the officers list dynamic or configurable?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx`
around lines 94 - 116, The AlumniRecap component currently renders a hardcoded
officers list (Adrian, Carlos, Jason, Nat); change it to render dynamically by
sourcing data instead of static JSX: add an officers prop or a data fetch (e.g.,
getOfficers / useEffect or pass in an imported config) and replace the four
hardcoded <li> entries with a map over officers (use unique keys and render
officer.name and officer.role), and ensure AlumniRecap and its callers are
updated to provide the officers array or the fetching mechanism so future
leadership changes don’t require code edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx`:
- Around line 33-45: The getYearsAsMember function can return negative values
when dateCreated is in the future; after computing years and the anniversary
adjustment (the local variables years and hasAnniversaryPassed inside
getYearsAsMember), clamp the final computed value to a minimum of 0 before
returning it (e.g., compute adjustedYears = hasAnniversaryPassed ? years : years
- 1; if adjustedYears < 0 return 0 else return adjustedYears) so the function
never returns negatives even with future dates.
- Around line 73-78: The AlumniRecap component declares a boardPosition?: string
| null prop in AlumniRecapProps but it is never passed, so the "Board History"
section in AlumniRecap will never render; either remove boardPosition from
AlumniRecapProps and delete the Board History rendering in the AlumniRecap
function (and clean up any JSX referencing boardPosition), or add boardPosition
to the Member data model and populate it at every call site that renders
<AlumniRecap> (or derive it from your Board/Position table) so AlumniRecap
receives a real value; update the AlumniRecap signature and all callers
accordingly and ensure types and tests reflect the chosen approach.

---

Nitpick comments:
In `@apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx`:
- Around line 94-116: The AlumniRecap component currently renders a hardcoded
officers list (Adrian, Carlos, Jason, Nat); change it to render dynamically by
sourcing data instead of static JSX: add an officers prop or a data fetch (e.g.,
getOfficers / useEffect or pass in an imported config) and replace the four
hardcoded <li> entries with a map over officers (use unique keys and render
officer.name and officer.role), and ensure AlumniRecap and its callers are
updated to provide the officers array or the fetching mechanism so future
leadership changes don’t require code edits.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx`:
- Around line 47-59: The link text currently renders the formatted slug from
f.slugName but lacks an accessible name describing the action; update the Link
(and its inner content) to include a descriptive accessible label such as
aria-label={`Fill out ${formattedName} form`} or add a visually hidden element
with the text "Fill out [Form Name]" alongside the displayed slug (use the same
formattedName computed from f.slugName). Ensure the aria-label or sr-only text
uses the same capitalization logic (the existing .split("-").map(...).join(" "))
so screen readers announce "Fill out [Form Name]" while visual output remains
unchanged.

In
`@apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx`:
- Around line 130-154: The donation grid buttons rendered in the
DONATION_OPTIONS.map lack an explicit aria-label for screen readers; add an
aria-label to the interactive element (the Link or the surrounding Button) using
the option data (e.g., combine opt.priceLabel and opt.name into a single
descriptive string like "Donate {opt.name} — {opt.priceLabel}") so it matches
the modal links' accessibility behavior and ensures consistent announcement by
assistive technologies; update the Link/Button in the map to include
aria-label={...} accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: bbd63f66-9c4f-4d44-9407-18eb4aa110a9

📥 Commits

Reviewing files that changed from the base of the PR and between 27cfd61 and c9d2d53.

⛔ Files ignored due to path filters (7)
  • apps/blade/public/alumni-recap/2019-crowd.jpg is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/DSC_0125.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_4699.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_6763.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/IMG_8131.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/KnightHacks.JPG is excluded by !**/*.jpg
  • apps/blade/public/alumni-recap/ThankYouAllForAttendingYouAllMeanTheWorldToUs.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • apps/blade/src/app/_components/dashboard/member-dashboard/AlumniRecap.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/early-access-volunteer.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/member-dashboard.tsx
  • apps/blade/src/app/_components/dashboard/member-dashboard/payment/donate.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/blade/src/app/_components/dashboard/member-dashboard/day-in-history.tsx

Copy link
Copy Markdown
Contributor

@DVidal1205 DVidal1205 left a comment

Choose a reason for hiding this comment

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

lgtm

@DVidal1205 DVidal1205 added this pull request to the merge queue Mar 8, 2026
Merged via the queue into main with commit ae02f81 Mar 8, 2026
8 checks passed
@DVidal1205 DVidal1205 deleted the blade/alumni-dashboard branch March 8, 2026 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blade Change modifies code in Blade app Feature New Feature or Request Help Wanted Needs assignment from a Developer Minor Small change - 1 reviewer required Onboarding Good first issue for onboarding Developers UI Changes modifies code in the global UI package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blade Alumni Dashboard

3 participants