mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-30 12:40:03 +02:00
Update navigation UI
This commit is contained in:
@@ -1,61 +1,38 @@
|
||||
---
|
||||
import { Menu } from 'lucide-react';
|
||||
import Icon from '../AstroIcon.astro';
|
||||
import { NavigationDropdown } from '../NavigationDropdown';
|
||||
import { AccountDropdown } from './AccountDropdown';
|
||||
---
|
||||
|
||||
<div class='bg-slate-900 py-5 text-white sm:py-8'>
|
||||
<nav class='container flex items-center justify-between'>
|
||||
<a
|
||||
class='flex items-center text-lg font-medium text-white'
|
||||
href='/'
|
||||
aria-label='roadmap.sh'
|
||||
>
|
||||
<Icon icon='logo' />
|
||||
</a>
|
||||
<div class='flex items-center gap-5'>
|
||||
<a
|
||||
class='flex items-center text-lg font-medium text-white'
|
||||
href='/'
|
||||
aria-label='roadmap.sh'
|
||||
>
|
||||
<Icon icon='logo' />
|
||||
</a>
|
||||
|
||||
<!-- Desktop navigation items -->
|
||||
<ul class='hidden space-x-5 sm:flex sm:items-center'>
|
||||
<li>
|
||||
<a href='/roadmaps' class='text-gray-400 hover:text-white'>Roadmaps</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/best-practices' class='text-gray-400 hover:text-white'
|
||||
>Best Practices</a
|
||||
>
|
||||
</li>
|
||||
<li class='hidden xl:inline'>
|
||||
<a href='/questions' class='text-gray-400 hover:text-white'>Questions</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/teams' class='group relative text-blue-300 hover:text-white'>
|
||||
Teams
|
||||
<span
|
||||
class='ml-0.5 hidden rounded-sm border-black bg-blue-300 px-1 py-0.5 text-xs font-semibold uppercase text-black group-hover:bg-white md:inline'
|
||||
>
|
||||
New
|
||||
</span>
|
||||
|
||||
<span class='inline md:hidden absolute -right-[11px] top-0'>
|
||||
<span class='relative flex h-2 w-2'>
|
||||
<span
|
||||
class='absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-400 opacity-75'
|
||||
></span>
|
||||
<span class='relative inline-flex h-2 w-2 rounded-full bg-sky-500'
|
||||
></span>
|
||||
</span>
|
||||
</span>
|
||||
<!-- Desktop navigation items -->
|
||||
<div class='hidden space-x-5 sm:flex sm:items-center'>
|
||||
<NavigationDropdown client:load />
|
||||
<a href='/get-started' class='text-gray-400 hover:text-white'>
|
||||
Start Here
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<kbd
|
||||
<a href='/teams' class='text-gray-400 hover:text-white'> Teams</a>
|
||||
<button
|
||||
data-command-menu
|
||||
class='hidden items-center rounded-md border border-gray-800 px-2.5 py-1 text-sm text-gray-400 hover:cursor-pointer hover:bg-gray-800 sm:flex'
|
||||
class='hidden items-center rounded-md border border-gray-800 px-2.5 py-1.5 text-sm text-gray-400 hover:cursor-pointer hover:bg-gray-800 sm:flex'
|
||||
>
|
||||
<Icon icon='search' class='mr-2 h-3 w-3' />
|
||||
<kbd class='mr-1 font-sans'>⌘</kbd><kbd class='font-sans'>K</kbd>
|
||||
</kbd>
|
||||
</li>
|
||||
</ul>
|
||||
<Icon icon='search' class='h-3 w-3' />
|
||||
<span class='ml-2'>Search</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class='hidden h-8 w-[172px] items-center justify-end gap-5 sm:flex'>
|
||||
<li data-guest-required class='hidden'>
|
||||
<a href='/login' class='text-gray-400 hover:text-white'>Login</a>
|
||||
|
89
src/components/NavigationDropdown.tsx
Normal file
89
src/components/NavigationDropdown.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import {
|
||||
CheckSquare,
|
||||
FileQuestion,
|
||||
Menu,
|
||||
Shirt,
|
||||
Waypoints,
|
||||
} from 'lucide-react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { cn } from '../lib/classname.ts';
|
||||
import { useOutsideClick } from '../hooks/use-outside-click.ts';
|
||||
|
||||
const links = [
|
||||
{
|
||||
link: '/roadmaps',
|
||||
label: 'Roadmaps',
|
||||
description: 'Step by step learning paths',
|
||||
Icon: Waypoints,
|
||||
},
|
||||
{
|
||||
link: '/best-practices',
|
||||
label: 'Best Practices',
|
||||
description: "Do's and don'ts",
|
||||
Icon: CheckSquare,
|
||||
},
|
||||
{
|
||||
link: '/questions',
|
||||
label: 'Questions',
|
||||
description: 'Test and Practice your knowledge',
|
||||
Icon: FileQuestion,
|
||||
},
|
||||
{
|
||||
link: 'https://cottonbureau.com/people/roadmapsh',
|
||||
label: 'Shop',
|
||||
description: 'Get some cool swag',
|
||||
Icon: Shirt,
|
||||
isExternal: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function NavigationDropdown() {
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
useOutsideClick(dropdownRef, () => {
|
||||
setIsOpen(false);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center" ref={dropdownRef}>
|
||||
<button
|
||||
className={cn('text-gray-400 hover:text-white', {
|
||||
'text-white': isOpen,
|
||||
})}
|
||||
onClick={() => setIsOpen(true)}
|
||||
onMouseOver={() => setIsOpen(true)}
|
||||
>
|
||||
<Menu className="h-5 w-5" />
|
||||
</button>
|
||||
<div
|
||||
className={cn(
|
||||
'absolute left-0 top-full z-[999] mt-2 w-48 min-w-[320px] -translate-y-1 rounded-lg bg-slate-800 py-2 opacity-0 shadow-xl transition-all duration-100',
|
||||
{
|
||||
'translate-y-2.5 opacity-100': isOpen,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{links.map((link) => (
|
||||
<a
|
||||
href={link.link}
|
||||
target={link.isExternal ? '_blank' : undefined}
|
||||
rel={link.isExternal ? 'noopener noreferrer' : undefined}
|
||||
key={link.link}
|
||||
className="group flex items-center gap-3 px-4 py-2.5 text-gray-400 transition-colors hover:bg-slate-700"
|
||||
>
|
||||
<span className="flex h-[40px] w-[40px] items-center justify-center rounded-full bg-slate-600 transition-colors group-hover:bg-slate-500 group-hover:text-slate-100">
|
||||
<link.Icon className="inline-block h-5 w-5" />
|
||||
</span>
|
||||
<span className="flex flex-col">
|
||||
<span className="font-medium text-slate-300 transition-colors group-hover:text-slate-100">
|
||||
{link.label}
|
||||
</span>
|
||||
<span className="text-sm">{link.description}</span>
|
||||
</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@@ -3,7 +3,6 @@ import Analytics from '../components/Analytics/Analytics.astro';
|
||||
import LoginPopup from '../components/AuthenticationFlow/LoginPopup.astro';
|
||||
import Authenticator from '../components/Authenticator/Authenticator.astro';
|
||||
import { CommandMenu } from '../components/CommandMenu/CommandMenu';
|
||||
import { AppChecklist } from '../components/AppChecklist';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import Navigation from '../components/Navigation/Navigation.astro';
|
||||
import OpenSourceBanner from '../components/OpenSourceBanner.astro';
|
||||
@@ -175,8 +174,6 @@ const gaPageIdentifier = Astro.url.pathname
|
||||
client:load
|
||||
/>
|
||||
|
||||
<AppChecklist client:idle />
|
||||
|
||||
<slot name='after-footer' />
|
||||
|
||||
<Analytics />
|
||||
|
Reference in New Issue
Block a user