Skip to content

Comments

feat: UX gap fixes — 404 page, empty state, hover states#146

Merged
ryota-murakami merged 3 commits intomainfrom
feat/bulk-issues-20260220
Feb 20, 2026
Merged

feat: UX gap fixes — 404 page, empty state, hover states#146
ryota-murakami merged 3 commits intomainfrom
feat/bulk-issues-20260220

Conversation

@ryota-murakami
Copy link
Contributor

@ryota-murakami ryota-murakami commented Feb 20, 2026

Summary

Resolves 3 UX gap issues identified by the UX Gap Detector audit (score: 61/100).
Issue #138 (loading states) was already implemented — closing with comment.

Changes

File Change
src/app/not-found.tsx New — branded 404 with Columns3 icon, "Go to Boards" + "Back to Home" CTAs
src/components/Board/StatusColumn.tsx Add Inbox icon empty state when cards.length === 0
src/app/(landing)/FeaturesSection.tsx Add hover:-translate-y-1 cursor-pointer to feature cards
src/app/(landing)/HowItWorksSection.tsx Add group hover states, lift effect, step number scale animation
src/app/(landing)/Footer.tsx Add Privacy and Terms nav links

Test plan

  • pnpm lint — passed
  • pnpm typecheck — passed
  • pnpm test — 1282 tests passed
  • pnpm build/_not-found route generated
  • pnpm e2e:parallel — all E2E tests passed

Closes #137
Closes #139
Closes #140

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Privacy and Terms navigation links to the footer
    • Added a 404 error page for unmatched routes
    • Added guidance messaging in empty status columns
  • Style

    • Enhanced hover effects and transitions on feature and step cards

- Add hover lift effect (-translate-y-1) to feature and step cards
- Add group hover transitions to HowItWorksSection step cards
- Add cursor-pointer to interactive cards
- Add Privacy and Terms links to footer

Closes #140
@vercel
Copy link
Contributor

vercel bot commented Feb 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gitbox Ready Ready Preview, Comment Feb 20, 2026 0:10am

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

This PR addresses three UX gaps by adding interactive hover effects to landing page components, introducing a branded 404 error page for unknown routes, and adding empty-state guidance to empty board columns to improve first-time user experience.

Changes

Cohort / File(s) Summary
Landing Page Interactive States
src/app/(landing)/FeaturesSection.tsx, src/app/(landing)/HowItWorksSection.tsx, src/app/(landing)/Footer.tsx
Added hover effects, cursor pointer, and transition animations to feature cards and step cards. Added Privacy and Terms links to footer with hover styling.
404 Error Page
src/app/not-found.tsx
New branded 404 page component with full-screen layout, icon, title, explanatory text, and navigation buttons ("Go to Boards" and "Back to Home").
Board Column Empty State
src/components/Board/StatusColumn.tsx
Added empty-column guidance UI that displays when a status column has no cards, showing an Inbox icon and message to drop repos or click "Add Repo".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Possibly related PRs


