feat(contacts): add image carousel and update section description#2171
feat(contacts): add image carousel and update section description#2171ComputelessComputer merged 2 commits intomainfrom
Conversation
📝 WalkthroughWalkthroughReplaces NoteshelfSection with a FoldersSection, converts ContactsSection to an auto-rotating image carousel, adds an AdvancedSearchSection image-swiper with progress-based autoplay and pause-on-hover, standardizes list icons to CheckIcon, and adds "Coming soon" badges and copy updates across the mini-apps page. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (3 warnings)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyprnote-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/src/routes/_view/product/mini-apps.tsx (1)
77-127: Add accessibility controls for auto-rotating carousel.The auto-rotating carousel lacks essential accessibility features:
- No pause/play controls (violates WCAG 2.2.2 - users cannot pause auto-updating content)
- No keyboard navigation (arrow keys to switch images)
- No screen reader announcements when images change
- No visual indicators for current slide position
Consider adding:
- Pause/play button for user control
- Keyboard event handlers for arrow key navigation
aria-live="polite"region to announce image changes- Visual indicators (dots) showing current position
function ContactsSection() { const [currentImage, setCurrentImage] = useState(0); + const [isPaused, setIsPaused] = useState(false); const images = [ "/api/images/hyprnote/mini-apps/contacts-human.jpg", "/api/images/hyprnote/mini-apps/contacts-org.jpg", ]; useEffect(() => { + if (isPaused) return; const interval = setInterval(() => { setCurrentImage((prev) => (prev + 1) % images.length); }, 4000); return () => clearInterval(interval); - }, [images.length]); + }, [images.length, isPaused]);Additionally, add pause/play button and keyboard handlers in the JSX.
🧹 Nitpick comments (1)
apps/web/src/routes/_view/product/mini-apps.tsx (1)
536-568: Improve accessibility with proper ARIA tablist pattern.The tab interface should use the proper ARIA pattern for better screen reader support and keyboard navigation.
Add ARIA attributes and keyboard handlers:
- <div className="grid md:grid-cols-3 border-y border-neutral-100"> + <div + className="grid md:grid-cols-3 border-y border-neutral-100" + role="tablist" + aria-label="Search feature examples" + > {images.map((image, index) => ( <button key={image.id} + role="tab" + aria-selected={selectedImage === image.id} + aria-controls={`search-panel-${image.id}`} className={cn([ "text-center cursor-pointer transition-colors relative overflow-hidden", index < images.length - 1 && "border-r border-neutral-100", ])}Also consider adding visual focus indicators for keyboard navigation.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/src/routes/_view/product/mini-apps.tsx(12 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, 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/product/mini-apps.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/product/mini-apps.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). (8)
- GitHub Check: Redirect rules - hyprnote-storybook
- GitHub Check: Header rules - hyprnote-storybook
- GitHub Check: Pages changed - hyprnote-storybook
- GitHub Check: Redirect rules - hyprnote
- GitHub Check: Header rules - hyprnote
- GitHub Check: Pages changed - hyprnote
- GitHub Check: fmt
- GitHub Check: ci
🔇 Additional comments (4)
apps/web/src/routes/_view/product/mini-apps.tsx (4)
142-158: LGTM! CheckIcon updates and "Coming soon" badges improve visual consistency.The replacement of generic icon components with CheckIcon from lucide-react provides better visual consistency. The addition of "Coming soon" badges in DailyNotesSection clearly communicates feature availability to users.
Also applies to: 210-226, 284-309, 331-356
369-449: LGTM! FoldersSection properly replaces NoteshelfSection.The section rename and content updates are well-implemented with consistent styling and layout patterns matching other sections.
600-601: LGTM! CTA text updated to reflect folders feature.The text update correctly mentions folders alongside contacts and calendar, aligning with the new FoldersSection.
3-4: LGTM! Imports and utility usage follow coding guidelines.The imports are appropriate and the
cnutility is correctly used with arrays throughout the file, consistent with the coding guidelines.Also applies to: 6-6
9860bf5 to
9609825
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/src/routes/_view/product/mini-apps.tsx (1)
80-91: Moveimagesarray outside component for consistency.The
imagesarray is defined inside the component, creating a new reference on each render. Whileimages.lengthas a dependency is stable, this pattern was already fixed inAdvancedSearchSectionby moving the array to module scope. Apply the same pattern here for consistency.+const CONTACTS_IMAGES = [ + "/api/images/hyprnote/mini-apps/contacts-human.jpg", + "/api/images/hyprnote/mini-apps/contacts-org.jpg", +]; + function ContactsSection() { const [currentImage, setCurrentImage] = useState(0); - const images = [ - "/api/images/hyprnote/mini-apps/contacts-human.jpg", - "/api/images/hyprnote/mini-apps/contacts-org.jpg", - ]; - useEffect(() => { const interval = setInterval(() => { - setCurrentImage((prev) => (prev + 1) % images.length); + setCurrentImage((prev) => (prev + 1) % CONTACTS_IMAGES.length); }, 4000); return () => clearInterval(interval); - }, [images.length]); + }, []);Then update the
images.mapcall on line 109 to useCONTACTS_IMAGES.map.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/src/routes/_view/product/mini-apps.tsx(11 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, 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/product/mini-apps.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/product/mini-apps.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). (8)
- GitHub Check: Redirect rules - hyprnote-storybook
- GitHub Check: Header rules - hyprnote-storybook
- GitHub Check: Pages changed - hyprnote-storybook
- GitHub Check: Redirect rules - hyprnote
- GitHub Check: Header rules - hyprnote
- GitHub Check: Pages changed - hyprnote
- GitHub Check: ci
- GitHub Check: fmt
🔇 Additional comments (8)
apps/web/src/routes/_view/product/mini-apps.tsx (8)
1-6: LGTM!Imports are appropriate for the new carousel functionality and icon standardization.
142-158: LGTM!Icon standardization to
CheckIconis consistent and properly styled.
284-309: LGTM!The "Coming soon" badges are appropriately styled and consistently applied across all feature items in both desktop and mobile views.
369-449: LGTM!Clean section rename from NoteshelfSection to FoldersSection with appropriate content updates and consistent styling.
451-473: Past review feedback addressed.The
advancedSearchImagesarray andADVANCED_SEARCH_AUTO_ADVANCE_DURATIONconstant have been correctly moved to module scope, preventing unnecessary re-renders and animation resets.
481-519: LGTM!The
requestAnimationFrame-based animation with pause/resume support is well-implemented. UsingprogressRefto preserve progress state across pause cycles is a good pattern.
538-569: LGTM!The tab rendering with progress overlay and pause-on-hover is well-implemented. The
cnusage follows the coding guidelines with array format for logical grouping.
604-605: LGTM!CTA copy appropriately updated to reflect the new folders terminology.
Description