feat: update-layout & add uuid tool (#4)

Co-authored-by: typist <git@mail.typist.cc>
Reviewed-on: #4
This commit is contained in:
2025-10-28 00:55:42 +08:00
parent 0c54293312
commit 24594deecc
8 changed files with 107 additions and 37 deletions

View File

@@ -18,11 +18,13 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"lucide-react": "^0.548.0", "lucide-react": "^0.548.0",
"nanoid": "^5.1.6",
"react": "^19.1.1", "react": "^19.1.1",
"react-dom": "^19.1.1", "react-dom": "^19.1.1",
"react-router-dom": "^7.9.4", "react-router-dom": "^7.9.4",
"tailwind-merge": "^3.3.1", "tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.16" "tailwindcss": "^4.1.16",
"uuid": "^13.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.36.0", "@eslint/js": "^9.36.0",

19
pnpm-lock.yaml generated
View File

@@ -35,6 +35,9 @@ importers:
lucide-react: lucide-react:
specifier: ^0.548.0 specifier: ^0.548.0
version: 0.548.0(react@19.2.0) version: 0.548.0(react@19.2.0)
nanoid:
specifier: ^5.1.6
version: 5.1.6
react: react:
specifier: ^19.1.1 specifier: ^19.1.1
version: 19.2.0 version: 19.2.0
@@ -50,6 +53,9 @@ importers:
tailwindcss: tailwindcss:
specifier: ^4.1.16 specifier: ^4.1.16
version: 4.1.16 version: 4.1.16
uuid:
specifier: ^13.0.0
version: 13.0.0
devDependencies: devDependencies:
'@eslint/js': '@eslint/js':
specifier: ^9.36.0 specifier: ^9.36.0
@@ -1266,6 +1272,11 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
nanoid@5.1.6:
resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==}
engines: {node: ^18 || >=20}
hasBin: true
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@@ -1551,6 +1562,10 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
uuid@13.0.0:
resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==}
hasBin: true
which@2.0.2: which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@@ -2683,6 +2698,8 @@ snapshots:
nanoid@3.3.11: {} nanoid@3.3.11: {}
nanoid@5.1.6: {}
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
node-releases@2.0.26: {} node-releases@2.0.26: {}
@@ -2912,6 +2929,8 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.2.2 '@types/react': 19.2.2
uuid@13.0.0: {}
which@2.0.2: which@2.0.2:
dependencies: dependencies:
isexe: 2.0.0 isexe: 2.0.0

View File

@@ -1,22 +1,32 @@
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar"; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar";
import { tools } from "@/components/tool"; import { tools } from "@/components/tool";
import { Link } from "react-router-dom";
export const AppSidebar = () => ( export const AppSidebar = () => (
<Sidebar> <Sidebar>
<SidebarHeader> <SidebarHeader className="text-2xl font-bold flex justify-center items-center">
Lite Kit Lite Kit
</SidebarHeader> </SidebarHeader>
<SidebarContent> <SidebarContent>
{ <SidebarGroup>
tools.map((tool) => ( <SidebarGroupLabel>
<SidebarMenuItem key={tool.name}> Tools
<SidebarMenuButton> </SidebarGroupLabel>
{tool.icon} <SidebarGroupContent>
{tool.name} {
</SidebarMenuButton> tools.map((tool) => (
</SidebarMenuItem> <SidebarMenuItem key={tool.name}>
)) <SidebarMenuButton asChild>
} <Link to={`/tool/${tool.path}`} title={tool.description}>
{tool.icon}
{tool.name}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))
}
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent> </SidebarContent>
<SidebarFooter> <SidebarFooter>
<a href="mailto:litek@mail.typist.cc">contact us</a> <a href="mailto:litek@mail.typist.cc">contact us</a>

View File

@@ -1,8 +1,14 @@
interface Tool { import { Hash } from 'lucide-react'
name: string;
description: string;
icon: React.ReactNode;
component: React.ReactNode;
}
export const tools: Tool[] = []; import type { Tool } from "./type";
import { UUID } from './uuid'
export const tools: Tool[] = [
{
path: "uuid",
name: "UUID Generator",
description: "Generate a UUID",
icon: <Hash />,
component: <UUID />,
}
];

View File

@@ -0,0 +1,9 @@
import type { ReactNode } from "react";
export interface Tool {
path: string;
name: string;
icon: ReactNode;
description: string;
component: ReactNode;
}

View File

@@ -0,0 +1,22 @@
import { type FC } from "react";
import * as uuid from 'uuid'
import { nanoid } from 'nanoid'
export const UUID: FC = () => {
return (
<div className="flex flex-col gap-4">
<span className="text-sm text-muted-foreground">Refresh the page to generate new UUID</span>
<label>UUID Version 1</label>
<span>{uuid.v1()}</span>
<label>UUID Version 4</label>
<span>{uuid.v4()}</span>
<label>UUID Version 6</label>
<span>{uuid.v6()}</span>
<label>UUID Version 7</label>
<span>{uuid.v7()}</span>
<label>Nano ID</label>
<span>{nanoid()}</span>
</div>
);
};

View File

@@ -1,14 +1,20 @@
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { Sidebar } from "@/components/ui/sidebar"
import type { FC } from "react" import type { FC } from "react"
import { Outlet } from "react-router-dom"; import { Outlet } from "react-router-dom";
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/sidebar";
export const Layout: FC = () => ( export const Layout: FC = () => (
<SidebarProvider> <SidebarProvider>
<Sidebar /> <AppSidebar />
<main> <div className="p-4 flex flex-col w-full h-[100vh]">
<SidebarTrigger /> <nav className="flex items-center justify-between">
<Outlet /> <SidebarTrigger className="size-10" />
</main> <div role="actions" />
</nav>
<main className="flex-1 overflow-auto p-4">
<Outlet />
</main>
</div>
</SidebarProvider> </SidebarProvider>
); );

View File

@@ -4,8 +4,8 @@ import {
RouterProvider, RouterProvider,
} from "react-router-dom"; } from "react-router-dom";
import { Layout } from "./layout";
import { tools } from "@/components/tool"; import { tools } from "@/components/tool";
import { Layout } from "./layout";
// 路由配置 // 路由配置
const router = createBrowserRouter([ const router = createBrowserRouter([
@@ -14,17 +14,17 @@ const router = createBrowserRouter([
element: <Layout />, element: <Layout />,
children: [ children: [
{ {
path: "tools", path: "tool",
children: [ children: [
...tools.map((tool) => ( ...tools.map((tool) => (
{ {
path: tool.name, path: tool.path,
element: tool.component, element: tool.component,
} }
)), )),
{ {
index: true, index: true,
element: null, loader: () => redirect("/tool/uuid"),
}, },
] ]
}, },
@@ -32,15 +32,11 @@ const router = createBrowserRouter([
}, },
{ {
index: true, index: true,
loader: () => { loader: () => redirect("/tool"),
return redirect("/tools");
},
}, },
{ {
path: "*", path: "*",
loader: () => { loader: () => redirect("/tool"),
return redirect("/tools");
},
}, },
]); ]);