-
Notifications
You must be signed in to change notification settings - Fork 9
Enhancement the ui #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…gress indicator; update font weights and add parallax effects.
WalkthroughThe pull request introduces a comprehensive homepage redesign with new animations and interactive features: updated global CSS with custom animation keyframes and utility classes, a major app/page.tsx overhaul adding parallax effects, scroll progress tracking, and multiple new sections (How It Works, Why Better, Comparison, enhanced CTA), plus a configuration constant extraction in utils/config.ts. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ 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 |
There was a problem hiding this 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
🧹 Nitpick comments (5)
app/globals.css (2)
214-217: Consider accessibility forscroll-behavior: smooth.Users with vestibular disorders may experience discomfort with smooth scrolling. Consider respecting the
prefers-reduced-motionmedia query:/* Smooth scroll behavior */ html { - scroll-behavior: smooth; + scroll-behavior: smooth; +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } }
252-268: Custom scrollbar styling is webkit-only.Firefox users won't see the custom scrollbar. For broader support, add Firefox properties:
/* Custom scrollbar */ +* { + scrollbar-width: thin; + scrollbar-color: oklch(0.7 0.18 270) oklch(0.08 0 0); +} + ::-webkit-scrollbar { width: 10px; }app/page.tsx (3)
22-35: Performance: Consider throttling high-frequency event handlers.
mousemoveandscrollevents fire very frequently (60+ times/second), and each call triggerssetState, causing re-renders. This may cause jank on lower-end devices.Consider throttling these handlers:
import { useCallback, useRef } from 'react' // Inside component: const throttleRef = useRef<number>(0) const handleMouseMove = useCallback((e: MouseEvent) => { if (Date.now() - throttleRef.current > 16) { // ~60fps throttleRef.current = Date.now() setMousePosition({ x: e.clientX, y: e.clientY }) } }, [])
348-362: Cleanup: Remove redundant checkmark symbols from strings.The feature strings include "✓" characters, but you're also rendering
CheckCircle2icons. This creates redundancy and may confuse screen readers.{[ - "✓ Permissionless creation", - "✓ Built-in liquidity via bonding curves", + "Permissionless creation", + "Built-in liquidity via bonding curves", // ... etc ].map((feature, idx) => (Apply the same cleanup to the "Traditional Oracles" list (lines 373-388) which has both "✗" in strings and a separate
<span>with "✗".
440-446: Footer copyright year is hardcoded.The year "2025" will become stale. Consider making it dynamic:
- <p>© 2025 Orb Oracle. Decentralized price discovery for everyone.</p> + <p>© {new Date().getFullYear()} Orb Oracle. Decentralized price discovery for everyone.</p>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
app/globals.css(2 hunks)app/page.tsx(3 hunks)utils/config.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
utils/config.ts (1)
providers/web3-provider.js (1)
projectId(11-11)
app/page.tsx (2)
components/ui/button.tsx (1)
Button(59-59)components/ui/card.tsx (5)
Card(85-85)CardHeader(86-86)CardTitle(88-88)CardContent(91-91)CardDescription(90-90)
⏰ 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). (1)
- GitHub Check: Agent
🔇 Additional comments (2)
app/globals.css (1)
129-244: Animation utilities look well-structured.The keyframes and utility classes are cleanly organized with reasonable animation durations. The glassmorphism and text-gradient effects follow current design patterns.
app/page.tsx (1)
37-56: IntersectionObserver implementation looks solid.The observer setup with proper cleanup and the section visibility tracking pattern is well-implemented. The threshold of 0.1 is reasonable for triggering animations as sections come into view.
| // Parallax offset calculation | ||
| const parallaxOffset = { | ||
| x: (mousePosition.x - window.innerWidth / 2) / 50, | ||
| y: (mousePosition.y - window.innerHeight / 2) / 50 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSR error: window accessed during render phase.
Accessing window directly in the component body (outside useEffect) will crash during server-side rendering since window is undefined on the server.
// Parallax offset calculation
- const parallaxOffset = {
- x: (mousePosition.x - window.innerWidth / 2) / 50,
- y: (mousePosition.y - window.innerHeight / 2) / 50
- }
+ const parallaxOffset = mounted ? {
+ x: (mousePosition.x - (typeof window !== 'undefined' ? window.innerWidth : 0) / 2) / 50,
+ y: (mousePosition.y - (typeof window !== 'undefined' ? window.innerHeight : 0) / 2) / 50
+ } : { x: 0, y: 0 }Or better, store window dimensions in state updated via the existing useEffect.
📝 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.
| // Parallax offset calculation | |
| const parallaxOffset = { | |
| x: (mousePosition.x - window.innerWidth / 2) / 50, | |
| y: (mousePosition.y - window.innerHeight / 2) / 50 | |
| } | |
| // Parallax offset calculation | |
| const parallaxOffset = mounted ? { | |
| x: (mousePosition.x - (typeof window !== 'undefined' ? window.innerWidth : 0) / 2) / 50, | |
| y: (mousePosition.y - (typeof window !== 'undefined' ? window.innerHeight : 0) / 2) / 50 | |
| } : { x: 0, y: 0 } |
🤖 Prompt for AI Agents
In app/page.tsx around lines 63 to 67, the code reads
window.innerWidth/innerHeight during render which breaks SSR; instead add state
for viewport size (e.g., width and height) initialized to safe defaults (or
null) and update that state inside your existing useEffect that runs on mount
and on resize, then compute parallaxOffset using the state values (or fall back
to zero) so no direct window access happens during server render.
| <div className="absolute inset-0 z-0 overflow-hidden pointer-events-none"> | ||
| {[...Array(20)].map((_, i) => ( | ||
| <div | ||
| key={i} | ||
| className="absolute w-2 h-2 bg-primary/30 rounded-full animate-float" | ||
| style={{ | ||
| left: `${Math.random() * 100}%`, | ||
| top: `${Math.random() * 100}%`, | ||
| animationDelay: `${Math.random() * 3}s`, | ||
| animationDuration: `${3 + Math.random() * 4}s` | ||
| }} | ||
| /> | ||
| ))} | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hydration mismatch: Math.random() in render produces different values on server vs client.
The floating particles use Math.random() for positioning, which will generate different values during SSR and client hydration, causing React hydration errors.
{/* Floating particles effect */}
<div className="absolute inset-0 z-0 overflow-hidden pointer-events-none">
- {[...Array(20)].map((_, i) => (
+ {mounted && [...Array(20)].map((_, i) => (
<div
key={i}
className="absolute w-2 h-2 bg-primary/30 rounded-full animate-float"
style={{
- left: `${Math.random() * 100}%`,
- top: `${Math.random() * 100}%`,
- animationDelay: `${Math.random() * 3}s`,
- animationDuration: `${3 + Math.random() * 4}s`
+ left: `${(i * 17 + 5) % 100}%`,
+ top: `${(i * 23 + 7) % 100}%`,
+ animationDelay: `${(i * 0.15) % 3}s`,
+ animationDuration: `${3 + (i % 4)}s`
}}
/>
))}
</div>Using deterministic values based on index avoids hydration issues while still providing visual variety.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In app/page.tsx around lines 124 to 137, the floating particle positions use
Math.random() during render which differs between server and client causing
hydration mismatches; replace the non-deterministic Math.random() calls with
deterministic values derived from the particle index (e.g., a simple index-based
pseudo-random function or a seeded PRNG) or compute the random values once on
the client after mount and render a placeholder during SSR; ensure the
style.left/top/animationDelay/animationDuration are generated deterministically
from the index (or from client-only state populated in useEffect) so server and
client markup match.
| // Fallback project ID for development (get your own at https://cloud.walletconnect.com) | ||
| const projectId = process.env.NEXT_PUBLIC_PROJECT_ID || 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid committing placeholder/hardcoded project IDs to source control.
The fallback 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6' looks like a placeholder and will likely fail in production. Additionally, providers/web3-provider.js (line 10) has a different hardcoded project ID "be36d80bd82aef7bdb958bb467c3e570", creating inconsistency.
Consider:
- Throwing an error if
NEXT_PUBLIC_PROJECT_IDis missing in production - Consolidating project ID management to a single source
- Using
.env.exampleto document required environment variables
// Fallback project ID for development (get your own at https://cloud.walletconnect.com)
-const projectId = process.env.NEXT_PUBLIC_PROJECT_ID || 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
+const projectId = process.env.NEXT_PUBLIC_PROJECT_ID
+
+if (!projectId) {
+ throw new Error('NEXT_PUBLIC_PROJECT_ID environment variable is required')
+}📝 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.
| // Fallback project ID for development (get your own at https://cloud.walletconnect.com) | |
| const projectId = process.env.NEXT_PUBLIC_PROJECT_ID || 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6' | |
| // Fallback project ID for development (get your own at https://cloud.walletconnect.com) | |
| const projectId = process.env.NEXT_PUBLIC_PROJECT_ID | |
| if (!projectId) { | |
| throw new Error('NEXT_PUBLIC_PROJECT_ID environment variable is required') | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR significantly enhances the homepage UI by adding 12 major interactive features including scroll progress tracking, animated backgrounds, floating particles, mouse parallax effects, live stats, and comprehensive new content sections. The changes transform a simple landing page into an immersive, animated experience.
Key Changes
- Added interactive animations and effects (scroll progress bar, parallax, floating particles, gradient animations)
- Expanded homepage content with new sections: "How It Works", "Why Choose Orb Oracle", "Comparison", and enhanced CTA
- Implemented client-side state management for animations and scroll tracking with React hooks
- Added extensive custom CSS animations and effects
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 15 comments.
| File | Description |
|---|---|
| utils/config.ts | Added hardcoded fallback WalletConnect project ID for development environments |
| package-lock.json | Updated peer dependency flags for multiple packages |
| app/page.tsx | Converted to client component with extensive UI enhancements, animations, and new content sections |
| app/globals.css | Added custom keyframe animations, font weights, and styling utilities for interactive effects |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } from '@rainbow-me/rainbowkit' | ||
|
|
||
| // Fallback project ID for development (get your own at https://cloud.walletconnect.com) | ||
| const projectId = process.env.NEXT_PUBLIC_PROJECT_ID || 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6' |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hardcoded fallback project ID should not be committed to the repository. Even if it's a development fallback, hardcoding credentials in source code is a security risk. If this project ID is compromised or rate-limited, it affects all users of the application. Consider throwing an error in development when the environment variable is missing, or use a separate development configuration file that's gitignored.
| const handleMouseMove = (e: MouseEvent) => { | ||
| setMousePosition({ x: e.clientX, y: e.clientY }) | ||
| } | ||
|
|
||
| // Scroll progress tracking | ||
| const handleScroll = () => { | ||
| const totalHeight = document.documentElement.scrollHeight - window.innerHeight | ||
| const progress = (window.scrollY / totalHeight) * 100 | ||
| setScrollProgress(progress) | ||
| } | ||
|
|
||
| window.addEventListener('mousemove', handleMouseMove) | ||
| window.addEventListener('scroll', handleScroll) |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mouse move and scroll event listeners should be throttled or debounced to improve performance. On every mouse movement and scroll, React state is being updated, which triggers re-renders. This can cause performance issues, especially on lower-end devices. Consider using requestAnimationFrame or a throttle utility to limit the frequency of state updates.
| <div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 z-10 animate-bounce"> | ||
| <div className="w-6 h-10 border-2 border-primary/50 rounded-full flex justify-center"> | ||
| <div className="w-1 h-3 bg-primary rounded-full mt-2 animate-pulse"></div> | ||
| </div> | ||
| </div> |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This scroll indicator lacks accessibility attributes. The animated scroll indicator should have appropriate ARIA labels to inform screen reader users of its purpose. Consider adding role="presentation" or aria-hidden="true" since it's purely decorative, or add descriptive aria-label if it's meant to be interactive.
| <div className="bg-gradient-to-r from-primary via-purple-400 to-pink-400 bg-clip-text text-transparent animate-gradient"> | ||
| The Price of Everything | ||
| </div> |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The animated gradient text may have insufficient color contrast in certain states of the animation, which could make it difficult to read for users with visual impairments. The gradient uses primary, purple-400, and pink-400 colors which may not meet WCAG AA contrast requirements against the background. Consider testing the contrast ratio throughout the animation cycle or using a more contrasting color palette.
| <div className="absolute inset-0 z-0 overflow-hidden pointer-events-none"> | ||
| {[...Array(20)].map((_, i) => ( | ||
| <div | ||
| key={i} |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using array indices as React keys is an anti-pattern when the array is static and never changes. While this technically works for a static decorative array, it's better practice to generate stable unique IDs. This isn't critical for decorative elements but could lead to issues if the particle array is ever made dynamic.
| <div className="fixed top-0 left-0 w-full h-1 bg-transparent z-50"> | ||
| <div | ||
| className="h-full bg-gradient-to-r from-primary via-purple-400 to-primary transition-all duration-300" | ||
| style={{ width: `${scrollProgress}%` }} | ||
| /> | ||
| </div> |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scroll progress bar lacks semantic meaning and accessibility attributes. This purely visual indicator should have aria-hidden="true" to prevent screen readers from announcing it. Additionally, consider adding aria-live regions for significant scroll milestones if this information is important for users.
| {/* Footer */} | ||
| <footer className="border-t border-border py-8 relative z-10"> | ||
| <div className="container mx-auto px-4 text-center text-sm text-muted-foreground"> | ||
| <p>© 2025 Orb Oracle. Decentralized price discovery for everyone.</p> |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copyright year is hardcoded to 2025. This should be dynamically generated using new Date().getFullYear() to ensure it stays current as years pass, or use a range format like "2025-present" to avoid manual updates.
| <p>© 2025 Orb Oracle. Decentralized price discovery for everyone.</p> | |
| <p>© {new Date().getFullYear()} Orb Oracle. Decentralized price discovery for everyone.</p> |
| <div className="grid grid-cols-3 gap-6 max-w-2xl mx-auto mt-12"> | ||
| <div className="bg-card/30 backdrop-blur border border-primary/20 rounded-lg p-4 hover:bg-card/50 transition-all duration-300 hover:scale-105"> | ||
| <Rocket className="h-6 w-6 text-primary mx-auto mb-2" /> | ||
| <div className="text-2xl font-bold text-primary">∞</div> |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The infinite symbol "∞" used here might not be immediately clear to all users and lacks a proper semantic description. While the text "Permissionless" helps, consider adding a tooltip or aria-label to clarify what this symbol represents in context.
| <div className="text-2xl font-bold text-primary">∞</div> | |
| <div className="text-2xl font-bold text-primary" aria-label="Unlimited" title="Unlimited">∞</div> |
| @keyframes gradient { | ||
| 0%, 100% { | ||
| background-position: 0% 50%; | ||
| } | ||
| 50% { | ||
| background-position: 100% 50%; | ||
| } | ||
| } | ||
|
|
||
| @keyframes float { | ||
| 0%, 100% { | ||
| transform: translateY(0px); | ||
| } | ||
| 50% { | ||
| transform: translateY(-20px); | ||
| } | ||
| } | ||
|
|
||
| @keyframes pulse-glow { | ||
| 0%, 100% { | ||
| box-shadow: 0 0 20px rgba(168, 85, 247, 0.4); | ||
| } | ||
| 50% { | ||
| box-shadow: 0 0 40px rgba(168, 85, 247, 0.8); | ||
| } | ||
| } | ||
|
|
||
| @keyframes shimmer { | ||
| 0% { | ||
| background-position: -1000px 0; | ||
| } | ||
| 100% { | ||
| background-position: 1000px 0; | ||
| } | ||
| } | ||
|
|
||
| @keyframes slideInFromBottom { | ||
| 0% { | ||
| opacity: 0; | ||
| transform: translateY(30px); | ||
| } | ||
| 100% { | ||
| opacity: 1; | ||
| transform: translateY(0); | ||
| } | ||
| } | ||
|
|
||
| @keyframes scaleIn { | ||
| 0% { | ||
| opacity: 0; | ||
| transform: scale(0.9); | ||
| } | ||
| 100% { | ||
| opacity: 1; | ||
| transform: scale(1); | ||
| } | ||
| } | ||
|
|
||
| .animate-gradient { | ||
| background-size: 200% 200%; | ||
| animation: gradient 3s ease infinite; | ||
| } | ||
|
|
||
| .animate-float { | ||
| animation: float 3s ease-in-out infinite; | ||
| } | ||
|
|
||
| .animate-pulse-glow { | ||
| animation: pulse-glow 2s ease-in-out infinite; | ||
| } | ||
|
|
||
| .animate-shimmer { | ||
| animation: shimmer 2s linear infinite; | ||
| } | ||
|
|
||
| .animate-slide-in { | ||
| animation: slideInFromBottom 0.6s ease-out; | ||
| } | ||
|
|
||
| .animate-scale-in { | ||
| animation: scaleIn 0.5s ease-out; | ||
| } |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The custom animations defined here don't respect user motion preferences. All keyframe animations should include a prefers-reduced-motion media query to disable or reduce animations for users who have indicated motion sensitivity. This is important for accessibility and preventing discomfort or vestibular issues for users with motion disorders.
| ::-webkit-scrollbar { | ||
| width: 10px; | ||
| } | ||
|
|
||
| ::-webkit-scrollbar-track { | ||
| background: oklch(0.08 0 0); | ||
| } | ||
|
|
||
| ::-webkit-scrollbar-thumb { | ||
| background: oklch(0.7 0.18 270); | ||
| border-radius: 5px; | ||
| } | ||
|
|
||
| ::-webkit-scrollbar-thumb:hover { | ||
| background: oklch(0.6 0.15 270); | ||
| } |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Custom scrollbar styling only works in WebKit browsers (Chrome, Safari, Edge). Firefox users won't see these custom scrollbar styles. Consider adding Firefox-compatible scrollbar styling using 'scrollbar-width' and 'scrollbar-color' properties to ensure a consistent experience across browsers.
Major Enhancements Added:
Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.