Skip to content

feat(volunteer): list open roles from the Hub in place of the Notion button - #540

Open
mohanadft wants to merge 1 commit into
mainfrom
feat/volunteer-open-roles
Open

feat(volunteer): list open roles from the Hub in place of the Notion button#540
mohanadft wants to merge 1 commit into
mainfrom
feat/volunteer-open-roles

Conversation

@mohanadft

Copy link
Copy Markdown
Collaborator

What

The Current Volunteer Needs button on /volunteer and /volunteer-new pointed at a Notion board. This replaces it with a filterable list of the live open roles from the Hub's public API (hub.techforpalestine.org/api/public/open-roles — 20 roles at time of writing).

How

/api/open-roles — server proxy following the /api/projects pattern. One retry on 5xx for cold starts (4xx returns immediately), tolerates a bare array or a {data}/{roles} envelope, no-store, ACAO: * (read-only GET over public data). Client gets a generic { error }; details go to console.error + Sentry via reportError. No secret needed — the upstream endpoint is public.

openRoleData.ts — normalizes upstream rows at the boundary: flattens project.name/team.name into a single orgName, coerces and length-caps every string, drops rows missing id/title, sorts newest-first. A shape change upstream now fails in one place.

OpenRoles.tsx / OpenRoleCard.tsx — client island (client:only="react"), fetched from /api/open-roles so a Hub outage never blocks the page render.

Design notes

  • Single-column bands, not a card grid. Expanding a long description in a grid reflows its siblings; a stacked list just pushes content down, and it gives the descriptions a sane reading measure.
  • Two skins, one structure. The pages use different design systems — /volunteer is Layout.astro (indigo/green, white cards, system font) and /volunteer-new is HomeLayout.astro (cream/sand/butter + rose #AB4956, Fraunces/Outfit via the ts-* scale, which only that layout loads). The island takes a skin prop that maps to the host page's tokens rather than introducing a third identity.
  • Surfaces on /volunteer-new follow projects-new.astro: the section sits on bg-page with an h-px bg-ink-divider rule closing the hero. Putting it on bg-sand broke the page's page/sand alternation for every section below it and put sand cards on a sand ground.
  • Collapsed previews flatten whitespace, expanded text keeps whitespace-pre-line. Several descriptions open with a short heading line that would otherwise spend the whole three-line clamp.
  • Apply target follows how the role is staffed: type === "team"/membership ("Become a member", matching that page's own title); otherwise the volunteer form ("Apply to volunteer", matching the existing CTA). The label carries the distinction, not just colour, and team roles also get a bordered "T4P team" marker.
  • Filters cap at the 8 most common skills with the tail behind a toggle — 15 categories with labels like "Graphic Design / Illustration", 9 of them holding a single role, would have outweighed the list itself. The active filter stays visible even when it's in the tail.
  • Motion is limited to the disclosure chevron; hover is a border/background shift, matching ProjectCard. Skeletons carry motion-reduce:animate-none.
  • A11y: chips are aria-pressed buttons, the disclosure is aria-expanded/aria-controls, the result count is an aria-live="polite" region, targets are ≥44px, and each apply link carries an sr-only role name so 20 otherwise-identical links read distinctly.

Also in this change

The in-prose "Check out specific roles we're looking for right now!" link on both pages is repointed at #open-roles. Left alone, it would have kept the replaced Notion board linked from the page.

Known upstream quirks (not worked around)

  • project.id is null on every row, so cards can't deep-link to a project page.
  • One title reads Fact Checke; rendered as-is rather than patched client-side.

Test plan

  • /volunteer — roles load, styling matches the page's indigo/white system, filters and Read-the-full-role work
  • /volunteer-new — roles load, styling matches the cream/rose system, hero divider reads correctly and section surfaces still alternate below
  • Team roles (currently Web Developer — Exposing Israel Bonds, Outreach helper — Internships for students from Gaza) show the "T4P team" marker and link to /membership; project roles link to the volunteer form
  • "Check out specific roles" link scrolls to the list on both pages
  • Error state: block /api/open-roles in devtools and confirm the notice + working Try again
  • Keyboard-only pass over chips, disclosures, and apply links; check focus rings are visible

…button

The "Current Volunteer Needs" button sent people to a Notion board. Replace it
on /volunteer and /volunteer-new with a filterable list of the live open roles
from the Hub's public API.

- Add /api/open-roles, a server proxy over
  hub.techforpalestine.org/api/public/open-roles. One retry on 5xx for cold
  starts, tolerates a bare array or a wrapped envelope, no-store, and returns a
  generic error to the client with details going to Sentry.
- Normalize the upstream rows at the boundary (openRoleData.ts): flatten
  project/team into a single orgName, coerce and cap strings, drop rows without
  an id or title, sort newest-first.
- Render as a single-column list of bands rather than a card grid, so expanding
  a long description doesn't reflow siblings. Collapsed previews flatten
  whitespace because several descriptions open with a short heading line that
  would otherwise waste the three-line clamp.
- Apply targets follow how a role is staffed: team roles point at /membership
  ("Become a member"), project roles at the volunteer form.
- Skill filters cap at the 8 most common with the tail behind a toggle; 15
  categories, 9 of them with a single role, would have outweighed the list.
  The active filter stays visible even when it lives in the tail.
- The island carries a skin prop because the two pages use different design
  systems (Layout.astro's indigo/white vs HomeLayout's cream/rose and ts-*
  scale, which only that layout loads). Each skin borrows its host's tokens
  instead of introducing a third identity.
- Repoint the in-prose "specific roles we're looking for" link at #open-roles;
  it would otherwise have kept the replaced Notion board linked.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying website with  Cloudflare Pages  Cloudflare Pages

Latest commit: c9a1911
Status: ✅  Deploy successful!
Preview URL: https://09d7e9ee.website-aun.pages.dev
Branch Preview URL: https://feat-volunteer-open-roles.website-aun.pages.dev

View logs

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.

1 participant