Skip to content

Feat: To add topbar Arrow that auto scroll-up on home page .#56

Open
AayushSahani01 wants to merge 7 commits intoCoderUzumaki:mainfrom
AayushSahani01:Bug
Open

Feat: To add topbar Arrow that auto scroll-up on home page .#56
AayushSahani01 wants to merge 7 commits intoCoderUzumaki:mainfrom
AayushSahani01:Bug

Conversation

@AayushSahani01
Copy link
Copy Markdown

@AayushSahani01 AayushSahani01 commented Aug 2, 2025

Summary by CodeRabbit

  • New Features

    • Theme toggle with persistent preference (dark/light modes).
    • Top progress bar showing page scroll progress.
    • Floating “back to top” button with smooth scrolling.
  • Style

    • Updated global colors to support dark and light themes.
  • Chores

    • Added styled-components as a runtime dependency.

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 2, 2025

@AayushSahani01 is attempting to deploy a commit to the coderuzumaki's projects Team on Vercel.

A member of the Team first needs to authorize it.

@AayushSahani01
Copy link
Copy Markdown
Author

hey @CoderUzumaki , 👍🏻
Can you reviews the code and merged it.

  • Thankyou

@hudazaan
Copy link
Copy Markdown
Collaborator

hudazaan commented Aug 2, 2025

Hey @AayushSahani01,
This Pull Request doesn't follow the PR template. Update your PR description to match the required format.
Also, add a screen recording of your implemented changes.

@AayushSahani01
Copy link
Copy Markdown
Author

Hey I'm also added this issues on raised PR request #56 both feature added as theme toggle & arrow functionality !

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Sep 14, 2025

Walkthrough

Adds styled-components dependency, introduces ThemeToggle and TopBar components, updates global styles for dark/light themes, and makes a whitespace-only edit in App.jsx. ThemeToggle manages theme via localStorage and a DOM class. TopBar shows a scroll progress bar and a back-to-top button using styled-components.

Changes

Cohort / File(s) Summary
Dependency Update
client/package.json
Adds runtime dependency "styled-components": "^6.1.19" under dependencies.
New UI Components
client/src/components/ThemeToggle.jsx, client/src/components/TopBar.jsx
Adds ThemeToggle (persisted dark/light toggle via localStorage and document.documentElement.classList) and OnTopBar (scroll progress bar and back-to-top button) components; TopBar uses styled-components for styling and window scroll listeners.
Global Styles
client/src/styles/index.css
Adds dark/light theme CSS: defaults dark on body; .dark inverses colors.
Minor Non-functional Edit
client/src/App.jsx
Inserts an empty line inside the component; no functional changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant ThemeToggle as ThemeToggle
  participant DOM as document.documentElement
  participant LS as localStorage

  rect rgb(235,245,255)
  note right of ThemeToggle: Mount/init
  ThemeToggle->>LS: getItem("theme")
  alt theme === "dark"
    ThemeToggle->>DOM: add "dark" class
    ThemeToggle->>ThemeToggle: set isDarkMode = true
  else
    ThemeToggle->>ThemeToggle: set isDarkMode = false
  end
  end

  User->>ThemeToggle: click toggle
  alt isDarkMode -> light
    ThemeToggle->>DOM: remove "dark" class
    ThemeToggle->>LS: setItem("theme","light")
    ThemeToggle->>ThemeToggle: set isDarkMode = false
  else light -> dark
    ThemeToggle->>DOM: add "dark" class
    ThemeToggle->>LS: setItem("theme","dark")
    ThemeToggle->>ThemeToggle: set isDarkMode = true
  end
Loading
sequenceDiagram
  autonumber
  participant Window as window
  participant TopBar as OnTopBar
  participant Doc as document.documentElement

  note right of TopBar: Mount
  Window-->>TopBar: addEventListener("scroll", handler)

  Window->>TopBar: scroll event (repeat)
  TopBar->>Doc: read scrollTop, scrollHeight, clientHeight
  TopBar->>TopBar: update scrollProgress, isVisible

  TopBar->>Window: onClick "to top" -> window.scroll({top:0, behavior:"smooth"})

  note right of TopBar: Unmount
  Window-->>TopBar: removeEventListener("scroll", handler)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A nibble of styles, a toggle of light,
