diff --git a/apps/web/src/components/footer.tsx b/apps/web/src/components/footer.tsx new file mode 100644 index 0000000000..f7f9a1ec37 --- /dev/null +++ b/apps/web/src/components/footer.tsx @@ -0,0 +1,242 @@ +import { Link, useRouterState } from "@tanstack/react-router"; + +function getMaxWidthClass(pathname: string): string { + const isBlogOrDocs = + pathname.startsWith("/blog") || pathname.startsWith("/docs"); + return isBlogOrDocs ? "max-w-6xl" : "max-w-6xl"; +} + +export function Footer() { + const currentYear = new Date().getFullYear(); + const router = useRouterState(); + const maxWidthClass = getMaxWidthClass(router.location.pathname); + + return ( + + ); +} diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx new file mode 100644 index 0000000000..51fd56cf71 --- /dev/null +++ b/apps/web/src/components/header.tsx @@ -0,0 +1,344 @@ +import { Link, useRouterState } from "@tanstack/react-router"; +import { ChevronDown, ChevronUp, Menu } from "lucide-react"; +import { useState } from "react"; + +import { getPlatformCTA, usePlatform } from "@/hooks/use-platform"; + +function getMaxWidthClass(pathname: string): string { + const isBlogOrDocs = + pathname.startsWith("/blog") || pathname.startsWith("/docs"); + return isBlogOrDocs ? "max-w-6xl" : "max-w-6xl"; +} + +const productsList = [ + { to: "/product/notepad", label: "Notepad" }, + { to: "/product/bot", label: "Bot", badge: "Coming Soon" }, + { to: "/product/api", label: "API", badge: "Coming Soon" }, + { to: "/product/extensions", label: "Extensions", badge: "Coming Soon" }, +]; + +const featuresList = [ + { to: "/product/ai-notetaking", label: "AI Notetaking" }, + { to: "/product/ai-assistant", label: "AI Assistant" }, + { to: "/product/mini-apps", label: "Mini Apps" }, + { to: "/product/workflows", label: "Workflows", badge: "Coming Soon" }, +]; + +export function Header() { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const [isProductOpen, setIsProductOpen] = useState(false); + const platform = usePlatform(); + const platformCTA = getPlatformCTA(platform); + const router = useRouterState(); + const maxWidthClass = getMaxWidthClass(router.location.pathname); + + return ( + <> +
+
+
+
+ + Hyprnote + +
setIsProductOpen(true)} + onMouseLeave={() => setIsProductOpen(false)} + > + + {isProductOpen && ( +
+
+
+
+
+ Products +
+ {productsList.map((link) => ( + setIsProductOpen(false)} + className="py-2 text-sm text-neutral-700 flex items-center justify-between hover:underline decoration-dotted" + > + {link.label} + {link.badge && ( + + {link.badge} + + )} + + ))} +
+
+
+ Features +
+
+ {featuresList.map((link) => ( + setIsProductOpen(false)} + className="py-2 text-sm text-neutral-700 flex items-center justify-between hover:underline decoration-dotted" + > + {link.label} + {link.badge && ( + + {link.badge} + + )} + + ))} +
+
+
+
+
+ )} +
+ + Docs + + + Blog + + + Pricing + + + Enterprise + +
+ + + Hyprnote + + + + +
+ {platformCTA.action === "download" ? ( + + {platformCTA.label} + + ) : ( + + {platform === "mobile" ? "Get reminder" : platformCTA.label} + + )} + +
+
+
+
+ + {isMenuOpen && ( + <> +
setIsMenuOpen(false)} + /> + +
+ +
+ + )} + + ); +} diff --git a/apps/web/src/components/not-found.tsx b/apps/web/src/components/not-found.tsx index de777879e2..fdfe2418f4 100644 --- a/apps/web/src/components/not-found.tsx +++ b/apps/web/src/components/not-found.tsx @@ -1,115 +1,39 @@ -import { Link } from "@tanstack/react-router"; +import { Footer } from "./footer"; +import { Header } from "./header"; export function NotFoundDocument() { return (
-
-
-

- Page Not Found -

+
+
+
+

+ Page Not Found +

-
- 404 -
+
+ 404 +
-

- We couldn't find the page you were looking for. If you think this is - an error, you can{" "} - - let us know - - . -

+

+ We couldn't find the page you were looking for. If you think this + is an error, you can{" "} + + let us know + + . +

+
); } - -function Header() { - return ( -
-
-
-
- - Hyprnote - - - Docs - - - Blog - - - Pricing - -
- -
-
-
- ); -} - -function Footer() { - const currentYear = new Date().getFullYear(); - - return ( - - ); -} diff --git a/apps/web/src/routes/_view/route.tsx b/apps/web/src/routes/_view/route.tsx index 692deff827..1f6abd7b94 100644 --- a/apps/web/src/routes/_view/route.tsx +++ b/apps/web/src/routes/_view/route.tsx @@ -1,13 +1,12 @@ import { createFileRoute, - Link, Outlet, useRouterState, } from "@tanstack/react-router"; -import { ChevronDown, ChevronUp, Menu } from "lucide-react"; import { createContext, useContext, useState } from "react"; -import { getPlatformCTA, usePlatform } from "@/hooks/use-platform"; +import { Footer } from "@/components/footer"; +import { Header } from "@/components/header"; export const Route = createFileRoute("/_view")({ component: Component, @@ -25,12 +24,6 @@ export function useHeroContext() { return useContext(HeroContext); } -function getMaxWidthClass(pathname: string): string { - const isBlogOrDocs = - pathname.startsWith("/blog") || pathname.startsWith("/docs"); - return isBlogOrDocs ? "max-w-6xl" : "max-w-6xl"; -} - function Component() { const router = useRouterState(); const isDocsPage = router.location.pathname.startsWith("/docs"); @@ -53,571 +46,3 @@ function Component() { ); } - -const productsList = [ - { to: "/product/notepad", label: "Notepad" }, - { to: "/product/bot", label: "Bot", badge: "Coming Soon" }, - { to: "/product/api", label: "API", badge: "Coming Soon" }, - { to: "/product/extensions", label: "Extensions", badge: "Coming Soon" }, -]; - -const featuresList = [ - { to: "/product/ai-notetaking", label: "AI Notetaking" }, - { to: "/product/ai-assistant", label: "AI Assistant" }, - { to: "/product/mini-apps", label: "Mini Apps" }, - { to: "/product/workflows", label: "Workflows", badge: "Coming Soon" }, -]; - -function Header() { - const [isMenuOpen, setIsMenuOpen] = useState(false); - const [isProductOpen, setIsProductOpen] = useState(false); - const platform = usePlatform(); - const platformCTA = getPlatformCTA(platform); - const router = useRouterState(); - const maxWidthClass = getMaxWidthClass(router.location.pathname); - - return ( - <> -
-
-
-
- - Hyprnote - -
setIsProductOpen(true)} - onMouseLeave={() => setIsProductOpen(false)} - > - - {isProductOpen && ( -
-
-
-
-
- Products -
- {productsList.map((link) => ( - setIsProductOpen(false)} - className="py-2 text-sm text-neutral-700 flex items-center justify-between hover:underline decoration-dotted" - > - {link.label} - {link.badge && ( - - {link.badge} - - )} - - ))} -
-
-
- Features -
-
- {featuresList.map((link) => ( - setIsProductOpen(false)} - className="py-2 text-sm text-neutral-700 flex items-center justify-between hover:underline decoration-dotted" - > - {link.label} - {link.badge && ( - - {link.badge} - - )} - - ))} -
-
-
-
-
- )} -
- - Docs - - - Blog - - - Pricing - - - Enterprise - -
- - - Hyprnote - - - - -
- {platformCTA.action === "download" ? ( - - {platformCTA.label} - - ) : ( - - {platform === "mobile" ? "Get reminder" : platformCTA.label} - - )} - -
-
-
-
- - {isMenuOpen && ( - <> -
setIsMenuOpen(false)} - /> - -
- -
- - )} - - ); -} - -function Footer() { - const currentYear = new Date().getFullYear(); - const router = useRouterState(); - const maxWidthClass = getMaxWidthClass(router.location.pathname); - - return ( - - ); -}