From fd790a9610f0e1efc3a761419f0bb01b31eed4c2 Mon Sep 17 00:00:00 2001 From: yun-zhi-ztl Date: Sat, 14 Mar 2026 17:32:37 +0800 Subject: [PATCH] feat(web): add header nav to landing page and local dev improvements - Add sticky header with LanguageSwitcher and UserMenu to landing page - Update token dialog and i18n translations - Fix dev process script and compose release config - Remove stale skillhub submodule reference --- scripts/dev_process.py | 3 +- skillhub | 1 - .../features/token/create-token-dialog.tsx | 19 +++++++++---- web/src/i18n/locales/en.json | 4 ++- web/src/i18n/locales/zh.json | 6 ++-- web/src/pages/landing.tsx | 28 ++++++++++++++++++- 6 files changed, 50 insertions(+), 11 deletions(-) delete mode 160000 skillhub diff --git a/scripts/dev_process.py b/scripts/dev_process.py index 8dd33f56..d0450410 100644 --- a/scripts/dev_process.py +++ b/scripts/dev_process.py @@ -7,6 +7,7 @@ import subprocess import sys import time from pathlib import Path +from typing import Optional def is_running(pid: int) -> bool: @@ -17,7 +18,7 @@ def is_running(pid: int) -> bool: return True -def read_pid(pid_file: Path) -> int | None: +def read_pid(pid_file: Path) -> Optional[int]: if not pid_file.exists(): return None content = pid_file.read_text(encoding="utf-8").strip() diff --git a/skillhub b/skillhub deleted file mode 160000 index a3c66108..00000000 --- a/skillhub +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a3c66108c6750a44f703e227ade992ee7715d099 diff --git a/web/src/features/token/create-token-dialog.tsx b/web/src/features/token/create-token-dialog.tsx index cb3d2abd..9d93b543 100644 --- a/web/src/features/token/create-token-dialog.tsx +++ b/web/src/features/token/create-token-dialog.tsx @@ -14,6 +14,7 @@ import { import { Button } from '@/shared/ui/button' import { Input } from '@/shared/ui/input' import { Label } from '@/shared/ui/label' +import { toast } from '@/shared/lib/toast' import type { CreateTokenRequest, CreateTokenResponse } from '@/api/types' interface CreateTokenDialogProps { @@ -48,6 +49,18 @@ export function CreateTokenDialog({ children }: CreateTokenDialogProps) { createMutation.reset() } + const handleCopyToken = async () => { + if (!createdToken) return + + try { + await navigator.clipboard.writeText(createdToken.token) + toast.success(t('createToken.copySuccess')) + } catch (error) { + console.error('Failed to copy token:', error) + toast.error(t('createToken.copyFailed')) + } + } + return ( {children} @@ -109,11 +122,7 @@ export function CreateTokenDialog({ children }: CreateTokenDialogProps) { -