1
1
import React , { useState , useEffect } from 'react' ;
2
- import { useAuth } from '../hooks/useAuth' ;
3
2
import { trpc } from '../services/trpc' ;
4
3
import { AiChatDemo } from './AiChatDemo' ;
4
+ import { AiChatBackendDemo } from './AiChatBackendDemo' ;
5
5
6
- export const Dashboard : React . FC = ( ) => {
7
- const { user, logout } = useAuth ( ) ;
6
+ type DashboardProps = {
7
+ user : { userId : string } ;
8
+ onLogout : ( ) => void ;
9
+ } ;
10
+
11
+ export const Dashboard : React . FC < DashboardProps > = ( { user, onLogout } ) => {
8
12
const [ announcements , setAnnouncements ] = useState < string [ ] > ( [ ] ) ;
9
13
const [ isLoading , setIsLoading ] = useState ( true ) ;
10
- const [ activeTab , setActiveTab ] = useState < 'overview' | 'user' | 'echo' | 'ai' > ( 'overview' ) ;
14
+ const [ activeTab , setActiveTab ] = useState < 'overview' | 'user' | 'echo' | 'ai' | 'aiBackend' > ( 'overview' ) ;
11
15
const [ me , setMe ] = useState < { userId : string } | null > ( null ) ;
12
16
const [ echoInput , setEchoInput ] = useState ( 'Hello Backend' ) ;
13
17
const [ echoResult , setEchoResult ] = useState < string > ( '' ) ;
@@ -35,7 +39,14 @@ export const Dashboard: React.FC = () => {
35
39
setMeError ( null ) ;
36
40
try {
37
41
const result = await trpc . user . getMe . query ( ) ;
38
- setMe ( { userId : result . userId } ) ;
42
+ if ( ! result ) {
43
+ throw new Error ( '未登录或会话已失效' ) ;
44
+ }
45
+ const derivedUserId = ( result as any ) . userId ?? ( result as any ) . id ;
46
+ if ( ! derivedUserId ) {
47
+ throw new Error ( '后端未返回用户ID' ) ;
48
+ }
49
+ setMe ( { userId : String ( derivedUserId ) } ) ;
39
50
} catch ( err ) {
40
51
setMeError ( err instanceof Error ? err . message : '请求失败' ) ;
41
52
} finally {
@@ -47,8 +58,6 @@ export const Dashboard: React.FC = () => {
47
58
setEchoLoading ( true ) ;
48
59
setEchoResult ( '' ) ;
49
60
try {
50
- // Use a generic echo if available in backend contract, otherwise fallback to announcement text
51
- // @ts -expect-error: echo may not exist depending on backend version
52
61
const res = await ( trpc as any ) . utils ?. echo ?. query ?.( { text : echoInput } ) ;
53
62
if ( res ?. text ) {
54
63
setEchoResult ( res . text ) ;
@@ -71,8 +80,8 @@ export const Dashboard: React.FC = () => {
71
80
< h1 className = "text-xl sm:text-2xl font-bold text-gray-900" > 欢迎回来!</ h1 >
72
81
< p className = "text-sm sm:text-base text-gray-600" > 用户ID: { user ?. userId } </ p >
73
82
</ div >
74
- < button
75
- onClick = { logout }
83
+ < button
84
+ onClick = { onLogout }
76
85
className = "bg-red-600 text-white px-3 sm:px-4 py-2 rounded-lg hover:bg-red-700 focus:ring-2 focus:ring-red-500 focus:ring-offset-2 text-sm sm:text-base"
77
86
>
78
87
退出登录
@@ -84,7 +93,8 @@ export const Dashboard: React.FC = () => {
84
93
< button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'overview' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'overview' ) } > 概览</ button >
85
94
< button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'user' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'user' ) } > 用户信息</ button >
86
95
< button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'echo' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'echo' ) } > Echo 示例</ button >
87
- < button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'ai' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'ai' ) } > AI 示例</ button >
96
+ < button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'ai' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'ai' ) } > AI 直连</ button >
97
+ < button className = { `whitespace-nowrap py-2 border-b-2 font-medium text-sm ${ activeTab === 'aiBackend' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700' } ` } onClick = { ( ) => setActiveTab ( 'aiBackend' ) } > AI 后端代理</ button >
88
98
</ nav >
89
99
</ div >
90
100
@@ -142,6 +152,10 @@ export const Dashboard: React.FC = () => {
142
152
{ activeTab === 'ai' && (
143
153
< AiChatDemo />
144
154
) }
155
+
156
+ { activeTab === 'aiBackend' && (
157
+ < AiChatBackendDemo />
158
+ ) }
145
159
</ div >
146
160
147
161
< div className = "bg-white rounded-lg shadow-lg p-4 sm:p-6" >
0 commit comments