Skip to content

Conversation

@OUMIMANDAL
Copy link
Contributor

This PR fixes:

  • Footer not sticking to bottom on large screens (>1100px)
  • Duplicate navigation menu in mobile view
  • Extra whitespace in metadata URLs

Uses flex min-h-screen flex-col in layout.tsx for proper layout.

Fixes #2033

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 31, 2025

Summary by CodeRabbit

  • New Features

    • Added a semantic main content wrapper for improved structure.
    • Introduced dedicated mobile actions (Star on GitHub, Sponsor) as full-width buttons.
    • Overhauled mobile navigation with nested submenu support and improved toggle icons.
  • Refactor

    • Simplified desktop header to direct links with active-state highlighting.
    • Updated branding/logo presentation and icon usage; adjusted visibility across breakpoints.
  • Style

    • Applied a flex column layout to the main content area and refined spacing and active state indicators.

Walkthrough

Introduces a main wrapper around page children in layout, and refactors Header to simplify desktop links, overhaul mobile navigation/actions, and remove NavDropdown/NavButton usage. No exported/public APIs changed.

Changes

Cohort / File(s) Summary
Layout structure update
frontend/src/app/layout.tsx
Wraps {children} in <main class="flex min-w-0 flex-1 flex-col"> to provide a semantic landmark and flex growth for the content area. No other layout providers or structural elements changed.
Header refactor: links and mobile nav
frontend/src/components/Header.tsx
Replaces desktop NavDropdown/NavButton with simple Link items and Button-based actions; adds explicit mobile actions; overhauls mobile navigation rendering with nested submenu handling; updates active-state aria attributes and Image props; maintains toggle behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Assessment against linked issues

