From 21a1f272fc330f8999fc5dcdc6f121622bba3a3c Mon Sep 17 00:00:00 2001 From: imeepos Date: Thu, 19 Mar 2026 18:57:33 +0800 Subject: [PATCH] chore: remove import staging files --- __stage/apps/web-chat/next-env.d.ts | 6 - __stage/apps/web-chat/next.config.js | 4 - __stage/apps/web-chat/package.json | 29 -- __stage/apps/web-chat/postcss.config.js | 5 - .../web-chat/src/app/avatars/[id]/page.tsx | 116 ------ .../apps/web-chat/src/app/avatars/page.tsx | 67 ---- __stage/apps/web-chat/src/app/chat/page.tsx | 119 ------ __stage/apps/web-chat/src/app/globals.css | 1 - __stage/apps/web-chat/src/app/layout.tsx | 25 -- .../apps/web-chat/src/app/lobsters/page.tsx | 309 ---------------- __stage/apps/web-chat/src/app/login/page.tsx | 157 -------- __stage/apps/web-chat/src/app/page.tsx | 28 -- .../web-chat/src/components/AvatarForm.tsx | 116 ------ .../web-chat/src/components/AvatarManager.tsx | 121 ------- .../src/components/AvatarSelector.tsx | 130 ------- .../src/components/BulkEmojiUpload.tsx | 128 ------- .../web-chat/src/components/ChatContainer.tsx | 298 --------------- .../web-chat/src/components/ChatInput.tsx | 82 ----- .../web-chat/src/components/ChatToolbar.tsx | 116 ------ .../src/components/ConnectionStatus.tsx | 22 -- .../web-chat/src/components/EmojiForm.tsx | 259 ------------- .../web-chat/src/components/EmojiList.tsx | 111 ------ .../web-chat/src/components/EmojiMedia.tsx | 55 --- .../web-chat/src/components/EmojiPicker.tsx | 108 ------ .../src/components/FloatingAvatar.tsx | 300 --------------- .../src/components/LobsterSidebar.tsx | 98 ----- .../web-chat/src/components/MessageBubble.tsx | 37 -- .../web-chat/src/components/MessageList.tsx | 123 ------- .../src/components/SystemStatusPanel.tsx | 72 ---- .../web-chat/src/hooks/useApiKeyAvatar.ts | 69 ---- __stage/apps/web-chat/src/hooks/useAuth.ts | 97 ----- __stage/apps/web-chat/src/hooks/useAvatars.ts | 124 ------- __stage/apps/web-chat/src/hooks/useChat.ts | 75 ---- __stage/apps/web-chat/src/hooks/useEmojis.ts | 123 ------- .../apps/web-chat/src/hooks/useLobsters.ts | 172 --------- __stage/apps/web-chat/src/hooks/useRelay.tsx | 341 ------------------ __stage/apps/web-chat/src/lib/avatarEmoji.ts | 40 -- __stage/apps/web-chat/src/lib/chatSessions.ts | 80 ---- __stage/apps/web-chat/src/lib/chatStorage.ts | 82 ----- __stage/apps/web-chat/src/lib/protocol.ts | 230 ------------ __stage/apps/web-chat/tsconfig.json | 24 -- 41 files changed, 4499 deletions(-) delete mode 100644 __stage/apps/web-chat/next-env.d.ts delete mode 100644 __stage/apps/web-chat/next.config.js delete mode 100644 __stage/apps/web-chat/package.json delete mode 100644 __stage/apps/web-chat/postcss.config.js delete mode 100644 __stage/apps/web-chat/src/app/avatars/[id]/page.tsx delete mode 100644 __stage/apps/web-chat/src/app/avatars/page.tsx delete mode 100644 __stage/apps/web-chat/src/app/chat/page.tsx delete mode 100644 __stage/apps/web-chat/src/app/globals.css delete mode 100644 __stage/apps/web-chat/src/app/layout.tsx delete mode 100644 __stage/apps/web-chat/src/app/lobsters/page.tsx delete mode 100644 __stage/apps/web-chat/src/app/login/page.tsx delete mode 100644 __stage/apps/web-chat/src/app/page.tsx delete mode 100644 __stage/apps/web-chat/src/components/AvatarForm.tsx delete mode 100644 __stage/apps/web-chat/src/components/AvatarManager.tsx delete mode 100644 __stage/apps/web-chat/src/components/AvatarSelector.tsx delete mode 100644 __stage/apps/web-chat/src/components/BulkEmojiUpload.tsx delete mode 100644 __stage/apps/web-chat/src/components/ChatContainer.tsx delete mode 100644 __stage/apps/web-chat/src/components/ChatInput.tsx delete mode 100644 __stage/apps/web-chat/src/components/ChatToolbar.tsx delete mode 100644 __stage/apps/web-chat/src/components/ConnectionStatus.tsx delete mode 100644 __stage/apps/web-chat/src/components/EmojiForm.tsx delete mode 100644 __stage/apps/web-chat/src/components/EmojiList.tsx delete mode 100644 __stage/apps/web-chat/src/components/EmojiMedia.tsx delete mode 100644 __stage/apps/web-chat/src/components/EmojiPicker.tsx delete mode 100644 __stage/apps/web-chat/src/components/FloatingAvatar.tsx delete mode 100644 __stage/apps/web-chat/src/components/LobsterSidebar.tsx delete mode 100644 __stage/apps/web-chat/src/components/MessageBubble.tsx delete mode 100644 __stage/apps/web-chat/src/components/MessageList.tsx delete mode 100644 __stage/apps/web-chat/src/components/SystemStatusPanel.tsx delete mode 100644 __stage/apps/web-chat/src/hooks/useApiKeyAvatar.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useAuth.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useAvatars.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useChat.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useEmojis.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useLobsters.ts delete mode 100644 __stage/apps/web-chat/src/hooks/useRelay.tsx delete mode 100644 __stage/apps/web-chat/src/lib/avatarEmoji.ts delete mode 100644 __stage/apps/web-chat/src/lib/chatSessions.ts delete mode 100644 __stage/apps/web-chat/src/lib/chatStorage.ts delete mode 100644 __stage/apps/web-chat/src/lib/protocol.ts delete mode 100644 __stage/apps/web-chat/tsconfig.json diff --git a/__stage/apps/web-chat/next-env.d.ts b/__stage/apps/web-chat/next-env.d.ts deleted file mode 100644 index 830fb59..0000000 --- a/__stage/apps/web-chat/next-env.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/__stage/apps/web-chat/next.config.js b/__stage/apps/web-chat/next.config.js deleted file mode 100644 index 1d61478..0000000 --- a/__stage/apps/web-chat/next.config.js +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = {} - -export default nextConfig diff --git a/__stage/apps/web-chat/package.json b/__stage/apps/web-chat/package.json deleted file mode 100644 index 20791d8..0000000 --- a/__stage/apps/web-chat/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@sker-pro/web-chat", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "next dev --hostname 0.0.0.0 --port=3001", - "build": "next build", - "start": "next start", - "typecheck": "tsc --noEmit" - }, - "dependencies": { - "@opennextjs/cloudflare": "^1.0.0", - "@bowong/auth": "git+https://gitea.bowongai.com/bowong/claushow-auth.git#main", - "better-auth": "^1.2.0", - "next": "^15.3.3", - "react": "^19.2.0", - "react-dom": "^19.2.0" - }, - "devDependencies": { - "@cloudflare/workers-types": "^4.20250312.0", - "@tailwindcss/postcss": "^4.1.13", - "@types/react": "^19.2.2", - "@types/react-dom": "^19.2.2", - "postcss": "^8.5.6", - "tailwindcss": "^4.1.13", - "typescript": "^5.9.3" - } -} diff --git a/__stage/apps/web-chat/postcss.config.js b/__stage/apps/web-chat/postcss.config.js deleted file mode 100644 index a7f73a2..0000000 --- a/__stage/apps/web-chat/postcss.config.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - plugins: { - '@tailwindcss/postcss': {}, - }, -} diff --git a/__stage/apps/web-chat/src/app/avatars/[id]/page.tsx b/__stage/apps/web-chat/src/app/avatars/[id]/page.tsx deleted file mode 100644 index 7721930..0000000 --- a/__stage/apps/web-chat/src/app/avatars/[id]/page.tsx +++ /dev/null @@ -1,116 +0,0 @@ -'use client' - -import { useEffect, useState } from 'react' -import { useRouter, useParams } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' -import { useAvatars, type AvatarWithEmojis } from '@/hooks/useAvatars' -import { BulkEmojiUpload } from '@/components/BulkEmojiUpload' -import { EmojiList } from '@/components/EmojiList' -import { EmojiForm } from '@/components/EmojiForm' - -export default function AvatarDetailPage() { - const router = useRouter() - const params = useParams() - const avatarId = params?.id as string - const { user, loading: authLoading } = useAuth() - const { fetchAvatar } = useAvatars() - const [avatar, setAvatar] = useState(null) - const [loading, setLoading] = useState(true) - const [showAddForm, setShowAddForm] = useState(false) - - useEffect(() => { - if (!authLoading && !user) { - router.replace('/login') - } - }, [user, authLoading, router]) - - useEffect(() => { - if (user && avatarId) { - loadAvatar() - } - }, [user, avatarId]) - - const loadAvatar = async () => { - try { - setLoading(true) - const data = await fetchAvatar(avatarId) - setAvatar(data) - } catch (err) { - console.error('Failed to load avatar:', err) - alert('加载失败') - router.replace('/avatars') - } finally { - setLoading(false) - } - } - - const handleAddSuccess = () => { - setShowAddForm(false) - loadAvatar() - } - - if (authLoading || !user || loading) { - return ( -
-
Loading...
-
- ) - } - - if (!avatar) { - return null - } - - return ( -
-
-
- -

{avatar.name}

- {avatar.description && ( -

{avatar.description}

- )} -
- -
-
- -
-
- - {showAddForm && ( -
-

- 添加新表情 -

- setShowAddForm(false)} - /> -
- )} - -
- -
- - -
-
- ) -} diff --git a/__stage/apps/web-chat/src/app/avatars/page.tsx b/__stage/apps/web-chat/src/app/avatars/page.tsx deleted file mode 100644 index a118bdd..0000000 --- a/__stage/apps/web-chat/src/app/avatars/page.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client' - -import { useEffect, useState } from 'react' -import { useRouter } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' -import { useAvatars, type Avatar } from '@/hooks/useAvatars' -import { AvatarManager } from '@/components/AvatarManager' - -export default function AvatarsPage() { - const router = useRouter() - const { user, loading: authLoading } = useAuth() - const { fetchAvatars } = useAvatars() - const [avatars, setAvatars] = useState([]) - const [loading, setLoading] = useState(true) - - useEffect(() => { - if (!authLoading && !user) { - router.replace('/login') - } - }, [user, authLoading, router]) - - useEffect(() => { - if (user) { - loadAvatars() - } - }, [user]) - - const loadAvatars = async () => { - try { - setLoading(true) - const data = await fetchAvatars() - setAvatars(Array.isArray(data) ? data : []) - } catch (err) { - console.error('Failed to load avatars:', err) - setAvatars([]) - } finally { - setLoading(false) - } - } - - if (authLoading || !user) { - return ( -
-
Loading...
-
- ) - } - - return ( -
-
-
-

形象管理

-

- 管理你的龙虾形象和表情包 -

-
- - -
-
- ) -} diff --git a/__stage/apps/web-chat/src/app/chat/page.tsx b/__stage/apps/web-chat/src/app/chat/page.tsx deleted file mode 100644 index c49d692..0000000 --- a/__stage/apps/web-chat/src/app/chat/page.tsx +++ /dev/null @@ -1,119 +0,0 @@ -'use client' - -import { Suspense, useCallback, useEffect, useState } from 'react' -import { useRouter, useSearchParams } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' -import { useLobsters, type LobsterWithStatus } from '@/hooks/useLobsters' -import { LobsterSidebar } from '@/components/LobsterSidebar' -import { ChatContainer } from '@/components/ChatContainer' -import { FloatingAvatar } from '@/components/FloatingAvatar' - -export default function ChatPage() { - return ( - -

