From b3f740ca46346bfccdf1cec74c59716775dcf502 Mon Sep 17 00:00:00 2001 From: Rene Arumetsa Date: Fri, 1 May 2026 20:06:56 +0300 Subject: [PATCH] Add navbar --- public/tipilan-icon-white.svg | 7 ++ src/app/[locale]/reeglid/[slug]/page.tsx | 110 ----------------------- src/app/[locale]/reeglid/page.tsx | 66 -------------- src/components/Header.tsx | 94 +++++++++++++++---- src/components/SidebarLayoutClient.tsx | 52 +---------- src/components/SidebarLayoutServer.tsx | 1 - 6 files changed, 85 insertions(+), 245 deletions(-) create mode 100644 public/tipilan-icon-white.svg delete mode 100644 src/app/[locale]/reeglid/[slug]/page.tsx delete mode 100644 src/app/[locale]/reeglid/page.tsx diff --git a/public/tipilan-icon-white.svg b/public/tipilan-icon-white.svg new file mode 100644 index 0000000..8c1c759 --- /dev/null +++ b/public/tipilan-icon-white.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/app/[locale]/reeglid/[slug]/page.tsx b/src/app/[locale]/reeglid/[slug]/page.tsx deleted file mode 100644 index 785f3cd..0000000 --- a/src/app/[locale]/reeglid/[slug]/page.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { notFound } from "next/navigation"; -import ReactMarkdown, { Components } from "react-markdown"; -import { vipnagorgialla } from "@/components/Vipnagorgialla"; -import SectionDivider from "@/components/SectionDivider"; -import { getTranslations, setRequestLocale } from "next-intl/server"; -import { loadRulesBun } from "@/lib/loadRules"; - -// Map of valid slugs to their translation keys -const rulesMap = { - lol: { - titleKey: "rules.lolRules", - }, - cs2: { - titleKey: "rules.cs2Rules", - }, -} as const; - -type RuleSlug = keyof typeof rulesMap; - -interface PageProps { - params: Promise<{ slug: string; locale: string }>; -} - -async function getRuleContent(slug: string, locale: string) { - if (!Object.keys(rulesMap).includes(slug)) { - return null; - } - - const ruleConfig = rulesMap[slug as RuleSlug]; - - try { - const content = await loadRulesBun( - slug as "cs2" | "lol", - locale as "et" | "en", - ); - return { - content, - titleKey: ruleConfig.titleKey, - }; - } catch (error) { - console.error( - `Error reading rule file for slug ${slug} in locale ${locale}:`, - error, - ); - return null; - } -} - -export default async function RulePage({ params }: PageProps) { - const { slug, locale } = await params; - setRequestLocale(locale); - const t = await getTranslations({ locale }); - const ruleData = await getRuleContent(slug, locale); - - if (!ruleData) { - notFound(); - } - - const headingStyle = `text-5xl sm:text-6xl ${vipnagorgialla.className} font-bold uppercase italic text-[#2A2C3F] dark:text-[#EEE5E5]`; - - return ( -
-
-

- {t(ruleData.titleKey)} -

- -
- ( -

- {props.children} -

- ), - h2: (props) => ( -

- {props.children} -

- ), - ol: (props) => ( -
    - {props.children} -
- ), - ul: (props) => ( -
    - {props.children} -
- ), - p: (props) =>

{props.children}

