done language switching
This commit is contained in:
		@@ -8,8 +8,15 @@ const { title, description } = dictionary[Astro.currentLocale];
 | 
			
		||||
<SinglePage>
 | 
			
		||||
   <div class="h-full max-h-dvh max-w-full grid grid-rows-3 gap-4">
 | 
			
		||||
      <AboutModule row="0" image="/temp.jpg">
 | 
			
		||||
        <h1 class="text-accent">Lorem</h1>
 | 
			
		||||
        <h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Lorem</h1>
 | 
			
		||||
        <p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
 | 
			
		||||
      </AboutModule>
 | 
			
		||||
      <AboutModule row="1" image="/temp.jpg" flipped>
 | 
			
		||||
        <h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Ipsum</h1>
 | 
			
		||||
        <p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
 | 
			
		||||
      </AboutModule>
 | 
			
		||||
      <AboutModule row="2" image="/temp.jpg" alt="image">
 | 
			
		||||
        <h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Dolor</h1>
 | 
			
		||||
        <p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
 | 
			
		||||
      </AboutModule>
 | 
			
		||||
      <AboutModule row="1" image="/temp.jpg" flipped />
 | 
			
		||||
      <AboutModule row="2" image="/temp.jpg" alt="image"/>
 | 
			
		||||
</SinglePage>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,15 +7,15 @@ const { row, flipped, image, alt } = Astro.props;
 | 
			
		||||
        {
 | 
			
		||||
            flipped ? (
 | 
			
		||||
                <>
 | 
			
		||||
                    <div class="bg-accentRed rounded-lg col-start-0 col-span-2 ">
 | 
			
		||||
                    <div class="bg-accentRed/65 rounded-lg col-start-0 col-span-2 hover:bg-accentRed/85 ">
 | 
			
		||||
                        <slot />
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class={`h-full rounded-lg col-start-3 bg-[url('${image}')] bg-no-repeat bg-cover`} />
 | 
			
		||||
                    <div class="h-full rounded-lg col-start-3 bg-no-repeat bg-cover" style={`background-image: url(${image})`} />
 | 
			
		||||
                </>
 | 
			
		||||
            ) : (
 | 
			
		||||
                <>
 | 
			
		||||
                    <div class={`h-full rounded-lg col-start-0 bg-[url('${image}')] bg-no-repeat bg-cover`} />
 | 
			
		||||
                    <div class="bg-accentRed rounded-lg col-start-2 col-span-2">
 | 
			
		||||
                    <div class="h-full rounded-lg col-start-0 bg-no-repeat bg-cover" style={`background-image: url(${image})`} />
 | 
			
		||||
                    <div class="bg-accentRed/65 rounded-lg col-start-2 col-span-2 hover:bg-accentRed/85">
 | 
			
		||||
                        <slot />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								src/components/LangSwitcher.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/components/LangSwitcher.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
"use client"
 | 
			
		||||
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import { navigate } from 'astro:transitions/client';
 | 
			
		||||
 | 
			
		||||
import { icons } from "../lib/icons"
 | 
			
		||||
 | 
			
		||||
import { Button } from "./ui/button"
 | 
			
		||||
import {
 | 
			
		||||
    DropdownMenu,
 | 
			
		||||
    DropdownMenuContent,
 | 
			
		||||
    DropdownMenuRadioGroup,
 | 
			
		||||
    DropdownMenuRadioItem,
 | 
			
		||||
    DropdownMenuTrigger,
 | 
			
		||||
} from "./ui/dropdown-menu"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Please note that clang = lang, it's just for more confusion
 | 
			
		||||
export function LangSwitcher() {
 | 
			
		||||
    function getClang(){
 | 
			
		||||
        const clang = window.location.pathname.substring(1,3);
 | 
			
		||||
        return clang
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [clang, setClang] = React.useState(getClang());
 | 
			
		||||
 | 
			
		||||
    function clinkClang(clang) {
 | 
			
		||||
        console.log(`${clang}`);
 | 
			
		||||
        const currentPath = window.location.pathname.slice(3);
 | 
			
		||||
        setClang(clang);
 | 
			
		||||
        navigate(`/${clang}${currentPath}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <DropdownMenu>
 | 
			
		||||
            <DropdownMenuTrigger asChild>
 | 
			
		||||
                <Button variant="outline" size="icon" className="bg-inherit border-none text-content" dangerouslySetInnerHTML={{ __html: icons["lang"] }} />
 | 
			
		||||
            </DropdownMenuTrigger>
 | 
			
		||||
            <DropdownMenuContent className="w-56">
 | 
			
		||||
                <DropdownMenuRadioGroup value={clang} onValueChange={clinkClang}>
 | 
			
		||||
                    <DropdownMenuRadioItem value="cs">Česky</DropdownMenuRadioItem>
 | 
			
		||||
                    <DropdownMenuRadioItem value="de">Deutsch</DropdownMenuRadioItem>
 | 
			
		||||
                    <DropdownMenuRadioItem value="en">English</DropdownMenuRadioItem>
 | 
			
		||||
                    <DropdownMenuRadioItem value="fr">Français</DropdownMenuRadioItem>
 | 
			
		||||
                </DropdownMenuRadioGroup>
 | 
			
		||||
            </DropdownMenuContent>
 | 
			
		||||
        </DropdownMenu >
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/components/NavButton.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/components/NavButton.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
"use client"
 | 
			
		||||
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
 | 
			
		||||
import { Button } from "./ui/button"
 | 
			
		||||
import { cn } from '../lib/utils'
 | 
			
		||||
import { icons } from "../lib/icons"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function NavButton({selected, variant}) {
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Button variant="outline" size="icon" className={cn("bg-inherit border-none text-content", selected ? "text-accent" : "text-content")} dangerouslySetInnerHTML={{ __html: icons[variant] }} />
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
@@ -1,23 +1,41 @@
 | 
			
		||||
---
 | 
			
		||||
import Navlink from "./Navlink.astro";
 | 
			
		||||
const links = [
 | 
			
		||||
	{
 | 
			
		||||
		display: "Home",
 | 
			
		||||
		href: "/"
 | 
			
		||||
	}, {
 | 
			
		||||
		display: "Blog",
 | 
			
		||||
		href: "/blog"
 | 
			
		||||
	}, {
 | 
			
		||||
		display: "About",
 | 
			
		||||
		href: "/about"
 | 
			
		||||
	}, {
 | 
			
		||||
		display: "Contact",
 | 
			
		||||
		href: "/contact"
 | 
			
		||||
	}
 | 
			
		||||
];
 | 
			
		||||
import { getRelativeLocaleUrl } from "astro:i18n";
 | 
			
		||||
/* import ThemeSelector from "./ThemeSelector" */
 | 
			
		||||
import NavbarSkeleton from "./NavbarSkeleton.astro";
 | 
			
		||||
import { LangSwitcher } from "./LangSwitcher";
 | 
			
		||||
import { NavButton } from "./NavButton";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function selected(path) {
 | 
			
		||||
	return (
 | 
			
		||||
		(Astro.url.pathname
 | 
			
		||||
			.replace(Astro.currentLocale + "/", "")
 | 
			
		||||
			.slice(0, -1) || "/") == path
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
---
 | 
			
		||||
<nav class="w-full flex justify-center">
 | 
			
		||||
	<div class="justify-around w-full md:w-[767px] flex">
 | 
			
		||||
		{ links.map((item) => (<Navlink href={item.href}, display={item.display}, isActive={ (Astro.url.pathname.replace(Astro.currentLocale + "/", "").slice(0,-1) || "/") == item.href}/>)) }
 | 
			
		||||
 | 
			
		||||
<NavbarSkeleton>
 | 
			
		||||
	<!-- Page Navigation -->
 | 
			
		||||
	<div class="flex gap-1">
 | 
			
		||||
		<a href={getRelativeLocaleUrl(Astro.currentLocale, "/")}>
 | 
			
		||||
			<NavButton selected={selected("/")} variant="home"/>
 | 
			
		||||
		</a>
 | 
			
		||||
		<a href={getRelativeLocaleUrl(Astro.currentLocale, "/blog")}>
 | 
			
		||||
			<NavButton selected={selected("/blog")} variant="blog"/>
 | 
			
		||||
		</a>
 | 
			
		||||
	</div>
 | 
			
		||||
</nav>
 | 
			
		||||
 | 
			
		||||
	<!-- Logo -->
 | 
			
		||||
	<div>
 | 
			
		||||
		<!-- <Icon icon="favicon" class={"h-8 w-8 text-content"} /> -->
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<!-- Options (language, light/dark mode) -->
 | 
			
		||||
	<div class="flex gap-4">
 | 
			
		||||
		<!-- <Icon icon="dark_mode" class={"h-8 w-8 hover:text-primary text-content"} /> -->
 | 
			
		||||
		<LangSwitcher client:load client:only/>
 | 
			
		||||
		<!-- <ThemeSelector client:load></ThemeSelector> -->
 | 
			
		||||
	</div>
 | 
			
		||||
</NavbarSkeleton>
 | 
			
		||||
./NavButton
 | 
			
		||||
							
								
								
									
										17
									
								
								src/components/NavbarSkeleton.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/components/NavbarSkeleton.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
<nav class="w-full flex justify-center">
 | 
			
		||||
	<div class="fixed w-full top-0 z-50 bg-bkgNavbar/70 shadow-md rounded-b-md">
 | 
			
		||||
		<div
 | 
			
		||||
			class="sm:grid sm:grid-cols-6 lg:grid-cols-12"
 | 
			
		||||
		>
 | 
			
		||||
			<div
 | 
			
		||||
				class="sm:col-start-2 sm:col-end-6 lg:col-start-3 lg:col-end-11 2xl:col-start-4 2xl:col-end-10 "
 | 
			
		||||
			>
 | 
			
		||||
				<div
 | 
			
		||||
					class="container mx-auto px-6 py-2 flex items-center justify-between"
 | 
			
		||||
				>
 | 
			
		||||
					<slot />
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</nav>
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
import { getRelativeLocaleUrl } from "astro:i18n";
 | 
			
		||||
 | 
			
		||||
const { display, href, isActive } = Astro.props;
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<a
 | 
			
		||||
    href={getRelativeLocaleUrl(Astro.currentLocale, href)}
 | 
			
		||||
    class={(isActive ? "bg-accent " : "bg-content hover:bg-primary ") + " w-full text-center mx-0.5"}
 | 
			
		||||
    ><span>{display}</span></a
 | 
			
		||||
>
 | 
			
		||||
							
								
								
									
										0
									
								
								src/components/ThemeSelector.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/components/ThemeSelector.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										47
									
								
								src/components/ui/button.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/components/ui/button.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import { Slot } from "@radix-ui/react-slot"
 | 
			
		||||
import { cva } from "class-variance-authority";
 | 
			
		||||
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
 | 
			
		||||
const buttonVariants = cva(
 | 
			
		||||
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none  focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
 | 
			
		||||
  {
 | 
			
		||||
    variants: {
 | 
			
		||||
      variant: {
 | 
			
		||||
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
 | 
			
		||||
        destructive:
 | 
			
		||||
          "bg-destructive text-destructive-foreground hover:bg-destructive/90",
 | 
			
		||||
        outline:
 | 
			
		||||
          "border border-input bg-background hover:bg-primary hover:text-accent-foreground",
 | 
			
		||||
        secondary:
 | 
			
		||||
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
 | 
			
		||||
        ghost: "hover:bg-accent hover:text-accent-foreground",
 | 
			
		||||
        link: "text-primary underline-offset-4 hover:underline",
 | 
			
		||||
      },
 | 
			
		||||
      size: {
 | 
			
		||||
        default: "h-10 px-4 py-2",
 | 
			
		||||
        sm: "h-9 rounded-md px-3",
 | 
			
		||||
        lg: "h-11 rounded-md px-8",
 | 
			
		||||
        icon: "h-10 w-10",
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    defaultVariants: {
 | 
			
		||||
      variant: "default",
 | 
			
		||||
      size: "default",
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
 | 
			
		||||
  const Comp = asChild ? Slot : "button"
 | 
			
		||||
  return (
 | 
			
		||||
    (<Comp
 | 
			
		||||
      className={cn(buttonVariants({ variant, size, className }))}
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      {...props} />)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
Button.displayName = "Button"
 | 
			
		||||
 | 
			
		||||
export { Button, buttonVariants }
 | 
			
		||||
							
								
								
									
										155
									
								
								src/components/ui/dropdown-menu.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/components/ui/dropdown-menu.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
 | 
			
		||||
import { Check, ChevronRight, Circle } from "lucide-react"
 | 
			
		||||
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
 | 
			
		||||
const DropdownMenu = DropdownMenuPrimitive.Root
 | 
			
		||||
 | 
			
		||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
 | 
			
		||||
 | 
			
		||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group
 | 
			
		||||
 | 
			
		||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub
 | 
			
		||||
 | 
			
		||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.SubTrigger
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
 | 
			
		||||
      inset && "pl-8",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}>
 | 
			
		||||
    {children}
 | 
			
		||||
    <ChevronRight className="ml-auto h-4 w-4" />
 | 
			
		||||
  </DropdownMenuPrimitive.SubTrigger>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSubTrigger.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.SubTrigger.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.SubContent
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSubContent.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.SubContent.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Portal>
 | 
			
		||||
    <DropdownMenuPrimitive.Content
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      sideOffset={sideOffset}
 | 
			
		||||
      className={cn(
 | 
			
		||||
        "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 | 
			
		||||
        className
 | 
			
		||||
      )}
 | 
			
		||||
      {...props} />
 | 
			
		||||
  </DropdownMenuPrimitive.Portal>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Item
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      inset && "pl-8",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.CheckboxItem
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    checked={checked}
 | 
			
		||||
    {...props}>
 | 
			
		||||
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
 | 
			
		||||
      <DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
        <Check className="h-4 w-4" />
 | 
			
		||||
      </DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
    </span>
 | 
			
		||||
    {children}
 | 
			
		||||
  </DropdownMenuPrimitive.CheckboxItem>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuCheckboxItem.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.CheckboxItem.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.RadioItem
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}>
 | 
			
		||||
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
 | 
			
		||||
      <DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
        <Circle className="h-2 w-2 fill-current" />
 | 
			
		||||
      </DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
    </span>
 | 
			
		||||
    {children}
 | 
			
		||||
  </DropdownMenuPrimitive.RadioItem>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Label
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Separator
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("-mx-1 my-1 h-px bg-muted", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuShortcut = ({
 | 
			
		||||
  className,
 | 
			
		||||
  ...props
 | 
			
		||||
}) => {
 | 
			
		||||
  return (
 | 
			
		||||
    (<span
 | 
			
		||||
      className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
 | 
			
		||||
      {...props} />)
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  DropdownMenu,
 | 
			
		||||
  DropdownMenuTrigger,
 | 
			
		||||
  DropdownMenuContent,
 | 
			
		||||
  DropdownMenuItem,
 | 
			
		||||
  DropdownMenuCheckboxItem,
 | 
			
		||||
  DropdownMenuRadioItem,
 | 
			
		||||
  DropdownMenuLabel,
 | 
			
		||||
  DropdownMenuSeparator,
 | 
			
		||||
  DropdownMenuShortcut,
 | 
			
		||||
  DropdownMenuGroup,
 | 
			
		||||
  DropdownMenuPortal,
 | 
			
		||||
  DropdownMenuSub,
 | 
			
		||||
  DropdownMenuSubContent,
 | 
			
		||||
  DropdownMenuSubTrigger,
 | 
			
		||||
  DropdownMenuRadioGroup,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/icons/blog.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/icons/blog.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z" />
 | 
			
		||||
  </svg>
 | 
			
		||||
  
 | 
			
		||||
| 
		 After Width: | Height: | Size: 485 B  | 
							
								
								
									
										4
									
								
								src/icons/dark_mode.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/icons/dark_mode.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
 | 
			
		||||
  </svg>
 | 
			
		||||
  
 | 
			
		||||
| 
		 After Width: | Height: | Size: 387 B  | 
							
								
								
									
										3
									
								
								src/icons/favicon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/icons/favicon.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 128 128">
 | 
			
		||||
    <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 614 B  | 
							
								
								
									
										4
									
								
								src/icons/home.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/icons/home.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
 | 
			
		||||
  </svg>
 | 
			
		||||
  
 | 
			
		||||
| 
		 After Width: | Height: | Size: 441 B  | 
							
								
								
									
										3
									
								
								src/icons/lang.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/icons/lang.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
  <path stroke-linecap="round" stroke-linejoin="round" d="m10.5 21 5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 0 1 6-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 0 1-3.827-5.802" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 441 B  | 
							
								
								
									
										4
									
								
								src/icons/light_mode.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/icons/light_mode.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
 | 
			
		||||
</svg>
 | 
			
		||||
      
 | 
			
		||||
| 
		 After Width: | Height: | Size: 400 B  | 
@@ -2,6 +2,7 @@
 | 
			
		||||
const { title, description, lang, themeOverride } = Astro.props;
 | 
			
		||||
import Navbar from "../components/Navbar.astro";
 | 
			
		||||
import "../style/index.css";
 | 
			
		||||
import "../style/globals.css";
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<!doctype html>
 | 
			
		||||
@@ -10,10 +11,11 @@ import "../style/index.css";
 | 
			
		||||
        <meta charset="UTF-8" />
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
        <meta name="description" content={description} />
 | 
			
		||||
        <link rel="shortcut icon" href="/favicon.svg">
 | 
			
		||||
        <title>{title}</title>
 | 
			
		||||
    </head>
 | 
			
		||||
    <body class="bg-bkg" >
 | 
			
		||||
        <!--<Navbar /> -->
 | 
			
		||||
        <Navbar />
 | 
			
		||||
        <div class="bg-bkg h-dvh w-full overflow-y-scroll snap-mandatory snap-y scroll-smooth">
 | 
			
		||||
            <slot />
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<div class="snap-start w-screen h-screen overflow-clip">
 | 
			
		||||
<div class="snap-start w-screen h-screen overflow-clip pt-10">
 | 
			
		||||
	<div class="bg-bkg h-full w-full sm:grid sm:grid-cols-6 lg:grid-cols-12">
 | 
			
		||||
		<div
 | 
			
		||||
			class="sm:col-start-2 sm:col-end-6 lg:col-start-3 lg:col-end-11 h-full p-2 sm:p-6"
 | 
			
		||||
			class="sm:col-start-2 sm:col-end-6 lg:col-start-3 lg:col-end-11 2xl:col-start-4 2xl:col-end-10 h-full p-2 sm:p-6"
 | 
			
		||||
		>
 | 
			
		||||
			<slot />
 | 
			
		||||
		</div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								src/lib/icons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/lib/icons.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
const home = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
 | 
			
		||||
    </svg>`;
 | 
			
		||||
const blog = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z" />
 | 
			
		||||
    </svg>`;
 | 
			
		||||
const dark_theme = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
 | 
			
		||||
    </svg>`;
 | 
			
		||||
const light_theme = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
 | 
			
		||||
    </svg>`;
 | 
			
		||||
const lang = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" d="m10.5 21 5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 0 1 6-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 0 1-3.827-5.802" />
 | 
			
		||||
</svg>`
 | 
			
		||||
 | 
			
		||||
export const icons = { home: home, blog: blog, dark_theme: dark_theme, light_theme: light_theme, lang:lang };
 | 
			
		||||
							
								
								
									
										6
									
								
								src/lib/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/lib/utils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import { clsx } from "clsx"
 | 
			
		||||
import { twMerge } from "tailwind-merge"
 | 
			
		||||
 | 
			
		||||
export function cn(...inputs) {
 | 
			
		||||
  return twMerge(clsx(inputs))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								src/style/globals.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/style/globals.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
@tailwind base;
 | 
			
		||||
@tailwind components;
 | 
			
		||||
@tailwind utilities;
 | 
			
		||||
 | 
			
		||||
@layer base {
 | 
			
		||||
  :root {
 | 
			
		||||
    --background: 0 0% 100%;
 | 
			
		||||
    --foreground: 222.2 47.4% 11.2%;
 | 
			
		||||
 | 
			
		||||
    --muted: 210 40% 96.1%;
 | 
			
		||||
    --muted-foreground: 215.4 16.3% 46.9%;
 | 
			
		||||
 | 
			
		||||
    --popover: 0 0% 100%;
 | 
			
		||||
    --popover-foreground: 222.2 47.4% 11.2%;
 | 
			
		||||
 | 
			
		||||
    --border: 214.3 31.8% 91.4%;
 | 
			
		||||
    --input: 214.3 31.8% 91.4%;
 | 
			
		||||
 | 
			
		||||
    --card: 0 0% 100%;
 | 
			
		||||
    --card-foreground: 222.2 47.4% 11.2%;
 | 
			
		||||
 | 
			
		||||
    --primary: 222.2 47.4% 11.2%;
 | 
			
		||||
    --primary-foreground: 210 40% 98%;
 | 
			
		||||
 | 
			
		||||
    --secondary: 210 40% 96.1%;
 | 
			
		||||
    --secondary-foreground: 222.2 47.4% 11.2%;
 | 
			
		||||
 | 
			
		||||
    --accent: 210 40% 96.1%;
 | 
			
		||||
    --accent-foreground: 222.2 47.4% 11.2%;
 | 
			
		||||
 | 
			
		||||
    --destructive: 0 100% 50%;
 | 
			
		||||
    --destructive-foreground: 210 40% 98%;
 | 
			
		||||
 | 
			
		||||
    --ring: 215 20.2% 65.1%;
 | 
			
		||||
 | 
			
		||||
    --radius: 0.5rem;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dark {
 | 
			
		||||
    --background: 224 71% 4%;
 | 
			
		||||
    --foreground: 213 31% 91%;
 | 
			
		||||
 | 
			
		||||
    --muted: 223 47% 11%;
 | 
			
		||||
    --muted-foreground: 215.4 16.3% 56.9%;
 | 
			
		||||
 | 
			
		||||
    --accent: 216 34% 17%;
 | 
			
		||||
    --accent-foreground: 210 40% 98%;
 | 
			
		||||
 | 
			
		||||
    --popover: 224 71% 4%;
 | 
			
		||||
    --popover-foreground: 215 20.2% 65.1%;
 | 
			
		||||
 | 
			
		||||
    --border: 216 34% 17%;
 | 
			
		||||
    --input: 216 34% 17%;
 | 
			
		||||
 | 
			
		||||
    --card: 224 71% 4%;
 | 
			
		||||
    --card-foreground: 213 31% 91%;
 | 
			
		||||
 | 
			
		||||
    --primary: 210 40% 98%;
 | 
			
		||||
    --primary-foreground: 222.2 47.4% 1.2%;
 | 
			
		||||
 | 
			
		||||
    --secondary: 222.2 47.4% 11.2%;
 | 
			
		||||
    --secondary-foreground: 210 40% 98%;
 | 
			
		||||
 | 
			
		||||
    --destructive: 0 63% 31%;
 | 
			
		||||
    --destructive-foreground: 210 40% 98%;
 | 
			
		||||
 | 
			
		||||
    --ring: 216 34% 17%;
 | 
			
		||||
 | 
			
		||||
    --radius: 0.5rem;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,6 +8,7 @@ Dark Mode:  https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
 | 
			
		||||
@layer base {
 | 
			
		||||
    :root {
 | 
			
		||||
        --color-bkg: 0deg, 0%, 94%;
 | 
			
		||||
        --color-bkgNavbar: 0deg, 0%, 50%;
 | 
			
		||||
        --color-content: 240deg, 4%, 9%;
 | 
			
		||||
        --color-primary: 54deg, 100%, 50%;
 | 
			
		||||
        --color-secondary: 237deg, 100%, 93%;
 | 
			
		||||
@@ -18,6 +19,7 @@ Dark Mode:  https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
 | 
			
		||||
    @media (prefers-color-scheme: dark) {
 | 
			
		||||
        :root {
 | 
			
		||||
            --color-bkg: 0deg, 0%, 6%;
 | 
			
		||||
            --color-bkgNavbar: 0deg, 0%, 17%;
 | 
			
		||||
            --color-content: 240deg, 4%, 91%;
 | 
			
		||||
            --color-primary: 262deg, 77%, 44%;
 | 
			
		||||
            --color-secondary: 273deg, 100%, 20%;
 | 
			
		||||
@@ -28,6 +30,7 @@ Dark Mode:  https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
 | 
			
		||||
 | 
			
		||||
    :root[data-theme="dark"] {
 | 
			
		||||
        --color-bkg: 0deg, 0%, 6%;
 | 
			
		||||
        --color-bkgNavbar: 0deg, 0%, 17%;
 | 
			
		||||
        --color-content: 240deg, 4%, 91%;
 | 
			
		||||
        --color-primary: 262deg, 77%, 44%;
 | 
			
		||||
        --color-secondary: 273deg, 100%, 20%;
 | 
			
		||||
@@ -37,6 +40,7 @@ Dark Mode:  https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
 | 
			
		||||
 | 
			
		||||
    :root[data-theme="light"] {
 | 
			
		||||
        --color-bkg: 0deg, 0%, 94%;
 | 
			
		||||
        --color-bkgNavbar: 0deg, 0%, 50%;
 | 
			
		||||
        --color-content: 240deg, 4%, 9%;
 | 
			
		||||
        --color-primary: 54deg, 100%, 50%;
 | 
			
		||||
        --color-secondary: 237deg, 100%, 93%;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user