Skip to content

Commit 2f5dd30

Browse files
committed
feat: add more page
1 parent 7144d1a commit 2f5dd30

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2394
-275
lines changed

web/biome.json

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
2+
"$schema": "https://biomejs.dev/schemas/2.0.5/schema.json",
33
"vcs": {
44
"enabled": true,
55
"clientKind": "git",
@@ -13,7 +13,17 @@
1313
"noExplicitAny": "off"
1414
},
1515
"style": {
16-
"useImportType": "off"
16+
"useImportType": "off",
17+
"noParameterAssign": "error",
18+
"useAsConstAssertion": "error",
19+
"useDefaultParameterLast": "error",
20+
"useEnumInitializers": "error",
21+
"useSelfClosingElements": "error",
22+
"useSingleVarDeclarator": "error",
23+
"noUnusedTemplateLiteral": "error",
24+
"useNumberNamespace": "error",
25+
"noInferrableTypes": "error",
26+
"noUselessElse": "error"
1727
},
1828
"recommended": true,
1929
"a11y": {
@@ -24,19 +34,16 @@
2434
"noUnusedImports": "warn"
2535
}
2636
},
27-
"ignore": ["node_modules", "tsconfig*", "dist", "components/ui/**"]
37+
"includes": ["**", "!**/node_modules", "!**/tsconfig*", "!**/dist", "!**/components/ui/**"]
2838
},
2939
"formatter": {
3040
"indentStyle": "space",
3141
"indentWidth": 2,
3242
"enabled": true,
3343
"lineWidth": 120,
34-
"ignore": ["node_modules", "tsconfig*", "dist"]
35-
},
36-
"organizeImports": {
37-
"enabled": true,
38-
"ignore": ["node_modules", "dist", "components/ui/**"]
44+
"includes": ["**", "!**/node_modules", "!**/tsconfig*", "!**/dist"]
3945
},
46+
"assist": { "actions": { "source": { "organizeImports": "on" } } },
4047
"javascript": {
4148
"formatter": {
4249
"quoteStyle": "double"

web/bun.lockb

5.16 KB
Binary file not shown.

web/copy-build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
1+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
22
import { cp } from "node:fs/promises";
33
import { join, resolve } from "node:path";
44

web/package.json

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,67 +14,46 @@
1414
"lint:fix": "bunx @biomejs/biome check ./ --write"
1515
},
1616
"devDependencies": {
17-
"@biomejs/biome": "1.9.4",
18-
"@types/node": "^22.15.29",
19-
"@types/react": "^19.1.6",
17+
"@biomejs/biome": "2.0.5",
18+
"@types/node": "^24.0.4",
19+
"@types/react": "^19.1.8",
2020
"@types/react-copy-to-clipboard": "^5.0.7",
2121
"@types/react-dom": "^19.1.6",
2222
"@types/react-syntax-highlighter": "^15.5.13",
23-
"@vitejs/plugin-react": "^4.5.1",
23+
"@vitejs/plugin-react": "^4.6.0",
2424
"rimraf": "^6.0.1",
25-
"tailwindcss": "^4.1.8",
25+
"tailwindcss": "^4.1.10",
2626
"typescript": "^5.8.3",
27-
"vite": "^6.3.5",
27+
"vite": "^7.0.0",
2828
"vite-bundle-visualizer": "^1.2.1"
2929
},
3030
"dependencies": {
31-
"@hookform/resolvers": "^5.0.1",
32-
"@radix-ui/react-accordion": "^1.2.11",
33-
"@radix-ui/react-alert-dialog": "^1.1.14",
34-
"@radix-ui/react-aspect-ratio": "^1.1.7",
35-
"@radix-ui/react-avatar": "^1.1.10",
36-
"@radix-ui/react-checkbox": "^1.3.2",
37-
"@radix-ui/react-context-menu": "^2.2.15",
38-
"@radix-ui/react-dialog": "^1.1.14",
39-
"@radix-ui/react-dropdown-menu": "^2.1.15",
40-
"@radix-ui/react-hover-card": "^1.1.14",
41-
"@radix-ui/react-label": "^2.1.7",
42-
"@radix-ui/react-menubar": "^1.1.15",
31+
"@hookform/resolvers": "^5.1.1",
4332
"@radix-ui/react-navigation-menu": "^1.2.13",
4433
"@radix-ui/react-popover": "^1.1.14",
45-
"@radix-ui/react-progress": "^1.1.7",
46-
"@radix-ui/react-radio-group": "^1.3.7",
47-
"@radix-ui/react-scroll-area": "^1.2.9",
48-
"@radix-ui/react-select": "^2.2.5",
49-
"@radix-ui/react-separator": "^1.1.7",
50-
"@radix-ui/react-slot": "^1.2.3",
51-
"@radix-ui/react-switch": "^1.2.5",
52-
"@radix-ui/react-tabs": "^1.1.12",
53-
"@radix-ui/react-toggle": "^1.1.9",
54-
"@radix-ui/react-toggle-group": "^1.1.10",
55-
"@radix-ui/react-tooltip": "^1.2.7",
56-
"@tailwindcss/vite": "^4.1.8",
57-
"@tanstack/react-query": "^5.80.3",
34+
"@tailwindcss/vite": "^4.1.10",
35+
"@tanstack/react-query": "^5.81.2",
5836
"class-variance-authority": "^0.7.1",
5937
"clsx": "^2.1.1",
60-
"date-fns": "^4.1.0",
38+
"framer-motion": "^12.19.1",
6139
"i18next": "^25.2.1",
62-
"lucide-react": "^0.513.0",
40+
"lucide-react": "^0.523.0",
41+
"motion": "^12.19.1",
42+
"radix-ui": "^1.4.2",
6343
"react": "^19.1.0",
6444
"react-copy-to-clipboard": "^5.1.0",
65-
"react-day-picker": "9.7.0",
6645
"react-dom": "^19.1.0",
67-
"react-hook-form": "^7.57.0",
68-
"react-i18next": "^15.5.2",
46+
"react-hook-form": "^7.58.1",
47+
"react-i18next": "^15.5.3",
6948
"react-router": "^7.6.2",
7049
"react-router-dom": "^7.6.2",
7150
"react-syntax-highlighter": "^15.6.1",
7251
"sonner": "^2.0.5",
73-
"tailwind-merge": "^3.3.0",
74-
"tailwind-scrollbar": "^4.0.2",
52+
"tailwind-merge": "^3.3.1",
7553
"tw-animate-css": "^1.3.4",
76-
"yup": "^1.6.1",
77-
"zod": "^3.25.51"
54+
"yup": "^1.6.1"
7855
},
79-
"trustedDependencies": ["@biomejs/biome"]
56+
"trustedDependencies": [
57+
"@biomejs/biome"
58+
]
8059
}