🎯 Four gaps now filled with grace,
Hover effects light up the space,
Empty columns whisper their tale,
Lost users find home without fail,
Polish blooms where emptiness dwelled ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main improvements: 404 page, empty state, and hover state enhancements across the landing page.
Linked Issues check ✅ Passed All linked issues (#137, #139, #140) are addressed: branded 404 page implemented, empty column state added with guidance icon, and landing page hover states enhanced across feature cards and steps.
Out of Scope Changes check ✅ Passed All changes align with the three linked issues; no unrelated modifications detected in the diff summary.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 feat/bulk-issues-20260220

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

@morph-subagents
Copy link

🤖 Morph Preview Test

Looks like you hit your rate limits!

Please upgrade your limits here, or wait a few minutes and try again.

If you need help, reach out to support@morphllm.com.


Automated testing by Morph

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.27%. Comparing base (abe756a) to head (25bb057).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #146      +/-   ##
==========================================
+ Coverage   69.26%   69.27%   +0.01%     
==========================================
  Files         146      146              
  Lines        4552     4554       +2     
  Branches     1214     1216       +2     
==========================================
+ Hits         3153     3155       +2     
  Misses       1377     1377              
  Partials       22       22              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@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 (1)
src/app/(landing)/FeaturesSection.tsx (1)

88-100: Hover lift effect looks good.

Clean, consistent implementation. The group + group-hover:scale-110 on the icon at line 92 is a nice detail.

One optional note: cursor-pointer on a non-interactive <div> (no onClick/href) can be mildly misleading to pointer users who expect a click response. If these cards are purely decorative, cursor-default is semantically more accurate — or you can add an onClick that anchors to the relevant section. The same pattern exists in HowItWorksSection.tsx line 52.

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

In `@src/app/`(landing)/FeaturesSection.tsx around lines 88 - 100, The top-level
feature card div using the class string that includes "group ... cursor-pointer"
is non-interactive and should not signal clickability; either replace
"cursor-pointer" with "cursor-default" on that div in FeaturesSection (the
container rendering feature.icon, feature.title, feature.description) or make
the card truly interactive by adding an onClick handler or wrapping it in a
semantic anchor/button that navigates to the related section; apply the same
change to the analogous non-interactive card in HowItWorksSection (the div
around line 52) to keep behavior consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`(landing)/Footer.tsx:
- Around line 40-46: Add rel="noopener noreferrer" to the external anchor for
Laststance.io in Footer.tsx to prevent reverse tabnapping; locate the <a>
element with href="https://laststance.io/" (the Laststance.io link) and add
rel="noopener noreferrer" alongside target="_blank" to match the GitHub link's
protection.

In `@src/components/Board/StatusColumn.tsx`:
- Around line 188-196: The empty-state guidance in the StatusColumn component
always tells users to "click 'Add Repo' below" even when the optional onAddCard
prop isn't provided; update the JSX inside the cards.length === 0 block in
StatusColumn.tsx to conditionally render the guidance text based on the presence
of onAddCard (e.g., show "Drop repos here" only when onAddCard is undefined, or
append "or click 'Add Repo' below" only when onAddCard is defined) so the
message matches whether the Add Repo button will be rendered.

---

Nitpick comments:
In `@src/app/`(landing)/FeaturesSection.tsx:
- Around line 88-100: The top-level feature card div using the class string that
includes "group ... cursor-pointer" is non-interactive and should not signal
clickability; either replace "cursor-pointer" with "cursor-default" on that div
in FeaturesSection (the container rendering feature.icon, feature.title,
feature.description) or make the card truly interactive by adding an onClick
handler or wrapping it in a semantic anchor/button that navigates to the related
section; apply the same change to the analogous non-interactive card in
HowItWorksSection (the div around line 52) to keep behavior consistent.

Comment on lines +40 to 46
<a
href="https://laststance.io/"
target="_blank"
className="hover:text-foreground transition-colors"
>
Laststance.io
</a>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add rel="noopener noreferrer" to the target="_blank" Laststance link.

The GitHub link in the same file already has it; the new Laststance.io link does not. Without it, the opened tab can access window.opener and redirect the originating page (reverse tabnapping).

🔒 Proposed fix
  <a
    href="https://laststance.io/"
    target="_blank"
+   rel="noopener noreferrer"
    className="hover:text-foreground transition-colors"
  >
    Laststance.io
  </a>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`(landing)/Footer.tsx around lines 40 - 46, Add rel="noopener
noreferrer" to the external anchor for Laststance.io in Footer.tsx to prevent
reverse tabnapping; locate the <a> element with href="https://laststance.io/"
(the Laststance.io link) and add rel="noopener noreferrer" alongside
target="_blank" to match the GitHub link's protection.

Comment on lines +188 to +196
{/* Empty column guidance */}
{cards.length === 0 && (
<div className="flex flex-col items-center gap-2 py-8 text-center">
<Inbox className="text-muted-foreground/40 h-8 w-8" />
<p className="text-muted-foreground text-xs">
Drop repos here or click &quot;Add Repo&quot; below
</p>
</div>
)}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Empty state message references "Add Repo" even when onAddCard is not provided.

onAddCard is optional — when absent the "Add Repo" button (line 201) is not rendered, but the guidance still tells users to click it.

🛠️ Proposed fix
-              <p className="text-muted-foreground text-xs">
-                Drop repos here or click &quot;Add Repo&quot; below
-              </p>
+              <p className="text-muted-foreground text-xs">
+                {onAddCard
+                  ? 'Drop repos here or click "Add Repo" below'
+                  : 'Drop repos here to get started'}
+              </p>
📝 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.

Suggested change
{/* Empty column guidance */}
{cards.length === 0 && (
<div className="flex flex-col items-center gap-2 py-8 text-center">
<Inbox className="text-muted-foreground/40 h-8 w-8" />
<p className="text-muted-foreground text-xs">
Drop repos here or click &quot;Add Repo&quot; below
</p>
</div>
)}
{/* Empty column guidance */}
{cards.length === 0 && (
<div className="flex flex-col items-center gap-2 py-8 text-center">
<Inbox className="text-muted-foreground/40 h-8 w-8" />
<p className="text-muted-foreground text-xs">
{onAddCard
? 'Drop repos here or click "Add Repo" below'
: 'Drop repos here to get started'}
</p>
</div>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Board/StatusColumn.tsx` around lines 188 - 196, The
empty-state guidance in the StatusColumn component always tells users to "click
'Add Repo' below" even when the optional onAddCard prop isn't provided; update
the JSX inside the cards.length === 0 block in StatusColumn.tsx to conditionally
render the guidance text based on the presence of onAddCard (e.g., show "Drop
repos here" only when onAddCard is undefined, or append "or click 'Add Repo'
below" only when onAddCard is defined) so the message matches whether the Add
Repo button will be rendered.

@github-actions
Copy link

🧪 E2E Coverage Report (Sharded: 12 parallel jobs)

Metric Coverage
Lines 94.48%
Functions 17.8%
Branches 17.41%
Statements 31.05%

📊 Full report available in workflow artifacts

@ryota-murakami ryota-murakami merged commit 4e3451a into main Feb 20, 2026
20 checks passed
@ryota-murakami ryota-murakami deleted the feat/bulk-issues-20260220 branch February 20, 2026 12:23
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.

UX Gap: Landing page feature cards lack hover states UX Gap: Empty board states lack onboarding guidance UX Gap: No custom 404 page

2 participants