Loading...

- - } - > - -
- ) -} - -function ChatPageInner() { - const router = useRouter() - const searchParams = useSearchParams() - const { user, loading: authLoading, token } = useAuth() - const { lobstersWithStatus, fetchApiKeys } = useLobsters() - - const [activeLobster, setActiveLobster] = useState(null) - const [sidebarCollapsed, setSidebarCollapsed] = useState(true) - - // Auth guard - useEffect(() => { - if (authLoading) return - if (!user || !token) { - router.replace('/login') - } - }, [user, token, authLoading, router]) - - // Fetch lobster list on mount - useEffect(() => { - if (user) void fetchApiKeys() - }, [user, fetchApiKeys]) - - // Restore selection from URL query param - useEffect(() => { - const lobsterIdFromUrl = searchParams.get('lobsterId') - if (lobsterIdFromUrl && !activeLobster && lobstersWithStatus.length > 0) { - const found = lobstersWithStatus.find((l) => l.id === lobsterIdFromUrl) - if (found) setActiveLobster(found) - } - }, [searchParams, lobstersWithStatus, activeLobster]) - - // Keep activeLobster in sync with fresh status data - useEffect(() => { - if (activeLobster) { - const fresh = lobstersWithStatus.find((l) => l.id === activeLobster.id) - if (fresh && fresh.isOnline !== activeLobster.isOnline) { - setActiveLobster(fresh) - } - } - }, [lobstersWithStatus, activeLobster]) - - const handleSelect = useCallback( - (lobster: LobsterWithStatus) => { - setActiveLobster(lobster) - setSidebarCollapsed(true) - // Update URL without navigation - const url = new URL(window.location.href) - url.searchParams.set('lobsterId', lobster.id) - window.history.replaceState(null, '', url.toString()) - }, - [], - ) - - if (authLoading || !user || !token) { - return ( -
-

Loading...

-
- ) - } - - return ( -
- setSidebarCollapsed((c) => !c)} - /> - -
- {activeLobster ? ( - - ) : ( -
-
-

- Select a lobster to start chatting -

-
-
- )} -
- - -
- ) -} diff --git a/__stage/apps/web-chat/src/app/globals.css b/__stage/apps/web-chat/src/app/globals.css deleted file mode 100644 index d4b5078..0000000 --- a/__stage/apps/web-chat/src/app/globals.css +++ /dev/null @@ -1 +0,0 @@ -@import 'tailwindcss'; diff --git a/__stage/apps/web-chat/src/app/layout.tsx b/__stage/apps/web-chat/src/app/layout.tsx deleted file mode 100644 index 93d81ab..0000000 --- a/__stage/apps/web-chat/src/app/layout.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { Metadata } from 'next' -import { AuthProvider } from '@/hooks/useAuth' -import { RelayProvider } from '@/hooks/useRelay' -import './globals.css' - -export const metadata: Metadata = { - title: 'Web Chat', - description: 'Chat with AI via WebSocket relay', -} - -export default function RootLayout({ - children, -}: { - children: React.ReactNode -}) { - return ( - - - - {children} - - - - ) -} diff --git a/__stage/apps/web-chat/src/app/lobsters/page.tsx b/__stage/apps/web-chat/src/app/lobsters/page.tsx deleted file mode 100644 index cc34a77..0000000 --- a/__stage/apps/web-chat/src/app/lobsters/page.tsx +++ /dev/null @@ -1,309 +0,0 @@ -'use client' - -import { useEffect, useState } from 'react' -import Link from 'next/link' -import { useRouter } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' -import { useLobsters } from '@/hooks/useLobsters' -import { useApiKeyAvatar, type ApiKeyAvatar } from '@/hooks/useApiKeyAvatar' -import { AvatarSelector } from '@/components/AvatarSelector' -import { EmojiMedia } from '@/components/EmojiMedia' - -export default function LobstersPage() { - const router = useRouter() - const { user, loading: authLoading, signOut } = useAuth() - const { getBoundAvatar } = useApiKeyAvatar() - const { - apiKeys, - onlineLobsters, - loading, - error, - fetchApiKeys, - createApiKey, - deleteApiKey, - } = useLobsters() - - const [newName, setNewName] = useState('') - const [createdKey, setCreatedKey] = useState(null) - const [copied, setCopied] = useState(false) - const [creating, setCreating] = useState(false) - const [deletingId, setDeletingId] = useState(null) - const [bindingKeyId, setBindingKeyId] = useState(null) - const [bindings, setBindings] = useState>({}) - const [bindingLoadingId, setBindingLoadingId] = useState(null) - const [bindingError, setBindingError] = useState(null) - - useEffect(() => { - if (authLoading) return - if (!user) { - router.replace('/login') - return - } - void fetchApiKeys() - }, [user, authLoading, router, fetchApiKeys]) - - useEffect(() => { - if (apiKeys.length === 0) { - setBindings({}) - return - } - - let cancelled = false - void (async () => { - const entries = await Promise.all( - apiKeys.map(async key => { - try { - return [key.id, await getBoundAvatar(key.id)] as const - } catch { - return [key.id, null] as const - } - }), - ) - - if (!cancelled) { - setBindings(Object.fromEntries(entries)) - } - })() - - return () => { - cancelled = true - } - }, [apiKeys, getBoundAvatar]) - - const handleCreate = async (e: React.FormEvent) => { - e.preventDefault() - if (!newName.trim()) return - setCreating(true) - setCreatedKey(null) - setCopied(false) - const key = await createApiKey(newName.trim()) - if (key) { - setCreatedKey(key) - setNewName('') - } - setCreating(false) - } - - const handleDelete = async (keyId: string) => { - if (!confirm('Are you sure you want to delete this lobster?')) return - setDeletingId(keyId) - await deleteApiKey(keyId) - setDeletingId(null) - } - - const handleOpenBinding = async (keyId: string) => { - setBindingError(null) - setBindingKeyId(current => (current === keyId ? null : keyId)) - - if (bindings[keyId] || bindingKeyId === keyId) { - return - } - - try { - setBindingLoadingId(keyId) - const data = await getBoundAvatar(keyId) - setBindings(current => ({ ...current, [keyId]: data })) - } catch (err) { - setBindingError(err instanceof Error ? err.message : '加载形象绑定失败') - } finally { - setBindingLoadingId(null) - } - } - - const handleBindingChanged = async (keyId: string) => { - try { - setBindingLoadingId(keyId) - const data = await getBoundAvatar(keyId) - setBindings(current => ({ ...current, [keyId]: data })) - setBindingKeyId(null) - } catch (err) { - setBindingError(err instanceof Error ? err.message : '刷新形象绑定失败') - } finally { - setBindingLoadingId(null) - } - } - - const isOnline = (keyId: string) => - onlineLobsters.some(l => l.lobsterId === keyId) - - if (authLoading || !user) { - return ( -
-

