[STU-154] Landing page UX overhaul — copy, icons, and benefits section#36
Conversation
…benefits section - Replace hero copy with clearer value proposition and inclusive CTAs - Add role-specific emoji icons to portal grid cards for visual differentiation - Replace technical search signals section with user-facing benefit cards - Remove dead CSS from earlier landing page iteration (~96 lines) - Add new CSS classes for portalIcon, landingBenefitsSection, and benefitGrid Co-Authored-By: Paperclip <noreply@paperclip.ing>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedFailed to post review comments 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:
WalkthroughThis PR updates the landing page with new role-to-icon mappings and a benefits grid, refreshes hero copy and CTAs, adds smoke test coverage for desktop and mobile, and adjusts certificate schema validation to remove unused fields and convert certificate type to boolean. ChangesLanding Page Content Refresh
Certificate Schema Validation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/app/page.tsx (1)
69-74: ⚡ Quick winFragile index-based logic for "PDF" vs "Live" determination.
The condition
index === 1hardcodes the assumption that "CV export" is always the second item. If the array order changes, this logic silently breaks. Consider using an explicit data structure or checking the item name.♻️ Proposed refactor using explicit mapping
-{["Profile", "CV export", "Timesheet", "Payment"].map((item, index) => ( +{[ + { label: "Profile", status: "Live" }, + { label: "CV export", status: "PDF" }, + { label: "Timesheet", status: "Live" }, + { label: "Payment", status: "Live" }, +].map((item) => ( - <div key={item}> - <span>{item}</span> - <strong>{index === 1 ? "PDF" : "Live"}</strong> + <div key={item.label}> + <span>{item.label}</span> + <strong>{item.status}</strong> </div> ))}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/page.tsx` around lines 69 - 74, The mapping over ["Profile", "CV export", "Timesheet", "Payment"] uses fragile index-based logic (index === 1) to decide "PDF" vs "Live"; update the rendering in the map so it derives the label from the item itself (e.g., check the item string or use an explicit array of objects like {name, mode}) instead of using index, and update the JSX in the map callback (the inline map and the span/strong rendering) to use that property to show "PDF" for CV export and "Live" for others.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/page.tsx`:
- Around line 9-15: The portalIcons map is currently typed as Record<string,
string>, causing unchecked indexed access against the specific portalRoles;
update types so keys are the exact union of roles and eliminate undefined on
portalIcons[role]. Derive a PortalRole from the existing portalRoles (e.g.,
using typeof portalRoles[number] or make portalRoles readonly with as const) and
then type portalIcons as Record<PortalRole, string> or recreate portalIcons
using the satisfies pattern so accesses like portalIcons[role] are typed as
string (refer to symbols portalRoles and portalIcons and the place where
portalIcons[role] is used).
---
Nitpick comments:
In `@src/app/page.tsx`:
- Around line 69-74: The mapping over ["Profile", "CV export", "Timesheet",
"Payment"] uses fragile index-based logic (index === 1) to decide "PDF" vs
"Live"; update the rendering in the map so it derives the label from the item
itself (e.g., check the item string or use an explicit array of objects like
{name, mode}) instead of using index, and update the JSX in the map callback
(the inline map and the span/strong rendering) to use that property to show
"PDF" for CV export and "Live" for others.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 5cdd0556-5d99-473e-839c-740d6c08da92
📒 Files selected for processing (1)
src/app/page.tsx
| const portalIcons: Record<string, string> = { | ||
| candidate: "🎓", | ||
| staff: "📋", | ||
| company: "🏭", | ||
| admin: "⚙️", | ||
| inspector: "🔍", | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Strengthen typing to align with portalRoles and satisfy strict mode.
portalIcons is typed as Record<string, string>, but the keys are exactly the five roles defined in portalRoles (line 36). With noUncheckedIndexedAccess enabled (per coding guidelines), accessing portalIcons[role] at line 108 will return string | undefined, requiring a runtime check or type assertion.
Define a more precise type to ensure compile-time safety and eliminate the need for runtime guards.
🔒 Proposed fix to align types with portalRoles
+type PortalRole = typeof portalRoles[number];
+
-const portalIcons: Record<string, string> = {
+const portalIcons: Record<PortalRole, string> = {
candidate: "🎓",
staff: "📋",
company: "🏭",
admin: "⚙️",
inspector: "🔍",
};Alternatively, use satisfies for inference while retaining safety:
-const portalIcons: Record<string, string> = {
+const portalIcons = {
candidate: "🎓",
staff: "📋",
company: "🏭",
admin: "⚙️",
inspector: "🔍",
-};
+} satisfies Record<PortalRole, string>;As per coding guidelines: "Strict mode enabled — no implicit any, no unchecked index access."
📝 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 portalIcons: Record<string, string> = { | |
| candidate: "🎓", | |
| staff: "📋", | |
| company: "🏭", | |
| admin: "⚙️", | |
| inspector: "🔍", | |
| }; | |
| type PortalRole = typeof portalRoles[number]; | |
| const portalIcons: Record<PortalRole, string> = { | |
| candidate: "🎓", | |
| staff: "📋", | |
| company: "🏭", | |
| admin: "⚙️", | |
| inspector: "🔍", | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/app/page.tsx` around lines 9 - 15, The portalIcons map is currently typed
as Record<string, string>, causing unchecked indexed access against the specific
portalRoles; update types so keys are the exact union of roles and eliminate
undefined on portalIcons[role]. Derive a PortalRole from the existing
portalRoles (e.g., using typeof portalRoles[number] or make portalRoles readonly
with as const) and then type portalIcons as Record<PortalRole, string> or
recreate portalIcons using the satisfies pattern so accesses like
portalIcons[role] are typed as string (refer to symbols portalRoles and
portalIcons and the place where portalIcons[role] is used).
DevRel ReviewStatus: Approved — solid landing page improvements Clean, single-file change to
This directly addresses GitHub issue #28 (landing page UX overhaul). One note: the Vercel preview deploy should be checked to confirm the visual layout renders correctly. |
Add Playwright e2e smoke test covering hero copy, portal grid with icons, benefits section, nav, CTA buttons, platform highlights, and mobile layout. Also add landing page checks to the existing smoke-test.mjs script. Tests: added e2e/smoke/landing.spec.ts (16 tests across chromium + mobile)
There was a problem hiding this comment.
🧹 Nitpick comments (1)
e2e/smoke/landing.spec.ts (1)
81-81: 💤 Low valueConsider aligning test name with what's actually verified.
The test name mentions "without overflow" but only verifies element visibility. For a smoke test this is acceptable, but you could either:
- Rename to something like "landing page renders key elements on mobile"
- Add explicit overflow verification if that's a critical concern
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/smoke/landing.spec.ts` at line 81, The test named "landing page renders on mobile without overflow" only asserts element visibility; either update the test name to reflect what it actually checks (e.g., rename the test to "landing page renders key elements on mobile") or add an explicit overflow assertion: after the existing visibility checks, evaluate page-level overflow (for example using page.evaluate to compare document.documentElement.scrollWidth to window.innerWidth or check computed overflow/overflowX on body/html) and assert no horizontal overflow; modify the test() declaration or append the overflow expect accordingly so the name matches behavior or the behavior matches the name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@e2e/smoke/landing.spec.ts`:
- Line 81: The test named "landing page renders on mobile without overflow" only
asserts element visibility; either update the test name to reflect what it
actually checks (e.g., rename the test to "landing page renders key elements on
mobile") or add an explicit overflow assertion: after the existing visibility
checks, evaluate page-level overflow (for example using page.evaluate to compare
document.documentElement.scrollWidth to window.innerWidth or check computed
overflow/overflowX on body/html) and assert no horizontal overflow; modify the
test() declaration or append the overflow expect accordingly so the name matches
behavior or the behavior matches the name.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ec490af1-19d1-476a-a9a0-acfc181a04ba
📒 Files selected for processing (2)
e2e/smoke/landing.spec.tsscripts/smoke-test.mjs
…ds on PR #36 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Action casts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add certificate CRUD for candidate profile edit - Add certificate_title, certificate_issuer, certificate_url fields to Prisma schema - Add Zod-validated addCandidateCertificate and removeCandidateCertificate server actions - Add certificate form section to CandidateEditForm with type select, title, issuer, dates, and URL - Pass certificate data from edit page to form component - Update data.ts to select and display new certificate fields Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: increase login page tap targets to 44px min-height for accessibility Bumps min-height on three login/shell elements from 40px/42px to 44px to meet WCAG 2.5.5 target size recommendations: nav links, theme toggle, and landing brand. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test: add workflow pipeline tests for request lifecycle Add tests for suggestion creation, application shortlist, interview completion, invitation creation, and cross-role visibility. Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat: restyle mobile tab bar CSS for bottom tab navigation with icons - Replace floating pill bar with fixed full-width bottom tab bar - Add icon+label stacked layout with flex-direction: column - Add backdrop-filter blur, safe-area-inset-bottom support - Add active indicator via border-top highlight - Separate dark mode mobile tab bar styles - Update workspace stage bottom padding from 88px to 76px Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: resolve FK constraint violations in workflow test cleanup Clear note.suggestion_uuid and story.suggestion_uuid before deleting suggestions to avoid circular FK errors during test data cleanup. Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat: add interview management page for staff [STU-134] Adds /staff/interviews list and detail pages with status management, data fetching functions, G I keyboard shortcut, and nav integration. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat: implement mobile bottom tab navigation with icons [STU-135] - Add LucideIcon field to NavItem type and map icons for all roles - Render icons in desktop WorkspaceNavigation and mobile tab bar - Add staff Interviews nav item with Calendar icon - Remove duplicate WorkspaceMobileNavigation when embedded in WorkspaceOS - Redesign mobile tab bar: full-width fixed bottom bar with icon+label layout - Add backdrop-filter blur, safe-area-inset-bottom, and active border-top indicator - Update workspace stage bottom padding from 88px to 76px Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix: address CodeRabbit review findings for PR #31 [STU-170] - Wrap candidateProfileUpdateTest DB mutations in try/finally so cleanup always runs even on assertion failure - Add certificate CRUD workflow test with DB row verification - Tighten suggestion test assertion with explicit note_uuid check - Replace undefined --fg CSS variable with --foreground in candidateMissingFields hover rule - Use strict z.enum(["true", "false"]) for certificate_type coercion - Replace Number.isInteger(status) with explicit whitelist (2, 3) in updateInterviewAction - Interview existence check before update already present (no change needed) Tests: added certificate CRUD workflow test, tightened suggestion assertion Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix: restore main-compatible actions.ts and fix merge inconsistencies Taking main's actions.ts (which includes approveIdRequest/rejectIdRequest) and re-applying the STU-170 strict certificate_type enum fix. Also pulling in main's WorkLogStaffActions and ID request page for consistency. Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix: add rejection_reason to ID request detail select query for PR #31 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: resolve merge conflicts and remove non-existent certificate fields on PR #36 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove duplicate Prisma schema fields on PR #31 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing>
This reverts commit afbee09.
…ts [STU-154] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Deployment failed with the following error: Learn More: https://vercel.com/khalid-proj?upgradeToPro=build-rate-limit |
…orm parsing These fields don't exist in the Prisma candidate_certificate model on main. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Context
Part of STU-154 landing page and login UX redesign. This cherry-picks the UX Designer's work that was completed in a worktree session.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Tests