Objective Addressed Explanation
Fix footer not sticking to bottom on initial Home page load via container flexibility changes (#2033)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Replace desktop submenu/NavDropdown with simple Link items (frontend/src/components/Header.tsx) Header navigation restructuring is unrelated to fixing footer sticking behavior on the Home page.
Convert Star/Sponsor actions from NavButton to Button with icon changes and add mobile-only actions (frontend/src/components/Header.tsx) Action button refactors and mobile action additions do not pertain to page container/flex behavior for the footer.
Overhaul mobile navigation rendering, including nested submenu layout and toggle icons (frontend/src/components/Header.tsx) Mobile nav UX changes are not required to address the footer positioning issue described in the linked issue.

Possibly related PRs

Suggested reviewers

  • kasya
  • arkid15r

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@OUMIMANDAL
Copy link
Contributor Author

@kasya
Hi , I've opened a clean PR with only the necessary changes:

Fixed footer layout issue
Removed duplicate navigation
No unnecessary files changed
Ready for review. Thank you!

@sonarqubecloud
Copy link

Copy link
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/src/components/Header.tsx (1)

106-114: Remove leftover NavButton block (undefined symbol)

NavButton isn’t imported anymore; leaving this in will fail at build-time. It’s also redundant with the new Desktop Actions.

Apply this diff:

-          <NavButton
-            href="https://github.com/OWASP/Nest"
-            defaultIcon={faRegularStar}
-            hoverIcon={faSolidStar}
-            defaultIconColor="#FDCE2D"
-            hoverIconColor="#FDCE2D"
-            text="Star"
-            className="hidden"
-          />
+
frontend/src/app/layout.tsx (1)

70-79: Apply flex layout to body (not just main) for a true sticky footer

Right now main has flex-1 but the parent (body) isn’t a flex column, so the footer may still float on tall viewports. Move flex min-h-screen flex-col to body and drop the inline style.

Apply this diff:

-      <body
-        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
-        style={{ minHeight: '100vh' }}
-      >
+      <body
+        className={`${geistSans.variable} ${geistMono.variable} antialiased flex min-h-screen flex-col`}
+      >
@@
-          <BreadCrumbs />
-           <main className="flex min-w-0 flex-1 flex-col">{children}</main>
-          
+          <BreadCrumbs />
+          <main className="flex min-w-0 flex-1 flex-col">{children}</main>
🧹 Nitpick comments (3)
frontend/src/components/Header.tsx (3)

119-128: Open external links safely in a new tab

Add target and rel for security and UX.

Apply this diff:

           <Button
             as="a"
             href="https://github.com/OWASP/Nest"
+            target="_blank"
+            rel="noopener noreferrer"
             variant="secondary"
             size="sm"
             className="hidden text-yellow-300 hover:text-yellow-200 md:flex"
           >
@@
           <Button
             as="a"
             href="https://owasp.org/donate/?reponame=www-project-nest&title=OWASP+Nest"
+            target="_blank"
+            rel="noopener noreferrer"
             variant="secondary"
             size="sm"
             className="hidden text-pink-300 hover:text-pink-200 md:flex"
           >

Also applies to: 129-138


143-153: Improve mobile menu toggle a11y (aria-expanded, controls, dynamic label)

Adds correct state and target wiring.

Apply this diff:

           <div className="md:hidden">
             <Button
               onPress={toggleMobileMenu}
+              aria-expanded={mobileMenuOpen}
+              aria-controls="mobile-drawer"
               className="bg-transparent text-slate-300 hover:bg-transparent hover:text-slate-100 focus:outline-hidden"
             >
-              <span className="sr-only">Open main menu</span>
+              <span className="sr-only">{mobileMenuOpen ? 'Close main menu' : 'Open main menu'}</span>
               {mobileMenuOpen ? (
                 <FontAwesomeIcon icon={faTimes} className="h-6 w-6" />
               ) : (
                 <FontAwesomeIcon icon={faBars} className="h-6 w-6" />
               )}
             </Button>
           </div>
@@
-      <div
+      <div
+        id="mobile-drawer"
         className={cn(

Also applies to: 158-162


2-6: Remove unused solid icon imports

They’re not referenced after the refactor; drop to keep tree clean.

Apply this diff:

 import { faBars, faTimes } from '@fortawesome/free-solid-svg-icons'
-import { faHeart as faSolidHeart } from '@fortawesome/free-solid-svg-icons'
-import { faStar as faSolidStar } from '@fortawesome/free-solid-svg-icons'
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7cd6d44 and 08ceb23.

📒 Files selected for processing (2)
  • frontend/src/app/layout.tsx (1 hunks)
  • frontend/src/components/Header.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/components/Header.tsx (5)
frontend/src/types/link.ts (1)
  • Link (1-7)
frontend/src/utils/constants.ts (1)
  • headerLinks (5-27)
frontend/src/utils/utility.ts (1)
  • cn (16-18)
frontend/src/components/UserMenu.tsx (1)
  • UserMenu (13-119)
frontend/src/components/ModeToggle.tsx (1)
  • ModeToggle (7-40)
🪛 Biome (2.1.2)
frontend/src/components/Header.tsx

[error] 82-82: Expected corresponding JSX closing tag for 'nav'.

Opening tag

closing tag

(parse)


[error] 261-261: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 263-264: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 264-264: expected < but instead the file ends

the file ends here

(parse)

🔇 Additional comments (2)
frontend/src/components/Header.tsx (1)

23-51: desktopViewMinWidth matches Tailwind’s default md breakpoint
desktopViewMinWidth is set to 768 and no custom screens override is defined in tailwind.config.mjs, so Tailwind’s default md breakpoint of 768px applies—no change needed.

frontend/src/app/layout.tsx (1)

68-80: Confirm content offset for fixed header

Header is fixed (top-0 h-16). Ensure the first content below it has enough top offset (e.g., global pt-16 or equivalent) to avoid overlap. If not already handled elsewhere, add pt-16 on the main container.

Option (if needed):

-          <main className="flex min-w-0 flex-1 flex-col">{children}</main>
+          <main className="flex min-w-0 flex-1 flex-col pt-16">{children}</main>

Comment on lines +81 to 104
{/* Desktop Links */}
<nav className="hidden flex-1 justify-start pl-6 font-medium md:flex">
<div className="flex space-x-1">
{headerLinks
.filter((link) => {
if (link.requiresGitHubAuth) {
return isGitHubAuthEnabled
}
if (link.requiresGitHubAuth) return isGitHubAuthEnabled
return true
})
.map((link, i) => {
return link.submenu ? (
<NavDropdown link={link} pathname={pathname} key={i} />
) : (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current="page"
>
{link.text}
</Link>
)
})}
.map((link) => (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={pathname === link.href ? 'page' : undefined}
>
{link.text}
</Link>
))}
</div>

</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing closing tag: use instead of

This is causing the parse error Biome reported. Close the opened nav element properly.

Apply this diff:

-        </div>
+        </nav>
📝 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
{/* Desktop Links */}
<nav className="hidden flex-1 justify-start pl-6 font-medium md:flex">
<div className="flex space-x-1">
{headerLinks
.filter((link) => {
if (link.requiresGitHubAuth) {
return isGitHubAuthEnabled
}
if (link.requiresGitHubAuth) return isGitHubAuthEnabled
return true
})
.map((link, i) => {
return link.submenu ? (
<NavDropdown link={link} pathname={pathname} key={i} />
) : (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current="page"
>
{link.text}
</Link>
)
})}
.map((link) => (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={pathname === link.href ? 'page' : undefined}
>
{link.text}
</Link>
))}
</div>
</div>
{/* Desktop Links */}
<nav className="hidden flex-1 justify-start pl-6 font-medium md:flex">
<div className="flex space-x-1">
{headerLinks
.filter((link) => {
if (link.requiresGitHubAuth) return isGitHubAuthEnabled
return true
})
.map((link) => (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={pathname === link.href ? 'page' : undefined}
>
{link.text}
</Link>
))}
</div>
</nav>
🧰 Tools
🪛 Biome (2.1.2)

[error] 82-82: Expected corresponding JSX closing tag for 'nav'.

Opening tag

closing tag

(parse)

🤖 Prompt for AI Agents
In frontend/src/components/Header.tsx around lines 81 to 104, the opened <nav>
element is incorrectly closed with </div>, causing an HTML/JSX parse error;
replace the incorrect closing tag with </nav> to properly close the nav element
and restore valid JSX structure.

Comment on lines +89 to +101
.map((link) => (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={pathname === link.href ? 'page' : undefined}
>
{link.text}
</Link>
))}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Desktop nav regression: submenu parents link to “/”