Loading...

-
- ) - } - - return ( -
- {/* Header */} -
-
-

My Lobsters

-

- Create and manage your lobster API keys -

-
-
- - Back to Chat - - - 形象管理 - - -
-
- - {/* Create lobster */} -
void handleCreate(e)} - className="mb-6 flex gap-3" - > - setNewName(e.target.value)} - placeholder="Lobster name" - className="flex-1 rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder-slate-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" - /> - -
- - {/* Newly created key + setup instructions */} - {createdKey && ( -
-

- 复制下面的文本,发送给 OpenClaw 即可完成安装 -

-
-
-              {`按照https://cdn.bowong.cc/static/ClawShowInstall/SKILL.md 的指示,安装ClawShow Gateway Connect插件。
-使用authToken = "${createdKey}", 安装@bowong/clawshow-gateway@latest`}
-            
- -
-
- )} - - {error &&

{error}

} - {bindingError &&

{bindingError}

} - - {/* Lobster list */} - {loading && apiKeys.length === 0 ? ( -

Loading lobsters...

- ) : apiKeys.length === 0 ? ( -
-

- No lobsters yet. Create one above to get started. -

-
- ) : ( -
- {apiKeys.map(key => { - const online = isOnline(key.id) - return ( -
-
-
- -
-

- {key.name ?? 'Unnamed'} -

- {key.prefix && ( -

{key.prefix}...

- )} -

- 当前形象: - {bindingLoadingId === key.id && !bindings[key.id] - ? '加载中...' - : bindings[key.id]?.avatar?.name ?? '未绑定'} -

-
-
-
- - -
-
- {bindingKeyId === key.id && ( -
- setBindingKeyId(null)} - onBound={() => void handleBindingChanged(key.id)} - /> -
- )} - {bindings[key.id]?.emojis && bindings[key.id]!.emojis.length > 0 && ( -
- {bindings[key.id]!.emojis.slice(0, 6).map(emoji => ( - - ))} - {bindings[key.id]!.emojis.length > 6 && ( -
- +{bindings[key.id]!.emojis.length - 6} -
- )} -
- )} -
- ) - })} -
- )} -
- ) -} diff --git a/__stage/apps/web-chat/src/app/login/page.tsx b/__stage/apps/web-chat/src/app/login/page.tsx deleted file mode 100644 index a7951e0..0000000 --- a/__stage/apps/web-chat/src/app/login/page.tsx +++ /dev/null @@ -1,157 +0,0 @@ -'use client' - -import { useState } from 'react' -import { useRouter } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' - -export default function LoginPage() { - const router = useRouter() - const { authClient, refreshSession } = useAuth() - const [isSignUp, setIsSignUp] = useState(false) - const [email, setEmail] = useState('') - const [password, setPassword] = useState('') - const [name, setName] = useState('') - const [error, setError] = useState('') - const [loading, setLoading] = useState(false) - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault() - setError('') - setLoading(true) - - try { - if (isSignUp) { - const { error: signUpError } = await authClient.signUp.email({ - email, - password, - name: name || email.split('@')[0], - }) - if (signUpError) { - setError(signUpError.message ?? 'Sign up failed') - setLoading(false) - return - } - } else { - const { error: signInError } = await authClient.signIn.email({ - email, - password, - }) - if (signInError) { - setError(signInError.message ?? 'Sign in failed') - setLoading(false) - return - } - } - - await refreshSession() - router.replace('/') - } catch (err) { - setError(err instanceof Error ? err.message : String(err)) - setLoading(false) - } - } - - return ( -
-
-
-