, - } as Components - } - > - {ruleData.content} -
-
-
- - -
- ); -} - -export async function generateStaticParams() { - return Object.keys(rulesMap).map((slug) => ({ - slug, - })); -} diff --git a/src/app/[locale]/reeglid/page.tsx b/src/app/[locale]/reeglid/page.tsx deleted file mode 100644 index 48dbcc8..0000000 --- a/src/app/[locale]/reeglid/page.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { vipnagorgialla } from "@/components/Vipnagorgialla"; -import SectionDivider from "@/components/SectionDivider"; -import { getTranslations, setRequestLocale } from "next-intl/server"; -import NextLink from "next/link"; - -export default async function RulesMenu({ - params, -}: { - params: Promise<{ locale: string }>; -}) { - const { locale } = await params; - - setRequestLocale(locale); - - const t = await getTranslations({ locale }); - - const headingStyle = `text-4xl md:text-5xl lg:text-6xl ${vipnagorgialla.className} font-bold italic text-[#2A2C3F] dark:text-[#EEE5E5] uppercase`; - - const boxStyle = `-skew-x-2 md:-skew-x-5 text-white md:px-12 hover:scale-103 transition-all duration-150 w-full md:w-xl lg:w-[400px]`; - - const boxTextStyle = `text-2xl md:text-3xl ${vipnagorgialla.className} font-bold uppercase text-[#EEE5E5] pb-2 break-normal whitespace-pre-line`; - - return ( -
-
-

- {t("rules.title")} -

- -
- -
-

{t("rules.houseRules")}

-
-
- - -
-

{t("rules.cs2Rules")}

-
-
- - -
-

{t("rules.lolRules")}

-
-
- - {/* Minitourn. link coming soon*/} - {/**/} - {/* ajutine div. kui asendate lingiga, siis saab selle ära võtta */} -
-
-

{t("rules.miniRules")}

-
-
- {/**/} -
-
- - -
- ); -} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 381c1f6..c759db6 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,8 +1,11 @@ "use client"; +import Image from "next/image"; +import { Link } from "@/i18n/routing"; +import { vipnagorgialla } from "@/components/Vipnagorgialla"; + // Icons import { - MdClose, MdMenu, MdSunny, MdModeNight, @@ -23,32 +26,63 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; -// Fonts -// import { vipnagorgialla } from "@/components/Vipnagorgialla"; +interface NavItem { + href: + | "/" + | "/ajakava" + | "/haldus" + | "/kodukord" + | "/messiala" + | "/piletid" + | "/striim" + | "/turniirid"; + label: string; +} interface HeaderProps { - isOpen: boolean; - onToggle: () => void; themeLabels: { light: string; dark: string; system: string; }; + navItems: NavItem[]; } -const Header = ({ isOpen, onToggle, themeLabels }: HeaderProps) => { +const Header = ({ themeLabels, navItems }: HeaderProps) => { const { theme, setTheme } = useTheme(); + // Filter nav items for the horizontal bar (exclude kodukord) + const mainNavItems = navItems.filter( + (item) => item.href !== "/kodukord" + ); + return ( -
- -
+
+ {/* Logo */} + + TipiLAN + + + {/* Right side - Navigation + controls */} +
+ {/* Desktop Navigation */} + @@ -57,8 +91,8 @@ const Header = ({ isOpen, onToggle, themeLabels }: HeaderProps) => { size="icon" className="size-10 cursor-pointer" > - - + + Toggle theme @@ -93,6 +127,32 @@ const Header = ({ isOpen, onToggle, themeLabels }: HeaderProps) => { + + {/* Mobile menu button */} + + + + + + {navItems.map((item) => ( + + + {item.label} + + + ))} + +
); diff --git a/src/components/SidebarLayoutClient.tsx b/src/components/SidebarLayoutClient.tsx index 470a2d0..26c4933 100644 --- a/src/components/SidebarLayoutClient.tsx +++ b/src/components/SidebarLayoutClient.tsx @@ -1,9 +1,5 @@ "use client"; -import { useState, useEffect } from "react"; -import { usePathname } from "@/i18n/routing"; -import { Link } from "@/i18n/routing"; -import { vipnagorgialla } from "@/components/Vipnagorgialla"; import Header from "./Header"; interface NavItem { @@ -14,7 +10,6 @@ interface NavItem { | "/kodukord" | "/messiala" | "/piletid" - | "/reeglid" | "/striim" | "/turniirid"; label: string; @@ -33,52 +28,7 @@ export default function SidebarLayoutClient({ themeLabels, navItems, }: SidebarLayoutClientProps) { - const [isOpen, setIsOpen] = useState(false); - const pathname = usePathname(); - - const toggleSidebar = () => setIsOpen(!isOpen); - - // Close sidebar when route changes - useEffect(() => { - if (isOpen) { - setIsOpen(false); - } - }, [pathname]); - return ( - <> -
- - {/* Sidebar */} - <> -
setIsOpen(false)} - >
-
- {navItems.map((item) => ( - - {item.label} - - ))} -
- - +
); } diff --git a/src/components/SidebarLayoutServer.tsx b/src/components/SidebarLayoutServer.tsx index 97820b9..c02b912 100644 --- a/src/components/SidebarLayoutServer.tsx +++ b/src/components/SidebarLayoutServer.tsx @@ -19,7 +19,6 @@ export default async function SidebarLayoutServer() { { href: "/ajakava" as const, label: navT("schedule") }, { href: "/turniirid" as const, label: navT("tournaments") }, { href: "/kodukord" as const, label: navT("houserules") }, - { href: "/reeglid" as const, label: navT("rules") }, ]; return ;