Feat/social icons clickable - #69
Conversation
…JSDoc to components for doc coverage
📝 WalkthroughWalkthroughThis PR implements dark mode support throughout the landing page by adding class-based Tailwind dark mode configuration, introducing a new ThemeToggle component for theme switching, applying dark-mode-aware styling across all UI components and sections, refactoring background animations, modernizing navigation links to Next.js Routes, adding social sharing functionality, and including license documentation. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant ThemeToggle as ThemeToggle Component
participant DOM as document.documentElement
participant Storage as localStorage
participant CSS as Tailwind CSS
User->>ThemeToggle: Click toggle button
ThemeToggle->>ThemeToggle: Update theme state ('light'/'dark')
ThemeToggle->>DOM: Add/remove 'dark' class
ThemeToggle->>Storage: Persist theme selection
DOM->>CSS: Trigger dark: variants
CSS->>CSS: Apply theme-aware colors & transitions
CSS-->>User: Visual theme update with animations
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/app/layout.tsx (1)
46-58:⚠️ Potential issue | 🟡 MinorDark mode users may experience a theme flash on initial load.
With
darkMode: 'class'and the default being light mode (bg-white text-black), users who prefer dark mode will briefly see the light theme beforeThemeToggle'suseEffectruns and applies thedarkclass. This happens because React hydration completes before the effect runs.To prevent the flash, consider adding an inline script in
<head>that synchronously sets thedarkclass based onlocalStorageorprefers-color-schemebefore the first paint:💡 Example inline script approach
<html lang="en"> <head> <script dangerouslySetInnerHTML={{ __html: ` (function() { const theme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); if (theme === 'dark') document.documentElement.classList.add('dark'); })(); `, }} /> </head> ...src/sections/CallToAction.tsx (1)
60-79:⚠️ Potential issue | 🟠 MajorBackground horizontal animation may be broken after refactor.
The
animate={{ backgroundPositionX }}is still on the parentmotion.div(lines 63-65), but thebackgroundImagewas moved to the nestedmotion.div(lines 73-78). SincebackgroundPositionXonly affects the element's own background, the star animation no longer applies to the visible background layer.Move the animation props to the nested div:
🐛 Proposed fix
<motion.div ref={borderedDivRef} className="border border-black/15 dark:border-white/15 py-12 sm:py-16 md:py-24 rounded-xl overflow-hidden relative group transition-colors duration-500 bg-white dark:bg-black" - animate={{ - backgroundPositionX: startBg.width, - }} - transition={{ - repeat: Infinity, - duration: 60, - ease: 'linear', - }} > {/* Animated Background */} <motion.div className="absolute inset-0 -z-20 invert opacity-40 dark:invert-0 dark:opacity-100 transition-all duration-500 pointer-events-none" style={{ backgroundImage: `url(${startBg.src})`, backgroundPositionY: backgroundPositionY, }} + animate={{ + backgroundPositionX: startBg.width, + }} + transition={{ + repeat: Infinity, + duration: 60, + ease: 'linear', + }} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sections/CallToAction.tsx` around lines 60 - 79, The animated background was moved into the nested motion.div so the animate prop on the parent motion.div (the element using borderedDivRef) no longer affects it; move the animate and transition props (currently using backgroundPositionX and duration/ease/repeat) from the parent motion.div to the nested motion.div that sets style.backgroundImage (the element using startBg.src and backgroundPositionY) so the star background animation targets the actual visible layer, keeping the same backgroundPositionX value source (startBg.width) and existing transition config.
🧹 Nitpick comments (3)
src/sections/LogoTicker.tsx (1)
12-15: Duplicate entries initemsarray create redundant rendering.The items array contains duplicate entries (each logo appears twice). While this may be intentional for the ticker visual effect, the duplication is already handled by the second
items.map()loop at lines 47-55. Consider whether four unique items were intended, or if this duplication is accidental.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sections/LogoTicker.tsx` around lines 12 - 15, The items array in the LogoTicker component currently contains duplicate entries which combined with the second items.map() duplication causes logos to render twice; update the items array (the items constant) to contain only the unique logo entries you intend to show, or if the visual effect relies on programmatic duplication remove the repeated literal entries and keep the duplication in the rendering logic (the items.map() usage inside LogoTicker) so each logo appears the intended number of times—adjust the items array (and/or the second items.map() call) accordingly to eliminate accidental redundancy.src/sections/Features.tsx (1)
73-73: Unusedgroupclass.The
groupclass was added to theFeatureTabcontainer, but there don't appear to be anygroup-*:variant utilities in the child elements. If grouped state styling is planned for a future iteration, this is fine; otherwise, it can be removed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sections/Features.tsx` at line 73, The FeatureTab container's className includes the Tailwind "group" utility but no child elements use any "group-*" variants; remove the "group" token from the className on the FeatureTab container (the JSX element with className that currently contains "group") to avoid an unused utility, or if you intended grouped state styling, add appropriate "group-*" classes to the relevant child elements instead; locate the className on the FeatureTab container in src/sections/Features.tsx and either delete "group" or add matching child "group-hover:" / "group-focus:" variants.src/sections/Header.tsx (1)
2-2: Remove the orphaned logo file.The logo import was changed from
@/assets/logo.svgto@/assets/svg/logo.svg. The old file atsrc/assets/logo.svgis no longer referenced anywhere in the codebase and should be removed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sections/Header.tsx` at line 2, Remove the unused/orphaned logo asset that remains after changing the import in Header.tsx (the old import string '@/assets/logo.svg' is no longer referenced); delete that old logo file from the repository so only the new import used by Header.tsx (import Logo from '@/assets/svg/logo.svg') remains and no orphaned asset is left behind.
🤖 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/components/ThemeToggle.tsx`:
- Around line 11-21: The page flashes light because ThemeToggle sets theme only
after mount while layout.tsx renders light classes; fix by adding a synchronous
inline script in the document head that reads localStorage and matchMedia and
applies document.documentElement.classList.add('dark') when appropriate, and set
suppressHydrationWarning on the <html> element in layout.tsx so React won't warn
on the mismatch; keep ThemeToggle (function ThemeToggle) as client-side state
but rely on the head script to set the initial class before hydration.
In `@src/sections/Footer.tsx`:
- Around line 50-58: The YouTube anchor in Footer.tsx currently uses a
placeholder href ("https://www.youtube.com"); update the href on the <a>
wrapping the YTSocial component to point to the actual Djed Alliance YouTube
channel URL (replace the placeholder href value in the anchor that contains
YTSocial with the correct channel link), keeping target, rel, aria-label and
classes unchanged.
- Around line 21-29: The footer currently uses Link components pointing to
non-existent routes (href="/features", "/docs", "/blog") which will 404; either
create corresponding route pages (e.g., add src/app/features/page.tsx,
src/app/docs/page.tsx, src/app/blog/page.tsx exporting React components) or
change the Link hrefs in Footer.tsx to anchor links used for in-page navigation
(replace "/features" with "#features", "/docs" with "#docs", "/blog" with
"#blog") so they match Header.tsx behavior; update the three Link elements (the
ones with className including "text-black/70 ... text-xs sm:text-sm")
accordingly and ensure any anchor targets exist in the page.
In `@src/sections/LogoTicker.tsx`:
- Around line 40-42: The SVGs used by LogoComp in LogoTicker.tsx have hardcoded
fill colors so the tailwind classes (fill-current text-black dark:text-white)
don't change their color; update the SVG asset files in src/assets/ (e.g.,
stability-nexus.svg, djed-alliance.svg) to use fill="currentColor" (or remove
fill attributes) and for any gradients (fill="url(`#g`)") convert gradient stop
colors to use stop-color="currentColor" (or define the gradient stops to
reference currentColor) so the LogoComp's className can control color, and
ensure LogoComp forwards the className prop onto the root <svg> element so the
tailwind color classes apply.
---
Outside diff comments:
In `@src/sections/CallToAction.tsx`:
- Around line 60-79: The animated background was moved into the nested
motion.div so the animate prop on the parent motion.div (the element using
borderedDivRef) no longer affects it; move the animate and transition props
(currently using backgroundPositionX and duration/ease/repeat) from the parent
motion.div to the nested motion.div that sets style.backgroundImage (the element
using startBg.src and backgroundPositionY) so the star background animation
targets the actual visible layer, keeping the same backgroundPositionX value
source (startBg.width) and existing transition config.
---
Nitpick comments:
In `@src/sections/Features.tsx`:
- Line 73: The FeatureTab container's className includes the Tailwind "group"
utility but no child elements use any "group-*" variants; remove the "group"
token from the className on the FeatureTab container (the JSX element with
className that currently contains "group") to avoid an unused utility, or if you
intended grouped state styling, add appropriate "group-*" classes to the
relevant child elements instead; locate the className on the FeatureTab
container in src/sections/Features.tsx and either delete "group" or add matching
child "group-hover:" / "group-focus:" variants.
In `@src/sections/Header.tsx`:
- Line 2: Remove the unused/orphaned logo asset that remains after changing the
import in Header.tsx (the old import string '@/assets/logo.svg' is no longer
referenced); delete that old logo file from the repository so only the new
import used by Header.tsx (import Logo from '@/assets/svg/logo.svg') remains and
no orphaned asset is left behind.
In `@src/sections/LogoTicker.tsx`:
- Around line 12-15: The items array in the LogoTicker component currently
contains duplicate entries which combined with the second items.map()
duplication causes logos to render twice; update the items array (the items
constant) to contain only the unique logo entries you intend to show, or if the
visual effect relies on programmatic duplication remove the repeated literal
entries and keep the duplication in the rendering logic (the items.map() usage
inside LogoTicker) so each logo appears the intended number of times—adjust the
items array (and/or the second items.map() call) accordingly to eliminate
accidental redundancy.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d2d19048-fba3-4553-9dcd-ed2c28583919
⛔ Files ignored due to path filters (5)
src/app/apple-touch-icon.svgis excluded by!**/*.svgsrc/app/favicon.svgis excluded by!**/*.svgsrc/assets/djed-alliance.svgis excluded by!**/*.svgsrc/assets/stability-nexus.svgis excluded by!**/*.svgsrc/assets/svg/logo.svgis excluded by!**/*.svg
📒 Files selected for processing (12)
License.mdsrc/app/layout.tsxsrc/app/page.tsxsrc/components/Button.tsxsrc/components/ThemeToggle.tsxsrc/sections/CallToAction.tsxsrc/sections/Features.tsxsrc/sections/Footer.tsxsrc/sections/Header.tsxsrc/sections/Hero.tsxsrc/sections/LogoTicker.tsxtailwind.config.ts
| export default function ThemeToggle() { | ||
| const [theme, setTheme] = useState<'light' | 'dark'>('dark'); | ||
| const [mounted, setMounted] = useState(false); | ||
|
|
||
| // Read initial theme and apply classes | ||
| useEffect(() => { | ||
| setMounted(true); | ||
| const storedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null; | ||
| const initialTheme = storedTheme || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); | ||
| setTheme(initialTheme); | ||
| }, []); |
There was a problem hiding this comment.
Flash of light theme on page load for dark-mode users.
The component correctly defers theme application until after mount, but src/app/layout.tsx renders with light-mode classes (bg-white text-black) and lacks a blocking script to synchronize the dark class before React hydrates. Users with a stored dark preference or prefers-color-scheme: dark will see a flash of light theme.
To fix, add an inline script in <head> (or on <html>) that reads localStorage / matchMedia and applies the dark class synchronously, plus add suppressHydrationWarning to <html>:
// In layout.tsx <html> tag:
<html lang="en" suppressHydrationWarning>
<head>
<script dangerouslySetInnerHTML={{ __html: `
(function() {
const theme = localStorage.getItem('theme') ||
(matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
if (theme === 'dark') document.documentElement.classList.add('dark');
})();
`}} />
</head>
...
</html>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/ThemeToggle.tsx` around lines 11 - 21, The page flashes light
because ThemeToggle sets theme only after mount while layout.tsx renders light
classes; fix by adding a synchronous inline script in the document head that
reads localStorage and matchMedia and applies
document.documentElement.classList.add('dark') when appropriate, and set
suppressHydrationWarning on the <html> element in layout.tsx so React won't warn
on the mismatch; keep ThemeToggle (function ThemeToggle) as client-side state
but rely on the head script to set the initial class before hydration.
| <Link href="/features" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | ||
| Features | ||
| </a> | ||
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | ||
| </Link> | ||
| <Link href="/docs" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | ||
| Docs | ||
| </a> | ||
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | ||
| </Link> | ||
| <Link href="/blog" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | ||
| Blog | ||
| </a> | ||
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | ||
| Github | ||
| </Link> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify that no page routes exist for /features, /docs, /blog
echo "Checking for route files in src/app/..."
fd -t f 'page\.(tsx|ts|js|jsx)' src/app/ 2>/dev/null || echo "fd not found, using find"
find src/app -name 'page.*' -type f 2>/dev/null
echo ""
echo "Checking for features, docs, blog directories..."
ls -la src/app/features 2>/dev/null || echo "No src/app/features directory"
ls -la src/app/docs 2>/dev/null || echo "No src/app/docs directory"
ls -la src/app/blog 2>/dev/null || echo "No src/app/blog directory"Repository: DjedAlliance/StablePay-LandingPage
Length of output: 283
Routes /features, /docs, and /blog do not exist.
The Link components point to /features, /docs, and /blog routes, but only src/app/page.tsx exists. These routes will return 404 errors when clicked.
Create the missing route files or use anchor links (#features, etc.) for in-page navigation, consistent with Header.tsx.
Proposed fix using anchor links
- <Link href="/features" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
+ <a href="#features" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
Features
- </Link>
- <Link href="/docs" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
+ </a>
+ <a href="https://docs.example.com" target="_blank" rel="noreferrer" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
Docs
- </Link>
- <Link href="/blog" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
+ </a>
+ <a href="https://blog.example.com" target="_blank" rel="noreferrer" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300">
Blog
- </Link>
+ </a>📝 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.
| <Link href="/features" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Features | |
| </a> | |
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | |
| </Link> | |
| <Link href="/docs" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Docs | |
| </a> | |
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | |
| </Link> | |
| <Link href="/blog" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Blog | |
| </a> | |
| <a href="#" className="text-white/70 hover:text-white text-xs sm:text-sm transition"> | |
| Github | |
| </Link> | |
| <a href="#features" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Features | |
| </a> | |
| <a href="https://docs.example.com" target="_blank" rel="noreferrer" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Docs | |
| </a> | |
| <a href="https://blog.example.com" target="_blank" rel="noreferrer" className="text-black/70 hover:text-black dark:text-white/70 dark:hover:text-white text-xs sm:text-sm transition-colors duration-300"> | |
| Blog | |
| </a> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/sections/Footer.tsx` around lines 21 - 29, The footer currently uses Link
components pointing to non-existent routes (href="/features", "/docs", "/blog")
which will 404; either create corresponding route pages (e.g., add
src/app/features/page.tsx, src/app/docs/page.tsx, src/app/blog/page.tsx
exporting React components) or change the Link hrefs in Footer.tsx to anchor
links used for in-page navigation (replace "/features" with "#features", "/docs"
with "#docs", "/blog" with "#blog") so they match Header.tsx behavior; update
the three Link elements (the ones with className including "text-black/70 ...
text-xs sm:text-sm") accordingly and ensure any anchor targets exist in the
page.
| <a | ||
| href="https://www.youtube.com" | ||
| target="_blank" | ||
| rel="noreferrer" | ||
| aria-label="Djed Alliance on YouTube" | ||
| className="text-black/40 hover:text-black dark:text-white/40 dark:hover:text-white transition-colors duration-300" | ||
| > | ||
| <YTSocial className="w-5 h-5 sm:w-6 sm:h-6" /> | ||
| </a> |
There was a problem hiding this comment.
YouTube link appears to be a placeholder.
The YouTube link points to the generic https://www.youtube.com rather than the actual Djed Alliance channel. Update this to the correct channel URL before merging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/sections/Footer.tsx` around lines 50 - 58, The YouTube anchor in
Footer.tsx currently uses a placeholder href ("https://www.youtube.com"); update
the href on the <a> wrapping the YTSocial component to point to the actual Djed
Alliance YouTube channel URL (replace the placeholder href value in the anchor
that contains YTSocial with the correct channel link), keeping target, rel,
aria-label and classes unchanged.
| <div key={index} className="flex items-center gap-2 text-black dark:text-white transition-colors duration-500"> | ||
| <LogoComp className="h-5 w-5 sm:h-6 sm:w-6 fill-current text-black dark:text-white transition-colors duration-500" /> | ||
| <span className="text-xs sm:text-sm font-medium">{item.label}</span> |
There was a problem hiding this comment.
SVG logos use hardcoded fill colors — fill-current will have no effect.
The fill-current text-black dark:text-white classes on LogoComp will not affect the SVG colors. Based on the SVG files in src/assets/:
stability-nexus.svgusesfill="#fff"andfill="url(#g)"(gradient)djed-alliance.svgusesfill="#1F2937",fill="#F59E0B",fill="#fff"
These hardcoded colors mean the logos will not respond to theme changes. If theme-aware coloring is desired, the SVG files need to use currentColor for their fill values.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/sections/LogoTicker.tsx` around lines 40 - 42, The SVGs used by LogoComp
in LogoTicker.tsx have hardcoded fill colors so the tailwind classes
(fill-current text-black dark:text-white) don't change their color; update the
SVG asset files in src/assets/ (e.g., stability-nexus.svg, djed-alliance.svg) to
use fill="currentColor" (or remove fill attributes) and for any gradients
(fill="url(`#g`)") convert gradient stop colors to use stop-color="currentColor"
(or define the gradient stops to reference currentColor) so the LogoComp's
className can control color, and ensure LogoComp forwards the className prop
onto the root <svg> element so the tailwind color classes apply.
Addressed Issues:
Fixes #38
Made social icons clickable and added sharing buttons to improve usability.
Summary by CodeRabbit
New Features
Style
Documentation
Chores