Skip to content

feat(frontend): add reusable executive info cards#68

Open
HaydenLawNZ wants to merge 4 commits into
mainfrom
feat/exec-info-card
Open

feat(frontend): add reusable executive info cards#68
HaydenLawNZ wants to merge 4 commits into
mainfrom
feat/exec-info-card

Conversation

@HaydenLawNZ
Copy link
Copy Markdown
Contributor

Description

Implements a reusable executive member info card for the About page.

This PR:

  • adds a reusable ExecCard component
  • adds the required executive fields in Payload (degree, position, yearsOfExperience, and photo)
  • renders executive cards from CMS data on a temporary /executives page for testing
  • handles missing fields gracefully.

Closes #59

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Manual testing (requires screenshots or videos)
Screenshot 2026-05-18 at 2 10 52 AM Screenshot 2026-05-18 at 2 10 05 AM Screenshot 2026-05-18 at 2 06 02 AM Screenshot 2026-05-18 at 2 07 49 AM

Tested:

  • populated with multiple cards
  • single-card state
  • empty state
  • missing photo placeholder
  • missing fields
  • long and short content

Checklist before requesting a review

  • My code follows the style guidelines of this project
  • I have commented my code in hard-to-understand areas
  • I have made corresponding changes to the documentation if needed
  • I've requested a review from another team member

@ashoomky ashoomky self-requested a review May 19, 2026 02:26
Copy link
Copy Markdown
Collaborator

@ashoomky ashoomky left a comment

Choose a reason for hiding this comment

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

Great work Hayden! Just some minor things to fix up:

Two font fixes needed: both the role label and name <h3> use font-heading (Staatliches) but Figma specifies Inter, so make sure to swap both to font-body with the correct weight. While you're on the role label, change break-all to break-words to fix the mid-word splitting.
Also either add a bio prop and render it, or remove the field from the schema, as right now it collects data that goes nowhere. The string branch in the photo type can also be dropped since depth is always ≥ 1 on fetch.

For the executives/page.tsx, delete the ExecutiveCardData type and import Executive from @/payload-types instead, as it's already generated from the schema and won't drift when fields change.

Lastly, for proper conventions make sure to create a ExecCard folder, and put the ExecCard.tsx file in that folder. Refer to Navbar for example.

Comment thread src/app/(frontend)/executives/page.tsx Outdated
Comment on lines +6 to +20
type ExecutiveCardData = {
id: string
role: string
name: string
degree?: string | null
position?: string | null
yearsOfExperience?: number | null
photo?:
| {
url?: string | null
alt?: string | null
}
| string
| null
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This type already exists as Executive in payload-types.ts. Payload generates it automatically from the collection schema. If a field is added or changed in the schema, payload-types.ts updates but this type will silently drift. Delete this block and import Executive from @/payload-types instead.

Comment thread src/app/(frontend)/executives/page.tsx Outdated
limit: 100,
})

const executives = result.docs as ExecutiveCardData[]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change to result.docs as Executive[] once the manual type above is removed

Comment thread src/components/ExecCard.tsx Outdated
Comment on lines +9 to +16
photo?:
| {
url?: string | null
alt?: string | null
}
| string
| null
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The string branch here will never be hit in practice. Payload always returns a populated media object or null for an upload field, never a raw URL string. The union adds complexity without benefit, so to fix this simplify to { url?: string | null; alt?: string | null } | null.

Comment thread src/components/ExecCard.tsx Outdated

return (
<article className="mx-auto flex w-full max-w-[220px] flex-col items-center text-center">
<p className="mb-3 max-w-full break-all text-center font-heading text-[#7FA6D8] text-sm uppercase tracking-wide sm:text-base">
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two issues here: break-all splits at any character boundary which causes the ugly mid-word wrapping seen in testing (where you had BBBBBBB). Change to break-words.

Also the font for people's names and their roles, should be font Inter as per Figma, right now it's Staatliches. Fix this please!

Comment thread src/components/ExecCard.tsx Outdated
)}
</div>

<h3 className="mb-2 font-heading text-brand-primary text-lg uppercase leading-tight sm:text-xl">
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same font issue as the role label, font-heading resolves to Staatliches but Figma uses Inter here. Change to font-body font-bold (or whichever weight the spec calls for).

Comment on lines +50 to +60
{degree ? (
<p className="font-body text-brand-primary text-sm leading-snug">{degree}</p>
) : null}
{position ? (
<p className="font-body text-brand-navy text-sm leading-snug">{position}</p>
) : null}
{typeof yearsOfExperience === "number" ? (
<p className="font-body text-brand-navy text-sm leading-snug">
{yearsOfExperience} years exp.
</p>
) : null}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The Executives collection defines a bio field but it's not in ExecCardProps and isn't rendered here, so anything entered in the CMS for bio is silently discarded. Either add a bio?: string | null prop and render it, or remove the field from the collection config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FRONTEND] Create Exec member info cards for About -> Exec team

2 participants