11/* eslint-disable @next/next/no-sync-scripts */
2- import { useState } from "react" ;
2+ import { useState , useRef , useEffect } from "react" ;
33import Link from "next/link" ;
44import Image from "next/image" ;
55import { MenuIcon , XIcon } from "@heroicons/react/outline" ;
66import Coffee from "./Coffee" ;
77import styles from "../styles/Coffee.module.css" ;
8+ import React from "react" ;
89
910const Header = ( ) => {
1011 const [ isOpen , setIsOpen ] = useState ( false ) ;
12+ const [ isDropdownOpen , setDropdownOpen ] = useState ( false ) ;
13+ const node = React . useRef < HTMLDivElement | null > ( null ) ;
14+
15+ const handleClickOutside = ( e : MouseEvent ) => {
16+ if ( node . current ?. contains ( e . target as Node ) ) {
17+ return ;
18+ }
19+ setDropdownOpen ( false ) ;
20+ } ;
21+
22+ useEffect ( ( ) => {
23+ if ( isDropdownOpen ) {
24+ document . addEventListener ( "mousedown" , handleClickOutside ) ;
25+ } else {
26+ document . removeEventListener ( "mousedown" , handleClickOutside ) ;
27+ }
28+
29+ return ( ) => {
30+ document . removeEventListener ( "mousedown" , handleClickOutside ) ;
31+ } ;
32+ } , [ isDropdownOpen ] ) ;
33+
1134 const toggleSideNav = ( ) => {
1235 setIsOpen ( ! isOpen ) ;
1336 } ;
1437
38+ const toggleDropdown = ( ) => {
39+ setDropdownOpen ( ! isDropdownOpen ) ;
40+ } ;
41+
1542 return (
1643 < >
1744 < nav className = "bg-slate-950 text-slate-50 backdrop-blur" >
@@ -85,11 +112,36 @@ const Header = () => {
85112 Contribute in GitHub
86113 </ div >
87114 </ Link >
88- < Link href = "/projects" >
89- < div className = "py-2 px-6 block text-sm cursor-pointer hover:underline" >
115+ < div className = "relative" ref = { node } >
116+ < button
117+ onClick = { toggleDropdown }
118+ className = "py-2 px-6 block text-sm cursor-pointer hover:underline"
119+ >
90120 Projects
91- </ div >
92- </ Link >
121+ </ button >
122+ { isDropdownOpen && (
123+ < div className = "absolute left-0 w-48 py-2 mt-2 bg-slate-900 rounded-lg shadow-xl" >
124+ < Link
125+ href = "/projects/websites"
126+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
127+ >
128+ Websites
129+ </ Link >
130+ < Link
131+ href = "/projects/mobile-apps"
132+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
133+ >
134+ Mobile Apps
135+ </ Link >
136+ < Link
137+ href = "/projects/desktop-apps"
138+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
139+ >
140+ Desktop Apps
141+ </ Link >
142+ </ div >
143+ ) }
144+ </ div >
93145 < Link href = "/developers" >
94146 < div className = "py-2 px-6 block text-sm cursor-pointer hover:underline" >
95147 Developers
@@ -110,11 +162,36 @@ const Header = () => {
110162 < header className = "bg-slate-950 text-slate-50 sticky top-0 z-10 hidden md:block" >
111163 < div className = "container mx-auto px-6 py-1 pb-6" >
112164 < div className = "mt-3 md:flex items-center space-x-1 justify-end" >
113- < Link href = "/projects" >
114- < div className = "py-2 px-6 block text-sm cursor-pointer hover:underline" >
165+ < div className = "relative" ref = { node } >
166+ < button
167+ onClick = { toggleDropdown }
168+ className = "py-2 px-6 block text-sm cursor-pointer hover:underline"
169+ >
115170 Projects
116- </ div >
117- </ Link >
171+ </ button >
172+ { isDropdownOpen && (
173+ < div className = "absolute left-0 w-48 py-2 mt-2 bg-slate-900 rounded-lg shadow-xl" >
174+ < Link
175+ href = "/projects/websites"
176+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
177+ >
178+ Websites
179+ </ Link >
180+ < Link
181+ href = "/projects/mobile-apps"
182+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
183+ >
184+ Mobile Apps
185+ </ Link >
186+ < Link
187+ href = "/projects/desktop-apps"
188+ className = "block px-4 py-2 text-sm cursor-pointer hover:underline"
189+ >
190+ Desktop Apps
191+ </ Link >
192+ </ div >
193+ ) }
194+ </ div >
118195 < Link href = "/developers" >
119196 < div className = "py-2 px-6 block text-sm cursor-pointer hover:underline" >
120197 Developers
0 commit comments