I bounce on the scroll bar, measuring height.
With moon and sun I flip the scene,
Styled bits shimmer, tidy and clean.
Tap—whoosh!—to the top I hop,
A happy bun shipping a polished prop. 🐇✨

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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title explicitly describes the primary feature — adding a topbar arrow that auto-scrolls the home page — which matches the TopBar/scroll-to-top functionality in the changeset, so it conveys the main change to reviewers; it is specific and not generic. It is slightly awkwardly worded and does not mention the added theme toggle or dependency, but a title need not enumerate every change.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

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

@AayushSahani01
Copy link
Copy Markdown
Author

Hey @CoderUzumaki, Can you please review the code and merge it to the main branch

Copy link
Copy Markdown

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

🧹 Nitpick comments (6)
client/src/App.jsx (1)

31-31: Remove stray blank line.

Keeps diffs clean and avoids noise in future blame.

-  );
-}
+  );
+}
client/src/components/ThemeToggle.jsx (1)

27-31: Tailwind class 'hover:transform-fill' is invalid.

Replace with supported utilities; also add accessible labeling.

-<button onClick={toggleTheme} className="p-1 cursor-pointer hover:bg-slate-500 rounded-lg transition-colors duration-300">
+<button
+  onClick={toggleTheme}
+  aria-label={isDarkMode ? 'Switch to light theme' : 'Switch to dark theme'}
+  className="p-1 cursor-pointer hover:bg-slate-500 rounded-lg transition-colors duration-300"
+>
-  {!isDarkMode ?  (<Sun className="h-6 w-6 text-yellow-300"/>) : (<Moon className="h-6 w-6 text-blue-700 hover:transform-fill"/>)}
+  {!isDarkMode ? (
+    <Sun className="h-6 w-6 text-yellow-300" />
+  ) : (
+    <Moon className="h-6 w-6 text-blue-700" />
+  )}
client/src/components/TopBar.jsx (4)

6-7: State naming nit: use isVisible to match setter.

Improves readability.

-const [isvisible, setIsVisible] = React.useState(false);
+const [isVisible, setIsVisible] = React.useState(false);

Also update usages of isvisible accordingly.


32-37: Use passive listener and initialize on mount.

Better scroll perf and correct initial render.

-useEffect(() => {
-  window.addEventListener("scroll", handleScroll);
-  return () => {
-    window.removeEventListener("scroll", handleScroll);
-  };
-}, []);
+useEffect(() => {
+  window.addEventListener("scroll", handleScroll, { passive: true });
+  handleScroll();
+  return () => window.removeEventListener("scroll", handleScroll);
+}, []); // handleScroll is stable within this component

57-85: Ensure visibility above header and improve hover contrast.

Add z-index to fixed elements and invert icon color on hover for contrast.

  .progress-bar {
     position: fixed;
     top: 0;
     left: 0;
     height: 2px;
     background: #00abff;
+    z-index: 50;
  }

  .on-top-bar {
     position: fixed;
     bottom: 20px;
     right: 18px;
     background-color: #fff;
     color: #1a1a1a;
     border-radius: 50%;
     width: 40px;
     height: 40px;
     display: flex;
     justify-content: center;
     align-items: center;
     cursor: pointer;
     transition: background-color 0.2s ease-in-out;
     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+    z-index: 50;

     &:hover {
-      background-color: #0039ff;
+      background-color: #0039ff;
+      color: #ffffff;
     }
  }

3-3: Naming convention: prefer 'styled' over 'Styled'.

Community convention aids readability: import styled from 'styled-components'.

-import Styled from "styled-components";
+import styled from "styled-components";
...
-const Container = Styled.section`
+const Container = styled.section`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ce03a2 and a67442d.

⛔ Files ignored due to path filters (2)
  • client/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • client/package.json (1 hunks)
  • client/src/App.jsx (1 hunks)
  • client/src/components/ThemeToggle.jsx (1 hunks)
  • client/src/components/TopBar.jsx (1 hunks)
  • client/src/styles/index.css (1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
client/src/styles/index.css

[error] 35-35: Unexpected unknown pseudo-class body

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)

🔇 Additional comments (2)
client/src/App.jsx (1)

20-29: Confirm TopBar and ThemeToggle are mounted somewhere.

I don’t see them used here; if they’re intended for the home page, ensure they’re rendered (e.g., in Header or layout).

client/package.json (1)

26-26: Cannot verify in sandbox — repo empty; run local checks for styled-components v6 + React 19 + Vite

