Conversation
ComputelessComputer
commented
Nov 28, 2025
- Added category search and navigation support for templates
- Implemented detailed template view page with routing
- Restructured templates page using modular components
- Updated route configuration for templates and images
✅ Deploy Preview for hyprnote-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe PR restructures the templates route from a single file to a folder-based structure. It removes Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/web/src/routes/_view/templates/index.tsx (2)
58-69: Consider using TanStack Router'snavigateinstead ofwindow.history.pushState.Using
window.history.pushStatebypasses TanStack Router's state management. This can cause inconsistencies:
- The router won't be aware of the URL change
- Browser back/forward navigation may not work as expected
- The URL shows
/templates/{slug}but the actual route (/$slug.tsx) isn't loadedSince there's already a dedicated
$slug.tsxroute, consider either:
- Option A: Navigate to the actual route using
navigate({ to: '/templates/$slug', params: { slug: template.slug } })instead of showing a modal- Option B: Use search params for modal state (e.g.,
?preview=slug) to keep routing consistentconst handleTemplateClick = (template: (typeof allTemplates)[0]) => { setSelectedTemplate(template); - window.history.pushState({}, "", `/templates/${template.slug}`); + navigate({ + search: { ...search, preview: template.slug }, + resetScroll: false + }); }; const handleModalClose = useCallback(() => { setSelectedTemplate(null); - const url = selectedCategory - ? `/templates?category=${encodeURIComponent(selectedCategory)}` - : "/templates"; - window.history.pushState({}, "", url); + navigate({ + search: selectedCategory ? { category: selectedCategory } : {}, + resetScroll: false + }); }, [selectedCategory]);
485-589: Consider adding accessibility attributes to the modal.The modal works functionally but lacks accessibility attributes. For screen reader users:
- return ( - <div className="fixed inset-0 z-50"> + return ( + <div + className="fixed inset-0 z-50" + role="dialog" + aria-modal="true" + aria-labelledby="modal-title" + > <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} + aria-hidden="true" />And on Line 527:
- <h2 className="font-serif text-2xl sm:text-3xl text-stone-700 mb-3"> + <h2 id="modal-title" className="font-serif text-2xl sm:text-3xl text-stone-700 mb-3">
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
apps/web/src/routeTree.gen.tsis excluded by!**/*.gen.ts
📒 Files selected for processing (3)
apps/web/src/routes/_view/templates.tsx(0 hunks)apps/web/src/routes/_view/templates/$slug.tsx(1 hunks)apps/web/src/routes/_view/templates/index.tsx(1 hunks)
💤 Files with no reviewable changes (1)
- apps/web/src/routes/_view/templates.tsx
🧰 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, usecn(import from@hypr/utils). It is similar toclsx. Always pass an array and split by logical grouping.
Usemotion/reactinstead offramer-motion.
Files:
apps/web/src/routes/_view/templates/$slug.tsxapps/web/src/routes/_view/templates/index.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/templates/index.tsx (4)
apps/web/src/routes/_view/templates/$slug.tsx (1)
Route(10-39)apps/web/src/components/slash-separator.tsx (1)
SlashSeparator(1-8)packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/download-button.tsx (1)
DownloadButton(5-21)
⏰ 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). (5)
- GitHub Check: Redirect rules - hyprnote
- GitHub Check: Header rules - hyprnote
- GitHub Check: Pages changed - hyprnote
- GitHub Check: ci (macos, macos-14)
- GitHub Check: fmt
🔇 Additional comments (14)
apps/web/src/routes/_view/templates/$slug.tsx (5)
10-39: Route configuration looks good overall.The loader correctly handles the 404 case with
notFound(), and the meta tags are well-structured for SEO.One minor observation: Line 22 uses non-null assertion
loaderData!. While TanStack Router guaranteesloaderDataexists inheadwhen loader succeeds, the type assertion is acceptable here sincenotFound()prevents reachingheadon failure.
57-106: LGTM!The LeftSidebar correctly uses TanStack Router's
Linkwith search params for category navigation and standard anchor links for in-page navigation. The prop type is appropriately inlined.
108-181: LGTM!The main content area is well-structured with clear component composition. MDX rendering via
MDXContentis handled correctly. TheExamplesSectionplaceholder is appropriate for future implementation.
183-218: LGTM!The
SuggestedTemplatescomponent correctly filters same-category templates, excludes the current template, and gracefully returnsnullwhen empty. TheLinkusage withparamsfollows TanStack Router conventions.
234-277: LGTM!The
RightSidebarcorrectly usescnwith array syntax per coding guidelines. External links have propertarget="_blank"withrel="noopener noreferrer"for security.apps/web/src/routes/_view/templates/index.tsx (9)
12-42: LGTM!The route configuration correctly uses
validateSearchfor type-safe search params and provides appropriate SEO meta tags. TheTemplatesSearchtype is defined locally which aligns with the coding guidelines.
71-90: LGTM!Both
useEffecthooks are well-implemented with proper cleanup functions and correct dependency arrays. The body overflow control prevents background scrolling when modal is open.
92-113: LGTM!The
useMemohook correctly memoizes the filtered templates with appropriate dependencies. The filtering logic handles both category and search query.
151-211: LGTM!Both components are well-implemented.
ContributeBannercorrectly usescnwith array syntax.HeroSectionhas inline prop types as per coding guidelines. The search input is properly controlled.
223-263: LGTM!The mobile category navigation is well-implemented with horizontal scroll and proper active state styling. The
cnusage follows the coding guidelines.
265-351: LGTM!The
TemplatesSectionandDesktopSidebarcomponents are well-structured. The sticky sidebar positioning and category navigation work correctly. Allcncalls use array syntax per coding guidelines.
353-434: LGTM!Good implementations with proper empty state handling in
TemplatesGrid. Using<button>forTemplateCardis correct for accessibility. The target badge overflow handling with "+X more" is a nice UX touch.
436-483: LGTM!Both components are clean and follow the established patterns. External links have proper security attributes.
591-603: LGTM!The helper function correctly groups templates by category using a reduce pattern.