feat: initialize zhixing-web with React, React Router, and Tailwind CSS

- Set up the main application structure with App component and routing.
- Implemented global state management for UI theme using Zustand.
- Created API utilities for fetching system status.
- Developed system status page with responsive design and theme toggle.
- Added testing setup with Vitest and initial tests for system status page.
- Configured TypeScript with appropriate settings for the application.
- Integrated Tailwind CSS for styling and responsive design.
- Established Vite configuration for development and testing environments.
This commit is contained in:
yuxuanhui
2026-08-03 13:47:24 +08:00
commit 844d8416bd
61 changed files with 4694 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
import { cva, type VariantProps } from "class-variance-authority"
import type { HTMLAttributes } from "react"
import { cn } from "@/shared/ui/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground",
destructive: "border-transparent bg-destructive text-white",
outline: "text-foreground",
},
},
defaultVariants: { variant: "default" },
},
)
export function Badge({
className,
variant,
...props
}: HTMLAttributes<HTMLSpanElement> & VariantProps<typeof badgeVariants>) {
return (
<span className={cn(badgeVariants({ variant }), className)} {...props} />
)
}
+39
View File
@@ -0,0 +1,39 @@
import { cva, type VariantProps } from "class-variance-authority"
import type { ButtonHTMLAttributes } from "react"
import { cn } from "@/shared/ui/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
outline:
"border bg-background hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-9 px-4 py-2",
icon: "size-9",
},
},
defaultVariants: { size: "default", variant: "default" },
},
)
export function Button({
className,
size,
type = "button",
variant,
...props
}: ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof buttonVariants>) {
return (
<button
className={cn(buttonVariants({ size, variant }), className)}
type={type}
{...props}
/>
)
}
+55
View File
@@ -0,0 +1,55 @@
import type { HTMLAttributes } from "react"
import { cn } from "@/shared/ui/utils"
export function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className,
)}
{...props}
/>
)
}
export function CardHeader({
className,
...props
}: HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
)
}
export function CardTitle({
className,
...props
}: HTMLAttributes<HTMLHeadingElement>) {
return (
<h1
className={cn("font-semibold leading-none tracking-tight", className)}
{...props}
/>
)
}
export function CardDescription({
className,
...props
}: HTMLAttributes<HTMLParagraphElement>) {
return (
<p className={cn("text-sm text-muted-foreground", className)} {...props} />
)
}
export function CardContent({
className,
...props
}: HTMLAttributes<HTMLDivElement>) {
return <div className={cn("p-6 pt-0", className)} {...props} />
}
+6
View File
@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}