- {isSignUp ? 'Create Account' : 'Sign In'} -

-

- {isSignUp - ? 'Create an account to start chatting' - : 'Sign in to continue'} -

-
- -
void handleSubmit(e)} className="space-y-4"> - {isSignUp && ( -
- - setName(e.target.value)} - className="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder-slate-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" - placeholder="Your name" - /> -
- )} - -
- - setEmail(e.target.value)} - className="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder-slate-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" - placeholder="you@example.com" - /> -
- -
- - setPassword(e.target.value)} - className="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder-slate-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" - placeholder="At least 8 characters" - /> -
- - {error &&

{error}

} - - -
- -
- -
-
-
- ) -} diff --git a/__stage/apps/web-chat/src/app/page.tsx b/__stage/apps/web-chat/src/app/page.tsx deleted file mode 100644 index b5f248b..0000000 --- a/__stage/apps/web-chat/src/app/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -'use client' - -import { useEffect } from 'react' -import { useRouter } from 'next/navigation' -import { useAuth } from '@/hooks/useAuth' - -export default function HomePage() { - const router = useRouter() - const { user, loading } = useAuth() - - useEffect(() => { - if (loading) return - - if (!user) { - router.replace('/login') - return - } - - // Logged in — go to chat - router.replace('/chat') - }, [user, loading, router]) - - return ( -
-

Loading...

-
- ) -} diff --git a/__stage/apps/web-chat/src/components/AvatarForm.tsx b/__stage/apps/web-chat/src/components/AvatarForm.tsx deleted file mode 100644 index a9e6716..0000000 --- a/__stage/apps/web-chat/src/components/AvatarForm.tsx +++ /dev/null @@ -1,116 +0,0 @@ -'use client' - -import { useState } from 'react' -import { useAvatars } from '@/hooks/useAvatars' - -interface AvatarFormProps { - onSuccess: () => void - onCancel: () => void - initialName?: string - initialDescription?: string - avatarId?: string -} - -export function AvatarForm({ - onSuccess, - onCancel, - initialName = '', - initialDescription = '', - avatarId, -}: AvatarFormProps) { - const { createAvatar, updateAvatar } = useAvatars() - const [name, setName] = useState(initialName) - const [description, setDescription] = useState(initialDescription) - const [submitting, setSubmitting] = useState(false) - const [error, setError] = useState(null) - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault() - - if (!name.trim()) { - setError('请输入形象名称') - return - } - - try { - setSubmitting(true) - setError(null) - - if (avatarId) { - await updateAvatar(avatarId, name.trim(), description.trim() || undefined) - } else { - await createAvatar(name.trim(), description.trim() || undefined) - } - - onSuccess() - } catch (err) { - setError(err instanceof Error ? err.message : '操作失败') - } finally { - setSubmitting(false) - } - } - - return ( -
- {error && ( -
- {error} -
- )} - -
- - setName(e.target.value)} - placeholder="例如:可爱小龙虾" - className="mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" - disabled={submitting} - /> -
- -
- -