web/src/components/code-viewer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Button, buttonVariants } from "@/components/ui/button";
2-
import { cn } from "@/lib/utils";
31
import { VariantProps } from "class-variance-authority";
42
import { Check, Copy } from "lucide-react";
53
import { type HTMLProps, type ReactNode, useCallback, useEffect, useState } from "react";
@@ -8,6 +6,8 @@ import { useTranslation } from "react-i18next";
86
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
97
import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism";
108
import { toast } from "sonner";
9+
import { Button, buttonVariants } from "@/components/ui/button";
10+
import { cn } from "@/lib/utils";
1111

1212
interface CopyButtonProps extends React.ComponentProps<"button"> {
1313
value: string;

web/src/components/copyable-field.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { Button } from "@/components/ui/button";
2-
import { Label } from "@/components/ui/label";
31
import { Check, Copy } from "lucide-react";
42
import { useCallback, useEffect, useState } from "react";
53
import { CopyToClipboard } from "react-copy-to-clipboard";
64
import { useTranslation } from "react-i18next";
75
import { toast } from "sonner";
6+
import { Button } from "@/components/ui/button";
7+
import { Label } from "@/components/ui/label";
88

99
interface CopyableFieldProps {
1010
label: string;

web/src/components/layouts/root-layout.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
1+
import { NavLink } from "react-router";
2+
import { Outlet } from "react-router-dom";
13
import { LanguageSwitcher } from "@/components/language-switcher";
24
import { ModeToggle } from "@/components/mode-toggle.tsx";
35
import { ThemeProvider } from "@/components/theme-provider.tsx";
46
import { Button } from "@/components/ui/button";
57
import { Toaster } from "@/components/ui/sonner";
68
import VersionBadge from "@/components/version-badge";
79
import { GitHubIcon } from "@/icon";
8-
import { Outlet } from "react-router-dom";
10+
import { siteConfig } from "@/lib/config";
11+
import { MobileNav } from "../modile-nav";
912

1013
export default function RootLayout() {
1114
return (
1215
<ThemeProvider defaultTheme="system" storageKey="vite-ui-theme">
1316
<Toaster />
1417
<div className="flex flex-col h-screen">
1518
<header className="sticky top-0 z-50 border-b bg-background px-2 sm:px-4 py-2 sm:py-3">
16-
<div className="flex flex-col sm:flex-row items-center justify-between gap-2 sm:gap-0">
17-
<div className="flex items-center">
18-
<h2 className="text-base sm:text-lg font-semibold text-center">MemShellParty - JavaWeb</h2>
19+
<div className="flex items-center gap-2">
20+
<MobileNav className="flex lg:hidden" items={siteConfig.navItems} />
21+
<div className="hidden lg:flex">
22+
<NavLink to="/" className="text-base sm:text-lg font-semibold text-center">
23+
MemShellParty
24+
</NavLink>
1925
</div>
20-
<div className="flex items-center gap-0.5 sm:gap-1">
26+
<nav className="items-center gap-0.5 hidden lg:flex">
27+
{siteConfig.navItems.map((item) => (
28+
<Button key={item.href} variant="ghost" size="sm" asChild>
29+
<NavLink to={item.href}>{item.label}</NavLink>
30+
</Button>
31+
))}
32+
</nav>
33+
<div className="ml-auto flex items-center gap-2 md:flex-1 md:justify-end">
2134
<VersionBadge />
2235
<LanguageSwitcher />
2336
<Button
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { MotionProps, motion } from "motion/react";
2+
import { cn } from "@/lib/utils";
3+
4+
interface LineShadowTextProps extends Omit<React.HTMLAttributes<HTMLElement>, keyof MotionProps>, MotionProps {
5+
shadowColor?: string;
6+
as?: React.ElementType;
7+
}
8+
9+
export function LineShadowText({
10+
children,
11+
shadowColor = "black",
12+
className,
13+
as: Component = "span",
14+
...props
15+
}: LineShadowTextProps) {
16+
const MotionComponent = motion.create(Component);
17+
const content = typeof children === "string" ? children : null;
18+
19+
if (!content) {
20+
throw new Error("LineShadowText only accepts string content");
21+
}
22+
23+
return (
24+
<MotionComponent
25+
style={{ "--shadow-color": shadowColor } as React.CSSProperties}
26+
className={cn(
27+
"relative z-0 inline-flex",
28+
"after:absolute after:left-[0.04em] after:top-[0.04em] after:content-[attr(data-text)]",
29+
"after:bg-[linear-gradient(45deg,transparent_45%,var(--shadow-color)_45%,var(--shadow-color)_55%,transparent_0)]",
30+
"after:-z-10 after:bg-[length:0.06em_0.06em] after:bg-clip-text after:text-transparent",
31+
"after:animate-line-shadow",
32+
className,
33+
)}
34+
data-text={content}
35+
{...props}
36+
>
37+
{content}
38+
</MotionComponent>
39+
);
40+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Slot } from "@radix-ui/react-slot";
2+
import { cva, VariantProps } from "class-variance-authority";
3+
import React from "react";
4+
import { cn } from "@/lib/utils";
5+
6+
const rainbowButtonVariants = cva(
7+
cn(
8+
"relative cursor-pointer group transition-all animate-rainbow",
9+
"inline-flex items-center justify-center gap-2 shrink-0",
10+
"rounded-sm outline-none focus-visible:ring-[3px] aria-invalid:border-destructive",
11+
"text-sm font-medium whitespace-nowrap",
12+
"disabled:pointer-events-none disabled:opacity-50",
13+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
14+
),
15+
{
16+
variants: {
17+
variant: {
18+
default:
19+
"border-0 bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] bg-[length:200%] text-primary-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.125rem)_solid_transparent] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:[filter:blur(0.75rem)] dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]",
20+
outline:
21+
"border border-input border-b-transparent bg-[linear-gradient(#ffffff,#ffffff),linear-gradient(#ffffff_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] bg-[length:200%] text-accent-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:[filter:blur(0.75rem)] dark:bg-[linear-gradient(#0a0a0a,#0a0a0a),linear-gradient(#0a0a0a_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]",
22+
},
23+
size: {
24+
default: "h-9 px-4 py-2",
25+
sm: "h-8 rounded-xl px-3 text-xs",
26+
lg: "h-11 rounded-xl px-8",
27+
icon: "size-9",
28+
},
29+
},
30+
defaultVariants: {
31+
variant: "default",
32+
size: "default",
33+
},
34+
},
35+
);
36+
37+
interface RainbowButtonProps
38+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39+
VariantProps<typeof rainbowButtonVariants> {
40+
asChild?: boolean;
41+
}
42+
43+
const RainbowButton = React.forwardRef<HTMLButtonElement, RainbowButtonProps>(
44+
({ className, variant, size, asChild = false, ...props }, ref) => {
45+
const Comp = asChild ? Slot : "button";
46+
return (
47+
<Comp
48+
data-slot="button"
49+
className={cn(rainbowButtonVariants({ variant, size, className }))}
50+
ref={ref}
51+
{...props}
52+
/>
53+
);
54+
},
55+
);
56+
57+
RainbowButton.displayName = "RainbowButton";
58+
59+
export { RainbowButton, rainbowButtonVariants, type RainbowButtonProps };

0 commit comments

Comments
 (0)