Skip to content

feat(web): add responsive kanban roadmap with GitHub issues#1971

Merged
ComputelessComputer merged 9 commits intomainfrom
devin/1764320910-roadmap-kanban-view
Nov 28, 2025
Merged

feat(web): add responsive kanban roadmap with GitHub issues#1971
ComputelessComputer merged 9 commits intomainfrom
devin/1764320910-roadmap-kanban-view

Conversation

@ComputelessComputer
Copy link
Collaborator

@ComputelessComputer ComputelessComputer commented Nov 28, 2025

Summary

Replaces the hardcoded roadmap page with a dynamic view that fetches issues from the GitHub repository. The page now displays a kanban-style layout on wide viewports (lg: breakpoint) and a stacked column layout on narrow viewports, with item limits per section to keep the page manageable.

Key changes:

  • Fetches issues with labels enhancement, feature, or improvement from the GitHub API
  • Categorizes issues into Done (closed), In Progress (has "in progress"/"wip"/"working" label), or Planned (open, no progress label)
  • Kanban view shows 5 items per column by default, column view shows 3 items per section
  • "Show more" buttons expand to reveal all items in each category
  • Loading spinner and error state handling included

Updates since last revision

  • Fixed TypeScript error: removed unused status prop from ColumnSection component
  • Fixed GitHub API query: changed from server-side label filtering (AND semantics) to client-side filtering (OR semantics) so issues with ANY of the roadmap labels are included

Review & Testing Checklist for Human

  • GitHub API rate limiting: The page makes unauthenticated API calls (60 req/hour limit). Test what happens when rate limited - the error state should display gracefully
  • Verify responsive breakpoints: Test at various viewport widths to confirm kanban (lg:) vs column layout switching works correctly
  • Test "Show more/less" toggle: Verify the expand/collapse buttons work in both kanban and column views
  • Check external link behavior: The Link component is used with external GitHub URLs - verify links open correctly in new tabs
  • Verify issue categorization: Check that issues appear in the correct columns based on their state and labels

Test plan: Run pnpm -F web dev and navigate to /roadmap. Test on both desktop (wide) and mobile (narrow) viewports. Verify issues load from GitHub, categories are correct, and expand/collapse works.

Notes

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Nov 28, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 2817b0e
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/6929ca3011bb97000844a69a
😎 Deploy Preview https://deploy-preview-1971--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Nov 28, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 2817b0e
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/6929ca30af58e400086e0dfb
😎 Deploy Preview https://deploy-preview-1971--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • apps/web/src/routeTree.gen.ts is excluded by !**/*.gen.ts

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Replaces a hard-coded roadmap UI with a content-driven implementation: adds a roadmap MDX collection and transform, three new MDX roadmap items, list and per-slug routes, and responsive Kanban/column UI that renders items via MDX with optional GitHub issue previews.

Changes

Cohort / File(s) Summary
Routes & UI
apps/web/src/routes/_view/roadmap/index.tsx, apps/web/src/routes/_view/roadmap/$slug.tsx
Adds/refactors roadmap list and item routes. Introduces data model (RoadmapItem, RoadmapStatus), KanbanView/ColumnView components, RoadmapCard, GitHubIssuePreview, MDX rendering (getMDXComponent), show-more logic, and SEO/head for slug pages.
Content collection & transform
apps/web/content-collections.ts
Adds roadmap collection with schema (title, status, created, updated?, labels), MDX transform using remarkGfm and mdxMermaid, slug generation, GitHub issue link extraction, and returns compiled MDX, slug, and githubIssues.
Roadmap content (new MDX items)
apps/web/content/roadmap/mobile-app.mdx, apps/web/content/roadmap/pdf-export.mdx, apps/web/content/roadmap/real-time-collaboration.mdx
Adds three roadmap MDX documents with frontmatter and body content referencing related GitHub issues.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant Route as Roadmap Route
  participant Content as allRoadmaps
  participant MDX as MDX renderer
  participant GitHub as GitHub iframe

  Browser->>Route: GET /_view/roadmap or /_view/roadmap/:slug
  Route->>Content: read allRoadmaps / find by slug (getRoadmapItems)
  Content-->>Route: roadmap items (meta, mdx string, githubIssues)
  Route-->>Browser: render page (Kanban/Columns or item page) with MDX payload
  Browser->>MDX: hydrate/getMDXComponent to render MDX per card
  MDX-->>Browser: rendered components (mermaid, embeds)
  alt item has GitHub issues
    Browser->>GitHub: load issue preview iframe(s)
    GitHub-->>Browser: issue preview content
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Files warranting extra attention:
    • apps/web/content-collections.ts — MDX transform, plugins, and returned shape (mdx string vs compiled output).
    • apps/web/src/routes/_view/roadmap/index.tsx — getRoadmapItems mapping, client/server MDX hydration, responsive UI logic and show-more state.
    • apps/web/src/routes/_view/roadmap/$slug.tsx — loader/notFound handling and SEO/head construction.
    • GitHub iframe embedding — sandboxing and security attributes.

