summaryrefslogtreecommitdiff
path: root/apps/web/src/components/header.tsx
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-27 00:55:15 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-29 15:56:48 +0200
commit4d127a038bf768eded68aae3cfa5c1b12241bdac (patch)
tree16bbb801caf6770546cff4fdb37b6408ec9ead98 /apps/web/src/components/header.tsx
parent82817cb50cb0487350573d6129130aec705f924b (diff)
downloadopencut-4d127a038bf768eded68aae3cfa5c1b12241bdac.tar.gz
chore: normalize line endings
Diffstat (limited to 'apps/web/src/components/header.tsx')
-rw-r--r--apps/web/src/components/header.tsx394
1 files changed, 197 insertions, 197 deletions
diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx
index e24486b4..5986308e 100644
--- a/apps/web/src/components/header.tsx
+++ b/apps/web/src/components/header.tsx
@@ -1,197 +1,197 @@
-"use client";
-
-import { useState } from "react";
-import Link from "next/link";
-import { motion } from "motion/react";
-import { Button } from "./ui/button";
-import { ArrowRight } from "lucide-react";
-import Image from "next/image";
-import { ThemeToggle } from "./theme-toggle";
-import {
- Copy01Icon,
- Download01Icon,
- GithubIcon,
- LinkSquare02Icon,
- Menu02Icon,
-} from "@hugeicons/core-free-icons";
-import { HugeiconsIcon } from "@hugeicons/react";
-import { cn } from "@/utils/ui";
-import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants";
-import {
- ContextMenu,
- ContextMenuContent,
- ContextMenuItem,
- ContextMenuTrigger,
-} from "./ui/context-menu";
-
-export function Header() {
- const [isMenuOpen, setIsMenuOpen] = useState(false);
- const closeMenu = () => setIsMenuOpen(false);
-
- const links = [
- {
- label: "Roadmap",
- href: "/roadmap",
- },
- {
- label: "Contributors",
- href: "/contributors",
- },
- {
- label: "Sponsors",
- href: "/sponsors",
- },
- {
- label: "Blog",
- href: "/blog",
- },
- ];
-
- return (
- <header className="bg-background shadow-background/85 sticky top-0 z-10 shadow-[0_30px_35px_15px_rgba(0,0,0,1)]">
- <div className="relative flex w-full items-center justify-between px-6 pt-4">
- <div className="relative z-10 flex items-center gap-6">
- <ContextMenu>
- <ContextMenuTrigger asChild>
- <Link href="/" className="flex items-center gap-3">
- <Image
- src={DEFAULT_LOGO_URL}
- alt="OpenCut Logo"
- className="invert dark:invert-0"
- width={32}
- height={32}
- />
- </Link>
- </ContextMenuTrigger>
- <ContextMenuContent>
- <ContextMenuItem
- onClick={async () => {
- const res = await fetch(DEFAULT_LOGO_URL);
- const svg = await res.text();
- await navigator.clipboard.writeText(svg);
- }}
- >
- <HugeiconsIcon icon={Copy01Icon} />
- Copy SVG
- </ContextMenuItem>
- <ContextMenuItem
- onClick={() => {
- const a = document.createElement("a");
- a.href = DEFAULT_LOGO_URL;
- a.download = "opencut-logo.svg";
- a.click();
- }}
- >
- <HugeiconsIcon icon={Download01Icon} />
- Download SVG
- </ContextMenuItem>
- <Link href="/brand">
- <ContextMenuItem>
- <HugeiconsIcon icon={LinkSquare02Icon} />
- Brand assets
- </ContextMenuItem>
- </Link>
- </ContextMenuContent>
- </ContextMenu>
-
- <nav className="hidden items-center gap-4 md:flex">
- {links.map((link) => (
- <Link key={link.href} href={link.href}>
- <Button variant="text" className="p-0 text-sm">
- {link.label}
- </Button>
- </Link>
- ))}
- </nav>
- </div>
-
- <div className="relative z-10">
- <div className="flex items-center gap-3 md:hidden">
- <Button
- variant="text"
- size="icon"
- className="flex items-center justify-center p-0"
- onClick={() => setIsMenuOpen(!isMenuOpen)}
- >
- <HugeiconsIcon icon={Menu02Icon} size={30} />
- </Button>
- </div>
- <div className="hidden items-center gap-3 md:flex">
- <Link href={SOCIAL_LINKS.github}>
- <Button className="bg-background text-sm" variant="outline">
- <HugeiconsIcon icon={GithubIcon} className="size-4" />
- 40k+
- </Button>
- </Link>
- <Link href="/projects">
- <Button className="text-sm">
- Projects
- <ArrowRight className="size-4" />
- </Button>
- </Link>
- <ThemeToggle />
- </div>
- </div>
- <div
- className={cn(
- "bg-background/20 pointer-events-none fixed inset-0 opacity-0 backdrop-blur-3xl",
- "transition-opacity duration-150",
- isMenuOpen && "pointer-events-auto opacity-100",
- )}
- >
- <div className="relative h-full">
- <button
- type="button"
- aria-label="Close menu"
- className="absolute inset-0"
- onClick={closeMenu}
- onKeyDown={(event) => {
- if (
- event.key === "Enter" ||
- event.key === " " ||
- event.key === "Escape"
- ) {
- event.preventDefault();
- closeMenu();
- }
- }}
- />
- <nav className="flex flex-col gap-3 px-6 pt-[5rem]">
- {links.map((link, index) => (
- <motion.div
- key={link.href}
- initial={{ scale: 0.98, opacity: 0 }}
- animate={{
- scale: isMenuOpen ? 1 : 0.98,
- opacity: isMenuOpen ? 1 : 0,
- }}
- transition={{
- duration: 0.4,
- delay: isMenuOpen ? index * 0.1 : 0,
- ease: [0.25, 0.46, 0.45, 0.94],
- }}
- >
- <Link
- href={link.href}
- className="text-2xl font-semibold"
- onClick={() => setIsMenuOpen(false)}
- >
- {link.label}
- </Link>
- </motion.div>
- ))}
- </nav>
- <ThemeToggle
- className="absolute right-8 bottom-8 size-10"
- iconClassName="!size-[1.2rem]"
- onToggle={(e) => {
- e.preventDefault();
- e.stopPropagation();
- }}
- />
- </div>
- </div>
- </div>
- </header>
- );
-}
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { motion } from "motion/react";
+import { Button } from "./ui/button";
+import { ArrowRight } from "lucide-react";
+import Image from "next/image";
+import { ThemeToggle } from "./theme-toggle";
+import {
+ Copy01Icon,
+ Download01Icon,
+ GithubIcon,
+ LinkSquare02Icon,
+ Menu02Icon,
+} from "@hugeicons/core-free-icons";
+import { HugeiconsIcon } from "@hugeicons/react";
+import { cn } from "@/utils/ui";
+import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants";
+import {
+ ContextMenu,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuTrigger,
+} from "./ui/context-menu";
+
+export function Header() {
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
+ const closeMenu = () => setIsMenuOpen(false);
+
+ const links = [
+ {
+ label: "Roadmap",
+ href: "/roadmap",
+ },
+ {
+ label: "Contributors",
+ href: "/contributors",
+ },
+ {
+ label: "Sponsors",
+ href: "/sponsors",
+ },
+ {
+ label: "Blog",
+ href: "/blog",
+ },
+ ];
+
+ return (
+ <header className="bg-background shadow-background/85 sticky top-0 z-10 shadow-[0_30px_35px_15px_rgba(0,0,0,1)]">
+ <div className="relative flex w-full items-center justify-between px-6 pt-4">
+ <div className="relative z-10 flex items-center gap-6">
+ <ContextMenu>
+ <ContextMenuTrigger asChild>
+ <Link href="/" className="flex items-center gap-3">
+ <Image
+ src={DEFAULT_LOGO_URL}
+ alt="OpenCut Logo"
+ className="invert dark:invert-0"
+ width={32}
+ height={32}
+ />
+ </Link>
+ </ContextMenuTrigger>
+ <ContextMenuContent>
+ <ContextMenuItem
+ onClick={async () => {
+ const res = await fetch(DEFAULT_LOGO_URL);
+ const svg = await res.text();
+ await navigator.clipboard.writeText(svg);
+ }}
+ >
+ <HugeiconsIcon icon={Copy01Icon} />
+ Copy SVG
+ </ContextMenuItem>
+ <ContextMenuItem
+ onClick={() => {
+ const a = document.createElement("a");
+ a.href = DEFAULT_LOGO_URL;
+ a.download = "opencut-logo.svg";
+ a.click();
+ }}
+ >
+ <HugeiconsIcon icon={Download01Icon} />
+ Download SVG
+ </ContextMenuItem>
+ <Link href="/brand">
+ <ContextMenuItem>
+ <HugeiconsIcon icon={LinkSquare02Icon} />
+ Brand assets
+ </ContextMenuItem>
+ </Link>
+ </ContextMenuContent>
+ </ContextMenu>
+
+ <nav className="hidden items-center gap-4 md:flex">
+ {links.map((link) => (
+ <Link key={link.href} href={link.href}>
+ <Button variant="text" className="p-0 text-sm">
+ {link.label}
+ </Button>
+ </Link>
+ ))}
+ </nav>
+ </div>
+
+ <div className="relative z-10">
+ <div className="flex items-center gap-3 md:hidden">
+ <Button
+ variant="text"
+ size="icon"
+ className="flex items-center justify-center p-0"
+ onClick={() => setIsMenuOpen(!isMenuOpen)}
+ >
+ <HugeiconsIcon icon={Menu02Icon} size={30} />
+ </Button>
+ </div>
+ <div className="hidden items-center gap-3 md:flex">
+ <Link href={SOCIAL_LINKS.github}>
+ <Button className="bg-background text-sm" variant="outline">
+ <HugeiconsIcon icon={GithubIcon} className="size-4" />
+ 40k+
+ </Button>
+ </Link>
+ <Link href="/projects">
+ <Button className="text-sm">
+ Projects
+ <ArrowRight className="size-4" />
+ </Button>
+ </Link>
+ <ThemeToggle />
+ </div>
+ </div>
+ <div
+ className={cn(
+ "bg-background/20 pointer-events-none fixed inset-0 opacity-0 backdrop-blur-3xl",
+ "transition-opacity duration-150",
+ isMenuOpen && "pointer-events-auto opacity-100",
+ )}
+ >
+ <div className="relative h-full">
+ <button
+ type="button"
+ aria-label="Close menu"
+ className="absolute inset-0"
+ onClick={closeMenu}
+ onKeyDown={(event) => {
+ if (
+ event.key === "Enter" ||
+ event.key === " " ||
+ event.key === "Escape"
+ ) {
+ event.preventDefault();
+ closeMenu();
+ }
+ }}
+ />
+ <nav className="flex flex-col gap-3 px-6 pt-[5rem]">
+ {links.map((link, index) => (
+ <motion.div
+ key={link.href}
+ initial={{ scale: 0.98, opacity: 0 }}
+ animate={{
+ scale: isMenuOpen ? 1 : 0.98,
+ opacity: isMenuOpen ? 1 : 0,
+ }}
+ transition={{
+ duration: 0.4,
+ delay: isMenuOpen ? index * 0.1 : 0,
+ ease: [0.25, 0.46, 0.45, 0.94],
+ }}
+ >
+ <Link
+ href={link.href}
+ className="text-2xl font-semibold"
+ onClick={() => setIsMenuOpen(false)}
+ >
+ {link.label}
+ </Link>
+ </motion.div>
+ ))}
+ </nav>
+ <ThemeToggle
+ className="absolute right-8 bottom-8 size-10"
+ iconClassName="!size-[1.2rem]"
+ onToggle={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ />
+ </div>
+ </div>
+ </div>
+ </header>
+ );
+}