|
1 | | -import { useState } from "react"; |
| 1 | +import { useState, useEffect, useRef } from "react"; |
2 | 2 |
|
3 | 3 | import Link from "next/link"; |
4 | 4 |
|
5 | 5 | import { translatoinSchemaType } from "@/types/page"; |
6 | 6 |
|
| 7 | +const scrollToSection = (id: string, offset: number = 64) => { |
| 8 | + const target = document.querySelector(id); |
| 9 | + if (target) { |
| 10 | + const top = target.getBoundingClientRect().top + window.scrollY - offset; |
| 11 | + window.scrollTo({ top, behavior: "smooth" }); |
| 12 | + } |
| 13 | +}; |
| 14 | + |
7 | 15 | const Navbar = (transation: translatoinSchemaType) => { |
8 | 16 | const [isOpen, setIsOpen] = useState(false); |
9 | 17 | const [isLangOpen, setIsLangOpen] = useState(false); |
| 18 | + const langDropdownRef = useRef<HTMLDivElement>(null); |
| 19 | + |
| 20 | + useEffect(() => { |
| 21 | + const handleClickOutside = (event: MouseEvent) => { |
| 22 | + if (langDropdownRef.current && !langDropdownRef.current.contains(event.target as Node)) { |
| 23 | + setIsLangOpen(false); |
| 24 | + } |
| 25 | + }; |
| 26 | + |
| 27 | + document.addEventListener("mousedown", handleClickOutside); |
| 28 | + return () => { |
| 29 | + document.removeEventListener("mousedown", handleClickOutside); |
| 30 | + }; |
| 31 | + }, []); |
10 | 32 |
|
11 | 33 | return ( |
12 | 34 | <div className="sticky top-0 inset-x-0 flex flex-wrap md:justify-start md:flex-nowrap z-50 w-full text-sm"> |
@@ -35,10 +57,19 @@ const Navbar = (transation: translatoinSchemaType) => { |
35 | 57 | <div id="hs-navbar-header-floating" className={`${isOpen ? "block" : "hidden"} md:block transition-all duration-300 basis-full grow md:block`} aria-labelledby="hs-navbar-header-floating-collapse"> |
36 | 58 | <div className="flex flex-col md:flex-row md:items-center md:justify-end gap-2 md:gap-3 mt-3 md:mt-0 py-2 md:py-0 md:ps-7"> |
37 | 59 | <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-gray-800 font-medium text-gray-800 focus:outline-none dark:border-neutral-200 dark:text-neutral-200" href="#" aria-current="page">{transation.data.profile.title}</Link> |
38 | | - <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" href="#work-experience">{transation.data.workExperience.title}</Link> |
39 | | - <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" href="#education">{transation.data.education.title}</Link> |
40 | | - <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" href="#skills">{transation.data.skills.title}</Link> |
41 | | - <div className="relative"> |
| 60 | + <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" onClick={(e) => { |
| 61 | + e.preventDefault(); |
| 62 | + scrollToSection("#work-experience"); |
| 63 | + }} href="#work-experience">{transation.data.workExperience.title}</Link> |
| 64 | + <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" onClick={(e) => { |
| 65 | + e.preventDefault(); |
| 66 | + scrollToSection("#education"); |
| 67 | + }} href="#education">{transation.data.education.title}</Link> |
| 68 | + <Link className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200" onClick={(e) => { |
| 69 | + e.preventDefault(); |
| 70 | + scrollToSection("#skills"); |
| 71 | + }} href="#skills">{transation.data.skills.title}</Link> |
| 72 | + <div className="relative" ref={langDropdownRef}> |
42 | 73 | <button className="py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-transparent text-gray-500 hover:text-gray-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200 flex items-center" onClick={() => setIsLangOpen(!isLangOpen)}> |
43 | 74 | {transation.data.language.title} |
44 | 75 | <svg className={`ml-1 w-4 h-4 transition-transform ${isLangOpen ? 'rotate-180' : ''}`} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
|
0 commit comments