Automated script returned an empty workspace; cannot confirm peer-dep warnings or Babel-plugin need. Run these in the project root (client/) and paste outputs (peer-dep warnings + build logs):

  • client/package.json (context): "styled-components": "^6.1.19",
  • cd client
  • npm ls react styled-components --depth=0 || true
  • npm install # capture any peer-dependency warnings
  • npm run build --silent # capture build warnings/errors
  • grep -nR "babel-plugin-styled-components" . || true
  • grep -nR "styled-components/babel" . || true

Comment on lines +8 to +14
useEffect(() => {
if( localStorage.getItem('theme') === 'dark' ){
document.documentElement.classList.add('dark');
setIsDarkMode(true);
}

},[])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Initialize dark mode from storage or system preference; current logic may show wrong icon on first paint.

Defaulting isDarkMode to false while the CSS default is dark causes a mismatch.

-useEffect(() => {
-    if( localStorage.getItem('theme') === 'dark' ){
-        document.documentElement.classList.add('dark');
-        setIsDarkMode(true);
-    }
-    
-},[])
+useEffect(() => {
+  const stored = localStorage.getItem('theme'); // 'dark' | 'light' | null
+  const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches;
+  const nextIsDark = stored ? stored === 'dark' : !!prefersDark;
+  document.documentElement.classList.toggle('dark', nextIsDark);
+  setIsDarkMode(nextIsDark);
+}, []);
📝 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.

Suggested change
useEffect(() => {
if( localStorage.getItem('theme') === 'dark' ){
document.documentElement.classList.add('dark');
setIsDarkMode(true);
}
},[])
useEffect(() => {
const stored = localStorage.getItem('theme'); // 'dark' | 'light' | null
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)')?.matches;
const nextIsDark = stored ? stored === 'dark' : !!prefersDark;
document.documentElement.classList.toggle('dark', nextIsDark);
setIsDarkMode(nextIsDark);
}, []);
🤖 Prompt for AI Agents
In client/src/components/ThemeToggle.jsx around lines 8 to 14, the component
initializes isDarkMode as false and only updates it in a useEffect, causing an
icon mismatch on first paint; change the implementation so the initial state is
computed from localStorage (if present) or from the prefers-color-scheme media
query and apply the corresponding document.documentElement.classList before
render (or use useLayoutEffect to avoid a paint flicker), and ensure both the
class toggle and setIsDarkMode are synchronized when mounting.

