Skip to content

feat(join): add public recruitment page, Google Form embed, and navigation entry points (PR B of 3) - #204

Merged
barunaniket merged 2 commits into
codechefPesuecc:mainfrom
aakash-agarwal-cs:feat/recruitment-join-page
Sep 9, 2026
Merged

feat(join): add public recruitment page, Google Form embed, and navigation entry points (PR B of 3)#204
barunaniket merged 2 commits into
codechefPesuecc:mainfrom
aakash-agarwal-cs:feat/recruitment-join-page

Conversation

@aakash-agarwal-cs

Copy link
Copy Markdown
Contributor

Summary

Companion to docs/recruitment.md and docs/recruitment-workplan.md. This is PR B of 3 (the public recruitment surface and form embed).

  • Creates /join (src/app/join/page.tsx) with server-side rendering (force-dynamic), reading recruitment drive state from getRecruitmentSettings().
  • Implements GoogleFormEmbed server component (src/components/join/GoogleFormEmbed.tsx) with a theme-aware card wrapper (dark mode deliberate white card styling), responsive min-height, no sandbox restrictions, and an external new-tab fallback link.
  • Updates CSP in next.config.ts: adds https://docs.google.com to frame-src while leaving frame-ancestors and X-Frame-Options strictly intact.
  • Adds Join link to Navbar.tsx and Footer.tsx.
  • Adds Apply now → CTA button on the homepage (/) under the member benefits section using @/components/AppLink.
  • Fully handles closed and fresh-DB state: when isOpen: false or formUrl: null, renders a clean closed notice with links to Instagram rather than an empty frame or crash.

Type of change

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

How was this tested?

  • npm run test: 90/90 tests passed.
  • npx tsc --noEmit: 0 TypeScript errors.
  • npm run lint: 0 ESLint errors.
  • npm run build: Production build succeeded cleanly (ƒ /join server-rendered).
  • Local dev server: verified HTTP 200 OK, CSP frame-src headers, and HTML rendering for /join and /.

Checklist

  • I ran the checks locally and they pass: npx tsc --noEmit, npm run lint, npm run test, npm run build
  • I did not commit unrelated package-lock.json changes
  • My change is focused and single-purpose
  • For UI changes: it looks correct in both light and dark mode
  • I did not commit any secrets

@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

@aakash-agarwal-cs is attempting to deploy a commit to the barunaniket-9400's projects Team on Vercel.

A member of the Team first needs to authorize it.

@barunaniket barunaniket left a comment

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.

Careful work — the engineering side is right, and a couple of the fiddly bits are exactly right in a way that's easy to get wrong. Blocking only on content: the domain list is out of sync with the actual form, and that's on us, not you.

What's correct

  • CSP — one token added to frame-src, with frame-ancestors and X-Frame-Options left alone. That's the right call and the easy thing to over-edit.
  • GoogleFormEmbed — server component, no sandbox (which would break Forms), has a title for screen readers, and the new-tab fallback is there.
  • Gates on settings.canEmbed rather than re-deriving isOpen && formUrl && valid. That's exactly what the flag is for.
  • force-dynamic, AppLink over next/link, closed state and fresh-DB state both handled without crashing.

Blocking

1. The page lists 9 domains; there are 6

The live form offers exactly these, verbatim:

Competitive Programming
Design
Events
Technical
Sponsorship
Social Media & Marketing

The domains array in src/app/join/page.tsx has nine, and Design is missing entirely while Problem Setting, Content & Editorial, and Operations & Logistics don't exist as domains. As it stands someone reads "Problem Setting" on /join, opens the form, and there's no such option.

This isn't your fault — the six were finalised after you'd started and nobody sent them over. The mapping:

  • Frontend Development + Backend & Systems → Technical
  • Social Media & Outreach + Content & Editorial → Social Media & Marketing
  • Problem Setting → drop (it's now a yes/no question inside the CP section of the form)
  • Operations & Logistics → drop, or fold into Events
  • Add Design

The tag values will need a pass too.

2. "You can apply to more than one domain in your submission"

The form is single-select with section branching — one domain, one section. This line sets an expectation the form doesn't meet, so it needs to go.

Please confirm before merge

  • <h1>: "Join the Core Team" — the roster distinguishes coordinator / core / members, and recruits presumably join as members. Reads as overpromising unless it's deliberate.
  • The 4-step timeline (Application → Review & Shortlist → Interaction / Task → Onboarding) is plausible but invented. Worth confirming it matches the real process before it's on a public page.

Minor, your call

  • settings.cycle || "2026–27" hardcodes a fallback — if an admin leaves the cycle blank the page shows 2026–27 indefinitely.
  • The closed state says it twice: "Recruitment is Closed" in the hero and "Recruitment is currently closed" in the panel.

Once the domain list matches the form, this is good to go.

@barunaniket barunaniket left a comment

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.

Verified against the file at head, not just the diff. Both blockers are resolved:

  • Six domains, matching the live form verbatim — Competitive Programming, Technical, Design, Events, Sponsorship, Social Media & Marketing. Design is in; Problem Setting, Content & Editorial and Operations & Logistics are gone.
  • "You can apply to more than one domain" is gone, replaced with singular phrasing that matches how the form actually behaves.
  • "Core Team" removed from the heading, the metadata and the onboarding step.

The cycle-label fix is better than what I asked for — making it conditional throughout, so a blank cycle drops the label instead of rendering a stale year, is the right call and covers the fresh-database case too.

CI verify passes, and there's no overlap with the admin work that landed in #205/#206.

Merging. One copy change is coming in a follow-up rather than another round trip on your branch: the four-step timeline describes a shortlist-then-task-then-onboarding process that hasn't actually been decided — everything after submission is being handled from the response sheet for now. That's on us for not telling you; the section reads well, it just promises applicants a round that may not happen. I'll trim it to what we can stand behind.

@barunaniket
barunaniket merged commit fda69eb into codechefPesuecc:main Sep 9, 2026
1 of 2 checks passed
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.

2 participants