Possibly related PRs

Suggested reviewers

  • yujonglee

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a responsive kanban-style roadmap UI with GitHub issue integration.
Description check ✅ Passed The description is directly related to the changeset, providing clear context about replacing the hardcoded roadmap with a dynamic GitHub-backed view.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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: 3

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35b1859 and 3f84163.

📒 Files selected for processing (1)
  • apps/web/src/routes/_view/roadmap.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/routes/_view/roadmap.tsx
🪛 GitHub Actions: .github/workflows/web_ci.yaml
apps/web/src/routes/_view/roadmap.tsx

[error] 343-343: src/routes/_view/roadmap.tsx(343,3): error TS6133: 'status' is declared but its value is never read.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: fmt
🔇 Additional comments (5)
apps/web/src/routes/_view/roadmap.tsx (5)

24-51: LGTM!

The type definitions are well-structured and clearly model the GitHub API response and the transformed roadmap data.


55-87: LGTM!

The categorization logic correctly prioritizes closed state, then checks for in-progress labels, with a sensible fallback to "planned". The description truncation is handled cleanly.


118-204: LGTM!

The component correctly handles loading, error, and success states. The filtering logic is straightforward and the conditional rendering is clean.


206-300: LGTM!

The Kanban view components are well-structured with proper responsive hiding, show-more functionality, and status-based border styling.


407-445: LGTM!

The card content handles compact/full modes elegantly with appropriate text truncation and label overflow indicators.

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
@argos-ci
Copy link

argos-ci bot commented Nov 28, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Awaiting the start of a new Argos build…

Replace the previous "planned" status and columns with a "todo" column to match requested columns: todo, in progress, done. Update the RoadmapStatus type and status mapping, rename and filter planned -> todo, and pass todo into KanbanView and ColumnView. Swap column titles/icons so columns render as To Do, In Progress, and Done, and update status-based styling to use "todo" where appropriate.
Copy link
Contributor

@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: 1

🧹 Nitpick comments (6)
apps/web/content-collections.ts (1)

404-446: Roadmap collection schema and transform look consistent; consider minor robustness tweaks.