Comment on lines +15 to +25
const toggleTheme = () => {
if(isDarkMode){
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
setIsDarkMode(false);
}else{
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
setIsDarkMode(true);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Normalize toggle semantics and storage values.

Ensure the class and localStorage reflect the same meaning.

-const toggleTheme = () => {
-    if(isDarkMode){
-        document.documentElement.classList.remove('dark');
-        localStorage.setItem('theme', 'light');
-        setIsDarkMode(false);
-    }else{
-        document.documentElement.classList.add('dark');
-        localStorage.setItem('theme', 'dark');
-        setIsDarkMode(true);
-    }
-}
+const toggleTheme = () => {
+  const next = !isDarkMode;
+  document.documentElement.classList.toggle('dark', next);
+  localStorage.setItem('theme', next ? 'dark' : 'light');
+  setIsDarkMode(next);
+};
📝 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.

Suggested change
const toggleTheme = () => {
if(isDarkMode){
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
setIsDarkMode(false);
}else{
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
setIsDarkMode(true);
}
}
const toggleTheme = () => {
const next = !isDarkMode;
document.documentElement.classList.toggle('dark', next);
localStorage.setItem('theme', next ? 'dark' : 'light');
setIsDarkMode(next);
};
🤖 Prompt for AI Agents
In client/src/components/ThemeToggle.jsx around lines 15 to 25, the toggle
should consistently apply the same semantics to the DOM class and localStorage;
replace the branching with a single toggle flow that computes newIsDark =
!isDarkMode, then if newIsDark add the 'dark' class else remove it, set
localStorage.setItem('theme', newIsDark ? 'dark' : 'light'), and finally call
setIsDarkMode(newIsDark) so the class, storage value and state all reflect the
same meaning.

Comment on lines +18 to +30
const handleScroll = () => {
const winScroll = document.documentElement.scrollTop;
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scrolled = (winScroll / height) * 100;

setScrollProgress(scrolled);

if (window.scrollY > 100) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard division by zero and clamp progress; improve cross-browser scroll source.

Avoid NaN/Infinity when the page isn’t scrollable and support body/html differences.

-const handleScroll = () => {
-  const winScroll =  document.documentElement.scrollTop;
-  const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
-  const scrolled = (winScroll / height) * 100;
-  
-  setScrollProgress(scrolled);
-  
-  if (window.scrollY > 100) {
-    setIsVisible(true);
-  } else {
-    setIsVisible(false);
-  }
-};
+const handleScroll = () => {
+  const doc = document.documentElement;
+  const body = document.body;
+  const winScroll = doc.scrollTop || body.scrollTop || 0;
+  const height = (doc.scrollHeight || body.scrollHeight) - doc.clientHeight;
+  const pct = height > 0 ? Math.min(100, Math.max(0, (winScroll / height) * 100)) : 0;
+  setScrollProgress(pct);
+  setIsVisible(window.scrollY > 100);
+};
📝 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.

Suggested change
const handleScroll = () => {
const winScroll = document.documentElement.scrollTop;
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scrolled = (winScroll / height) * 100;
setScrollProgress(scrolled);
if (window.scrollY > 100) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
const handleScroll = () => {
const doc = document.documentElement;
const body = document.body;
const winScroll = doc.scrollTop || body.scrollTop || 0;
const height = (doc.scrollHeight || body.scrollHeight) - doc.clientHeight;
const pct = height > 0 ? Math.min(100, Math.max(0, (winScroll / height) * 100)) : 0;
setScrollProgress(pct);
setIsVisible(window.scrollY > 100);
};
🤖 Prompt for AI Agents
In client/src/components/TopBar.jsx around lines 18 to 30, the scroll progress
calculation can produce NaN/Infinity on non-scrollable pages and doesn't account
for cross-browser differences in where scrollTop is stored; update handleScroll
to read scroll position from window.scrollY ||
document.documentElement.scrollTop || document.body.scrollTop, compute total
scrollable height defensively (e.g. const height =
Math.max(document.documentElement.scrollHeight, document.body.scrollHeight) -
Math.max(document.documentElement.clientHeight, document.body.clientHeight)),
guard against division by zero by setting scrolled to 0 when height <= 0, and
clamp the resulting progress between 0 and 100 before calling setScrollProgress;
keep the existing visibility toggle logic.

Comment on lines +41 to +47
<div className="progress-bar" style={{ width: `${scrollProgress}%` }} />
{isvisible && (
<div className="on-top-bar" onClick={onTopbtn}>
<ArrowBigUp />
</div>
)}
</Container>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use a button for accessibility; add aria-label.

Clickable divs are not keyboard-accessible by default.

-  {isvisible && (
-    <div className="on-top-bar" onClick={onTopbtn}>
-      <ArrowBigUp />
-    </div>
-  )}
+  {isVisible && (
+    <button className="on-top-bar" type="button" onClick={onTopbtn} aria-label="Back to top">
+      <ArrowBigUp />
+    </button>
+  )}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In client/src/components/TopBar.jsx around lines 41 to 47, the clickable
"on-top-bar" div is not keyboard-accessible; replace that div with a semantic
<button> element, move the onClick handler to the button, add an appropriate
aria-label (e.g., "Scroll to top"), ensure any styling or className is preserved
on the button, and remove any tabIndex/role hacks so the element is naturally
focusable and accessible to keyboard and assistive technologies.

Comment on lines +35 to +38
:body {
background-color: #1a1a1a;
color: #f3f4f6;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix invalid selector ':body' (lint error).

:body is not a valid selector; use body.

-:body {
+body {
   background-color: #1a1a1a;
   color: #f3f4f6;
 }
📝 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.

Suggested change
:body {
background-color: #1a1a1a;
color: #f3f4f6;
}
body {
background-color: #1a1a1a;
color: #f3f4f6;
}
🧰 Tools
🪛 Biome (2.1.2)

[error] 35-35: Unexpected unknown pseudo-class body

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)

🤖 Prompt for AI Agents
In client/src/styles/index.css around lines 35 to 38, the selector uses an
invalid `:body`; replace it with the valid `body` selector so the rule reads
`body { background-color: #1a1a1a; color: #f3f4f6; }` and then run the CSS
linter to confirm the error is resolved.

@AayushSahani01
Copy link
Copy Markdown
Author

hey @CoderUzumaki ,

Please, Can you review my work implementation that feature as per your instructions

👍🏻

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.

2 participants