On desktop, links with a submenu (e.g., “Community”) currently resolve to “/”, removing access to submenu pages. Use the first submenu item as the fallback href and improve active matching.

Apply this diff:

-              .map((link) => (
-                <Link
-                  key={link.text}
-                  href={link.href || '/'}
-                  className={cn(
-                    'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
-                    pathname === link.href && 'font-bold text-blue-800 dark:text-white'
-                  )}
-                  aria-current={pathname === link.href ? 'page' : undefined}
-                >
-                  {link.text}
-                </Link>
-              ))}
+              .map((link) => {
+                const href = link.href ?? link.submenu?.[0]?.href ?? '/'
+                const isActive = href !== '/' && pathname.startsWith(href)
+                return (
+                  <Link
+                    key={link.text}
+                    href={href}
+                    className={cn(
+                      'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
+                      isActive && 'font-bold text-blue-800 dark:text-white'
+                    )}
+                    aria-current={isActive ? 'page' : undefined}
+                  >
+                    {link.text}
+                  </Link>
+                )
+              })}
📝 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
.map((link) => (
<Link
key={link.text}
href={link.href || '/'}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
pathname === link.href && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={pathname === link.href ? 'page' : undefined}
>
{link.text}
</Link>
))}
.map((link) => {
const href = link.href ?? link.submenu?.[0]?.href ?? '/'
const isActive = href !== '/' && pathname.startsWith(href)
return (
<Link
key={link.text}
href={href}
className={cn(
'navlink px-3 py-2 text-sm text-slate-700 hover:text-slate-800 dark:text-slate-300 dark:hover:text-slate-200',
isActive && 'font-bold text-blue-800 dark:text-white'
)}
aria-current={isActive ? 'page' : undefined}
>
{link.text}
</Link>
)
})}
🤖 Prompt for AI Agents
In frontend/src/components/Header.tsx around lines 89 to 101, links that have
submenus currently fall back to "/" which breaks access to submenu pages; change
the fallback href to the first submenu item's href (e.g., link.href ||
link.items?.[0]?.href || '/') and update the active matching so the navitem is
considered active when the current pathname matches the link.href or any submenu
href (or startsWith the link href if appropriate) — adjust the aria-current and
className condition to use this improved check (e.g., pathname === link.href ||
link.items?.some(i => i.href === pathname) or pathname.startsWith(link.href)).

</div>
</div>
</div>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove stray “)}” after the mobile drawer

This unmatched token breaks parsing/compilation.

Apply this diff:

-      )}
+      
📝 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
)}
🧰 Tools
🪛 Biome (2.1.2)

[error] 261-261: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)

🤖 Prompt for AI Agents
In frontend/src/components/Header.tsx around line 261, there is a stray closing
token ")}" left after the mobile drawer which breaks compilation; remove that
unmatched ")}" so the JSX/TSX returns and component structure remain balanced,
then run TypeScript/JSX compile to verify no other mismatched braces remain.

@kasya
Copy link
Collaborator

kasya commented Aug 31, 2025

Hi @OUMIMANDAL ! Sorry, but this doesn't work.
The original issue is still there, plus new one arose after your PR.

I can tell that you haven't even ran the code, because it doesn't compile right now - there are missing closing tags for some items and missed imports. Btw, CodeRabbit told you so in this PR too, so you could have fixed it quickly.

I appreciate your work on this one, but that's not the quality of PRs we are looking for.

I'm going to close this PR and reassign the issue.
Feel free to try yourself in other, smaller tasks though to get better. Thanks!

@kasya kasya closed this Aug 31, 2025
@OUMIMANDAL
Copy link
Contributor Author

Hi @kasya

Thanks for the feedback — I apologize for the errors. I should’ve tested the code properly before submitting.

My monitor has a limited width , which makes it hard to preview larger layouts. Still, I should’ve used dev tools to check responsiveness — I’ll do that going forward.

I’m committed to improving and would love to collaborate on future tasks. Thanks again for your guidance.

Best regards,
Oumimandal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix Home Page container flexibility

2 participants