The roadmap collection mirrors existing patterns (schema + MDX compile + slug) and aligns with the MDX frontmatter in this PR. The GitHub issue extraction regex is safe but quite strict (no query strings or fragments, duplicates allowed). If you expect variations like ?tab=comments or repeated links, you might want to:

  • Loosen the regex to allow optional [\?#][^\s]* tail.
  • Optionally Array.from(new Set(...)) to dedupe githubIssues.

Not required for correctness, but would make the extractor more robust.

Also applies to: 448-459

apps/web/content/roadmap/mobile-app.mdx (1)

1-14: Content matches roadmap schema; link formatting tweak is optional.

Frontmatter aligns with the roadmap collection schema (status: "todo", labels array, dates as strings), so this item will hydrate cleanly into RoadmapItem. If you want slightly better readability and accessibility, you could convert the inline issue URLs in the task list to Markdown links ([iOS app development](https://github.com/...)), but it's not required for functionality.

apps/web/content/roadmap/pdf-export.mdx (1)

1-15: Schema alignment looks good; Markdown issue links could be friendlier.

This entry’s frontmatter (status, dates, labels) is consistent with the roadmap collection and RoadmapStatus/RoadmapItem usage, so it should render correctly in the Kanban. As a small UX polish, you could wrap the issue URLs in Markdown links ([Basic PDF generation](...)) to improve readability, but it’s optional.

apps/web/src/routes/_view/roadmap.tsx (3)

23-51: RoadmapItem model is consistent with content; consider explicit ordering if item count grows.

RoadmapStatus matches the Zod enum in the roadmap collection, and RoadmapItem mirrors the fields returned from allRoadmaps. The labels || [] and githubIssues || [] defaults prevent undefined access later, which is good.

Right now getRoadmapItems() preserves the underlying collection order. If you expect more items over time, you might want to sort (e.g., by created or updated) before splitting into done / in-progress / todo so column ordering is predictable across builds.

Also applies to: 54-58


67-80: Desktop Kanban layout behaves correctly; show‑more logic is sound.

The split into KanbanView (desktop) and ColumnView (mobile) via hidden lg:grid / lg:hidden avoids double-rendering on a single viewport. In KanbanColumn, DEFAULT_VISIBLE_ITEMS and the hasMore / showAll logic are correct and handle empty columns gracefully with the “No items” placeholder.

If you later add significantly more roadmap items, you may want to consider per-status sorting (e.g., newest first) inside each column, but the current implementation is functionally solid.

Also applies to: 107-201


203-284: Mobile ColumnView matches desktop semantics and hides empty sections.

ColumnView reuses the same done / inProgress / todo arrays and ColumnSection cleanly early-returns when items.length === 0, so you don’t show empty headings on small screens. The mobile-specific cap of 3 items with a “Show more items” CTA mirrors the desktop behavior well.

No functional issues here; just note that "Show X more items" will always use the plural, which is fine but could be refined later if you want singular/plural handling.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f84163 and b6f8be2.

📒 Files selected for processing (5)
  • apps/web/content-collections.ts (2 hunks)
  • apps/web/content/roadmap/mobile-app.mdx (1 hunks)
  • apps/web/content/roadmap/pdf-export.mdx (1 hunks)
  • apps/web/content/roadmap/real-time-collaboration.mdx (1 hunks)
  • apps/web/src/routes/_view/roadmap.tsx (5 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/content/roadmap/real-time-collaboration.mdx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/routes/_view/roadmap.tsx
  • apps/web/content-collections.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Agent implementations should use TypeScript and follow the established architectural patterns defined in the agent framework
Agent communication should use defined message protocols and interfaces

Files:

  • apps/web/content-collections.ts
🧬 Code graph analysis (1)
apps/web/src/routes/_view/roadmap.tsx (1)
packages/utils/src/cn.ts (1)
  • cn (20-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: ci (macos, macos-14)
  • GitHub Check: fmt
🔇 Additional comments (1)
apps/web/src/routes/_view/roadmap.tsx (1)

286-350: MDX rendering in RoadmapCard is correct; memoization looks appropriate.

Using useMemo(() => getMDXComponent(item.mdx.code), [item.mdx.code]) is a good way to avoid recompiling MDX on every render, and constraining the dependency to item.mdx.code avoids unnecessary recomputes. Label rendering with a cap (slice(0, compact ? 2 : 4)) plus a +N badge works well for dense cards.

No issues from a React/TS standpoint; this component should be performant enough for the expected roadmap size.

Comment on lines 352 to 375
function GitHubIssuePreview({ url }: { url: string }) {
return (
<div className="mt-3 pt-3 border-t border-neutral-100">
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className={cn([
"inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-medium",
config.bg,
config.border,
config.text,
"flex items-center gap-2 text-sm text-stone-500",
"hover:text-stone-700 transition-colors",
])}
>
<Icon icon={config.icon} />
<span>{config.label}</span>
<Icon icon="mdi:github" className="text-lg" />
<span>View on GitHub</span>
<Icon icon="mdi:open-in-new" className="text-xs" />
</a>
<div className="mt-2 rounded-sm overflow-hidden border border-neutral-200">
<iframe
src={url}
className="w-full h-[400px] bg-white"
title="GitHub Issue Preview"
sandbox="allow-same-origin allow-scripts"
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub X-Frame-Options CSP frame-ancestors headers third-party embedding policy

💡 Result:

Short answer: GitHub blocks third‑party embedding by default. It sends both X-Frame-Options and a CSP frame-ancestors policy (to cover older and newer browsers) that prevent framing of github.com pages, with only a few explicit exceptions (rendering endpoints, the Gist embed endpoint, and the GitHub Pages preview/related preview endpoints). Use the supported embed mechanisms (Gist embed script, GitHub Pages, or their allowed render endpoints) rather than trying to iframe github.com pages. [1][2][3]

Sources

  • GitHub engineering: “GitHub’s CSP journey” — explains using both X-Frame-Options + CSP frame-ancestors, default deny framing, and the limited exceptions (render domain, Gist embed, Pages preview). [1]
  • Gist embed documentation/examples — Gists are intended to be embedded via the provided embed script/endpoint. [2]
  • CSP/frame-ancestors overview (behavior and why it replaces X-Frame-Options). [3]

🏁 Script executed:

# Check the codebase for GitHubIssuePreview usage patterns and context
rg -n "GitHubIssuePreview" --type ts --type tsx -B 3 -A 3

Repository: fastrepl/hyprnote

Length of output: 88


🏁 Script executed:

# Search for any GitHub API integration or preview implementations
rg -n "github.*api\|api.*github" --type ts --type tsx -i -B 2 -A 2

Repository: fastrepl/hyprnote

Length of output: 88


🏁 Script executed:

# Check how many times GitHubIssuePreview might render and in what context
rg -n "GitHubIssuePreview\|iframe" apps/web/src/routes/_view/roadmap.tsx -B 2 -A 2

Repository: fastrepl/hyprnote

Length of output: 43


🏁 Script executed:

# Find the roadmap file
fd "roadmap" --type f

Repository: fastrepl/hyprnote

Length of output: 152


🏁 Script executed:

# Search for GitHubIssuePreview without specifying tsx type
rg -n "GitHubIssuePreview" -B 3 -A 3

Repository: fastrepl/hyprnote

Length of output: 1026


🏁 Script executed:

# Check repository structure
git ls-files apps/web/src/routes/ | head -20

Repository: fastrepl/hyprnote

Length of output: 906


🏁 Script executed:

# Read the complete GitHubIssuePreview function and surrounding context
sed -n '340,380p' apps/web/src/routes/_view/roadmap.tsx

Repository: fastrepl/hyprnote

Length of output: 1149


🏁 Script executed:

# Check if there's any lazy loading or optimization patterns elsewhere in the file
rg -n "lazy\|defer\|Suspense" apps/web/src/routes/_view/roadmap.tsx

Repository: fastrepl/hyprnote

Length of output: 43


🏁 Script executed:

# Understand the data structure - check how many github issues might be attached per item
rg -n "githubIssues\|github_issues" apps/web/src/routes/_view/roadmap.tsx -B 2 -A 2

Repository: fastrepl/hyprnote

Length of output: 43


GitHub iframe previews will be blocked by security headers and won't render; prefer lighter alternatives or API-based preview.

The web search confirmed that GitHub sends both X-Frame-Options and CSP frame-ancestors headers that deny framing of github.com pages. The only supported embedding mechanisms are the Gist embed script endpoint and GitHub Pages preview endpoints — direct issue page embedding is not allowed.

The current implementation attempts to embed full issue pages via iframe src={url} (line 365), which will fail silently with a blank iframe or security error. Additionally:

  • No lazy loading: Each iframe is a 400px-height resource loaded immediately, and item.githubIssues can contain multiple URLs, multiplying the performance impact.
  • No fallback UI: Users see nothing when the embed is blocked, degrading experience.
  • Permissive sandbox: The allow-same-origin allow-scripts attributes don't override browser security policies.

Recommended paths forward:

  • Remove the iframe entirely and rely on the "View on GitHub" link + metadata (simplest).
  • Fetch lightweight issue data via the GitHub API (title, state, comment count) and render as a card preview.
  • At minimum, add loading="lazy" and render only the first 1–2 previews per item to contain performance impact.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (3)
apps/web/src/routes/_view/roadmap/$slug.tsx (1)

48-70: Consider moving statusConfig outside the component.

This static configuration object is recreated on every render. Moving it to module scope avoids unnecessary allocations.

+const statusConfig = {
+  done: {
+    label: "Done",
+    icon: "mdi:check-circle",
+    iconColor: "text-green-600",
+    bgColor: "bg-green-50",
+    borderColor: "border-green-200",
+  },
+  "in-progress": {
+    label: "In Progress",
+    icon: "mdi:progress-clock",
+    iconColor: "text-blue-600",
+    bgColor: "bg-blue-50",
+    borderColor: "border-blue-200",
+  },
+  todo: {
+    label: "To Do",
+    icon: "mdi:calendar-clock",
+    iconColor: "text-neutral-400",
+    bgColor: "bg-neutral-50",
+    borderColor: "border-neutral-200",
+  },
+};
+
 function Component() {
   const { item } = Route.useLoaderData();
-
-  const statusConfig = {
-    done: { ... },
-    ...
-  };
apps/web/src/routes/_view/roadmap/index.tsx (2)

38-49: Consider simplifying or memoizing getRoadmapItems.

This function creates new array and objects on every call, and is invoked on each render (line 52). Since allRoadmaps is static, you can simplify by:

  1. Using allRoadmaps directly with a type assertion, or
  2. Memoizing the result at module scope
-function getRoadmapItems(): RoadmapItem[] {
-  return allRoadmaps.map((item) => ({
-    slug: item.slug,
-    title: item.title,
-    status: item.status,
-    labels: item.labels || [],
-    githubIssues: item.githubIssues || [],
-    created: item.created,
-    updated: item.updated,
-    mdx: item.mdx,
-  }));
-}
+const roadmapItems: RoadmapItem[] = allRoadmaps.map((item) => ({
+  slug: item.slug,
+  title: item.title,
+  status: item.status as RoadmapStatus,
+  labels: item.labels || [],
+  githubIssues: item.githubIssues || [],
+  created: item.created,
+  updated: item.updated,
+  mdx: item.mdx,
+}));

Then in Component:

 function Component() {
-  const items = getRoadmapItems();
+  const items = roadmapItems;

245-248: Consider extracting mobileLimit as a named constant.

For consistency with DEFAULT_VISIBLE_ITEMS (line 36), consider extracting this magic number.

 const DEFAULT_VISIBLE_ITEMS = 5;
+const MOBILE_VISIBLE_ITEMS = 3;
 
 // ...
 
 function ColumnSection({ ... }) {
   const [showAll, setShowAll] = useState(false);
-  const mobileLimit = 3;
-  const visibleItems = showAll ? items : items.slice(0, mobileLimit);
-  const hasMore = items.length > mobileLimit;
+  const visibleItems = showAll ? items : items.slice(0, MOBILE_VISIBLE_ITEMS);
+  const hasMore = items.length > MOBILE_VISIBLE_ITEMS;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6f8be2 and 9580974.

⛔ Files ignored due to path filters (1)
  • apps/web/src/routeTree.gen.ts is excluded by !**/*.gen.ts
📒 Files selected for processing (2)
  • apps/web/src/routes/_view/roadmap/$slug.tsx (1 hunks)
  • apps/web/src/routes/_view/roadmap/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/routes/_view/roadmap/$slug.tsx
  • apps/web/src/routes/_view/roadmap/index.tsx
🔇 Additional comments (8)
apps/web/src/routes/_view/roadmap/$slug.tsx (3)

1-8: LGTM!

Imports are well-organized and follow the coding guidelines. The cn utility is correctly imported from @hypr/utils.


10-43: LGTM!

Route definition is well-structured with proper 404 handling via notFound() and comprehensive SEO meta tags.


74-187: LGTM!

Well-structured component with proper semantic HTML (article, header, footer, time with dateTime), responsive design, and correct usage of the cn utility with array syntax as per coding guidelines.

apps/web/src/routes/_view/roadmap/index.tsx (5)

1-7: LGTM!

Imports are appropriate. The Link component is correctly used for internal navigation to the detail pages.


9-21: LGTM!

Route definition with appropriate meta tags for SEO. Since allRoadmaps is static content-collections data, client-side access is acceptable.


51-103: LGTM!

Component structure is clean with proper responsive handling. Both KanbanView and ColumnView are rendered with CSS-based visibility toggling, which is a standard responsive pattern.


105-199: LGTM!

Kanban view implementation is solid. The status prop is appropriately used for column border color styling. State management with useState for the show more/less toggle is appropriate for this simple UI interaction.


284-338: LGTM!

RoadmapCard correctly uses Link for internal navigation to detail pages. The label truncation logic with "+N more" indicator provides good UX for items with many labels.

@ComputelessComputer ComputelessComputer merged commit 3423779 into main Nov 28, 2025
10 of 11 checks passed
@ComputelessComputer ComputelessComputer deleted the devin/1764320910-roadmap-kanban-view branch November 28, 2025 16:32
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