diff --git a/package.json b/package.json
index a7f37c6..eaae381 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-icons": "^1.3.2",
+ "@radix-ui/react-navigation-menu": "^1.2.5",
"@radix-ui/react-slot": "^1.1.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -38,4 +39,4 @@
"typescript": "^5"
},
"packageManager": "pnpm@9.5.0"
-}
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b0164b0..37cbaae 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,6 +14,9 @@ importers:
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.0.0)
+ '@radix-ui/react-navigation-menu':
+ specifier: ^1.2.5
+ version: 1.2.5(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-slot':
specifier: ^1.1.2
version: 1.1.2(@types/react@19.0.8)(react@19.0.0)
@@ -487,6 +490,19 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-dismissable-layer@1.1.5':
+ resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-icons@1.3.2':
resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==}
peerDependencies:
@@ -501,6 +517,19 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-navigation-menu@1.2.5':
+ resolution: {integrity: sha512-myMHHQUZ3ZLTi8W381/Vu43Ia0NqakkQZ2vzynMmTUtQQ9kNkjzhOwkZC9TAM5R07OZUVIQyHC06f/9JZJpvvA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-presence@1.1.2':
resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
peerDependencies:
@@ -554,6 +583,15 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-escape-keydown@1.1.0':
+ resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@radix-ui/react-use-layout-effect@1.1.0':
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
peerDependencies:
@@ -563,6 +601,28 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-use-previous@1.1.0':
+ resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-visually-hidden@1.1.2':
+ resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -3087,6 +3147,19 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.8
+ '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.8
+ '@types/react-dom': 19.0.3(@types/react@19.0.8)
+
'@radix-ui/react-icons@1.3.2(react@19.0.0)':
dependencies:
react: 19.0.0
@@ -3098,6 +3171,28 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.8
+ '@radix-ui/react-navigation-menu@1.2.5(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.8
+ '@types/react-dom': 19.0.3(@types/react@19.0.8)
+
'@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0)
@@ -3137,12 +3232,34 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.8
+ '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.8)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.8)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.8
+
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.8)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.8
+ '@radix-ui/react-use-previous@1.1.0(@types/react@19.0.8)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.8
+
+ '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.8
+ '@types/react-dom': 19.0.3(@types/react@19.0.8)
+
'@rtsao/scc@1.1.0': {}
'@rushstack/eslint-patch@1.10.5': {}
diff --git a/src/app/components/top-navigation/index.ts b/src/app/components/top-navigation/index.ts
new file mode 100644
index 0000000..53a93a9
--- /dev/null
+++ b/src/app/components/top-navigation/index.ts
@@ -0,0 +1 @@
+export * from "./top-navigation";
diff --git a/src/app/components/top-navigation/navigationData.d.ts b/src/app/components/top-navigation/navigationData.d.ts
new file mode 100644
index 0000000..2dca721
--- /dev/null
+++ b/src/app/components/top-navigation/navigationData.d.ts
@@ -0,0 +1 @@
+export type NavigationDataType = { content: string; link: string };
diff --git a/src/app/components/top-navigation/top-navigation.tsx b/src/app/components/top-navigation/top-navigation.tsx
new file mode 100644
index 0000000..e90ce2a
--- /dev/null
+++ b/src/app/components/top-navigation/top-navigation.tsx
@@ -0,0 +1,44 @@
+import FrontChapter from "@/components/logos/front-chapter";
+import { Button } from "@/components/ui/button";
+import {
+ NavbarCenter,
+ Navbar as NavbarComponent,
+ NavbarLeft,
+ NavbarRight,
+} from "@/components/ui/navbar";
+import Navigation from "@/components/ui/navigation";
+import { TicketIcon } from "lucide-react";
+import Link from "next/link";
+
+export default function TopNavigation() {
+ return (
+
+ );
+}
diff --git a/src/app/globals.css b/src/app/globals.css
index bc828b7..5ddc566 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -6,7 +6,28 @@
* {
@apply border-border;
}
+
body {
@apply bg-background text-foreground dark:bg-background-dark dark:text-foreground-dark;
}
}
+
+@layer components {
+
+ .glass-1 {
+ @apply border border-border/20 border-b-border/5 bg-gradient-to-b from-[#09090B]/5 to-[#09090B]/20 dark:border-b-0 dark:border-border/5 dark:border-t-border/20 dark:from-white/5 dark:to-white/20;
+ }
+
+ .glass-2 {
+ @apply border border-border/20 border-b-border/5 bg-gradient-to-b from-[#09090B]/20 to-[#09090B]/5 dark:border-b-0 dark:border-border/5 dark:border-t-border/20 dark:from-white/20 dark:to-white/5;
+ }
+
+
+ .dark-glass-1 {
+ @apply border border-border/80 border-b-input/90 bg-gradient-to-b from-[#27272A]/60 to-[#27272A]/20 dark:border-b-0 dark:border-border/5 dark:border-t-border/20 dark:from-white/10 dark:to-white/5;
+ }
+
+ .dark-glass-2 {
+ @apply border border-border/100 border-b-input bg-gradient-to-b from-[#27272A]/100 to-[#27272A]/20 dark:border-b-0 dark:border-border/5 dark:border-t-border/20 dark:from-white/15 dark:to-white/5;
+ }
+}
\ No newline at end of file
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 304aca4..13b4ea4 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,4 +1,5 @@
import Sponsors from "./components/Sponsors/Sponsors";
+import TopNavigation from "./components/top-navigation/top-navigation";
import FAQ from "@/app/components/FAQ/FAQ";
import TweetSection from "@/app/components/TweetSection/TweetSection";
import Speakers from "@/app/components/speakers/Speakers";
@@ -6,10 +7,11 @@ import Speakers from "@/app/components/speakers/Speakers";
export default function Home() {
return (
<>
+
+
-
>
);
}
diff --git a/src/components/logos/front-chapter.tsx b/src/components/logos/front-chapter.tsx
new file mode 100644
index 0000000..3e4caff
--- /dev/null
+++ b/src/components/logos/front-chapter.tsx
@@ -0,0 +1,20 @@
+const FrontChapter = (props: React.SVGProps) => (
+
+);
+export default FrontChapter;
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
new file mode 100644
index 0000000..224f9f7
--- /dev/null
+++ b/src/components/ui/button.tsx
@@ -0,0 +1,58 @@
+import { cn } from "@/lib/utils";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+import * as React from "react";
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
+ {
+ variants: {
+ variant: {
+ default:
+ "text-white -foreground shadow dark:hover:from-white/80 hover:from-white/70 dark:hover:to-white/70 hover:to-white/90 bg-gradient-to-b from-white/60 to-white/100 dark:from-white/100 dark:to-white/70 border-t-white",
+ destructive:
+ "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent",
+ glow: "glass-1 dark:dark-glass-1 hover:glass-2 dark:hover:dark-glass-2 shadow-md",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-foreground underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2",
+ xs: "h-7 rounded-md px-2",
+ sm: "h-8 rounded-md px-3 text-xs",
+ lg: "h-10 rounded-md px-5",
+ icon: "h-9 w-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ },
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return (
+
+ );
+ },
+);
+Button.displayName = "Button";
+
+export { Button, buttonVariants };
diff --git a/src/components/ui/navbar.tsx b/src/components/ui/navbar.tsx
new file mode 100644
index 0000000..7d112cc
--- /dev/null
+++ b/src/components/ui/navbar.tsx
@@ -0,0 +1,51 @@
+import * as React from "react";
+import { cn } from "@/lib/utils";
+
+const Navbar = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+Navbar.displayName = "Navbar";
+
+const NavbarLeft = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+NavbarLeft.displayName = "NavbarLeft";
+
+const NavbarRight = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+NavbarRight.displayName = "NavbarRight";
+
+const NavbarCenter = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+NavbarCenter.displayName = "NavbarCenter";
+
+export { Navbar, NavbarLeft, NavbarRight, NavbarCenter };
diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx
new file mode 100644
index 0000000..7dc165e
--- /dev/null
+++ b/src/components/ui/navigation-menu.tsx
@@ -0,0 +1,127 @@
+import { cn } from "@/lib/utils";
+import { ChevronDownIcon } from "@radix-ui/react-icons";
+import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
+import { cva } from "class-variance-authority";
+import * as React from "react";
+
+const NavigationMenu = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+
+));
+NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
+
+const NavigationMenuList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
+
+const NavigationMenuItem = NavigationMenuPrimitive.Item;
+
+const navigationMenuTriggerStyle = cva(
+ "group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-colors hover:bg-accent dark:hover:text-white focus:bg-accent dark:focus:text-white focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50",
+);
+
+const NavigationMenuTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}{" "}
+
+
+));
+NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
+
+const NavigationMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
+
+const NavigationMenuLink = NavigationMenuPrimitive.Link;
+
+const NavigationMenuViewport = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+NavigationMenuViewport.displayName =
+ NavigationMenuPrimitive.Viewport.displayName;
+
+const NavigationMenuIndicator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+NavigationMenuIndicator.displayName =
+ NavigationMenuPrimitive.Indicator.displayName;
+
+export {
+ navigationMenuTriggerStyle,
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuContent,
+ NavigationMenuTrigger,
+ NavigationMenuLink,
+ NavigationMenuIndicator,
+ NavigationMenuViewport,
+};
diff --git a/src/components/ui/navigation.tsx b/src/components/ui/navigation.tsx
new file mode 100644
index 0000000..a5e25be
--- /dev/null
+++ b/src/components/ui/navigation.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import {
+ NavigationMenu,
+ NavigationMenuItem,
+ NavigationMenuLink,
+ NavigationMenuList,
+ navigationMenuTriggerStyle,
+} from "./navigation-menu";
+import { NavigationData } from "@/configs/NavigationData";
+import Link from "next/link";
+import * as React from "react";
+
+export default function Navigation() {
+ return (
+
+
+ {!!NavigationData &&
+ NavigationData.map((item, index) => (
+
+
+
+ {item.content}
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/configs/NavigationData.ts b/src/configs/NavigationData.ts
new file mode 100644
index 0000000..3adbc28
--- /dev/null
+++ b/src/configs/NavigationData.ts
@@ -0,0 +1,16 @@
+import { NavigationDataType } from "@/app/components/top-navigation/navigationData";
+
+export const NavigationData: NavigationDataType[] = [
+ {
+ content: "شروع",
+ link: "#",
+ },
+ {
+ content: "سخنرانان",
+ link: "/#speakers",
+ },
+ {
+ content: "خرید بلیط",
+ link: "https://frontchapter.ir/product/conf1403/",
+ },
+];