166 lines
4.4 KiB
TypeScript
166 lines
4.4 KiB
TypeScript
// 學習會話服務
|
|
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5008';
|
|
|
|
// 類型定義
|
|
export interface StudySession {
|
|
sessionId: string;
|
|
totalCards: number;
|
|
totalTests: number;
|
|
currentCardIndex: number;
|
|
currentTestType?: string;
|
|
startedAt: string;
|
|
}
|
|
|
|
export interface CurrentTest {
|
|
sessionId: string;
|
|
testType: string;
|
|
card: Card;
|
|
progress: ProgressSummary;
|
|
}
|
|
|
|
export interface Card {
|
|
id: string;
|
|
word: string;
|
|
translation: string;
|
|
definition: string;
|
|
example: string;
|
|
exampleTranslation: string;
|
|
pronunciation: string;
|
|
difficultyLevel: string;
|
|
}
|
|
|
|
export interface ProgressSummary {
|
|
currentCardIndex: number;
|
|
totalCards: number;
|
|
completedTests: number;
|
|
totalTests: number;
|
|
completedCards: number;
|
|
}
|
|
|
|
export interface TestResult {
|
|
testType: string;
|
|
isCorrect: boolean;
|
|
userAnswer?: string;
|
|
confidenceLevel?: number;
|
|
responseTimeMs: number;
|
|
}
|
|
|
|
export interface SubmitTestResponse {
|
|
success: boolean;
|
|
isCardCompleted: boolean;
|
|
progress: ProgressSummary;
|
|
message: string;
|
|
}
|
|
|
|
export interface NextTest {
|
|
hasNextTest: boolean;
|
|
testType?: string;
|
|
sameCard: boolean;
|
|
message: string;
|
|
}
|
|
|
|
export interface Progress {
|
|
sessionId: string;
|
|
status: string;
|
|
currentCardIndex: number;
|
|
totalCards: number;
|
|
completedTests: number;
|
|
totalTests: number;
|
|
completedCards: number;
|
|
cards: CardProgress[];
|
|
}
|
|
|
|
export interface CardProgress {
|
|
cardId: string;
|
|
word: string;
|
|
plannedTests: string[];
|
|
completedTestsCount: number;
|
|
isCompleted: boolean;
|
|
tests: TestProgress[];
|
|
}
|
|
|
|
export interface TestProgress {
|
|
testType: string;
|
|
isCorrect: boolean;
|
|
completedAt: string;
|
|
}
|
|
|
|
export class StudySessionService {
|
|
private async makeRequest<T>(endpoint: string, options: RequestInit = {}): Promise<{ success: boolean; data: T | null; error?: string }> {
|
|
try {
|
|
const token = localStorage.getItem('auth_token');
|
|
|
|
const response = await fetch(`${API_BASE}${endpoint}`, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': token ? `Bearer ${token}` : '',
|
|
...options.headers,
|
|
},
|
|
...options,
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json().catch(() => ({ error: 'Network error' }));
|
|
return { success: false, data: null, error: errorData.error || `HTTP ${response.status}` };
|
|
}
|
|
|
|
const result = await response.json();
|
|
return { success: result.Success || false, data: result.Data || null, error: result.Error };
|
|
} catch (error) {
|
|
console.error('API request failed:', error);
|
|
return { success: false, data: null, error: 'Network error' };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 開始新的學習會話
|
|
*/
|
|
async startSession(): Promise<{ success: boolean; data: StudySession | null; error?: string }> {
|
|
return await this.makeRequest<StudySession>('/api/study/sessions/start', {
|
|
method: 'POST'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 獲取當前測驗
|
|
*/
|
|
async getCurrentTest(sessionId: string): Promise<{ success: boolean; data: CurrentTest | null; error?: string }> {
|
|
return await this.makeRequest<CurrentTest>(`/api/study/sessions/${sessionId}/current-test`);
|
|
}
|
|
|
|
/**
|
|
* 提交測驗結果
|
|
*/
|
|
async submitTest(sessionId: string, result: TestResult): Promise<{ success: boolean; data: SubmitTestResponse | null; error?: string }> {
|
|
return await this.makeRequest<SubmitTestResponse>(`/api/study/sessions/${sessionId}/submit-test`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(result)
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 獲取下一個測驗
|
|
*/
|
|
async getNextTest(sessionId: string): Promise<{ success: boolean; data: NextTest | null; error?: string }> {
|
|
return await this.makeRequest<NextTest>(`/api/study/sessions/${sessionId}/next-test`);
|
|
}
|
|
|
|
/**
|
|
* 獲取詳細進度
|
|
*/
|
|
async getProgress(sessionId: string): Promise<{ success: boolean; data: Progress | null; error?: string }> {
|
|
return await this.makeRequest<Progress>(`/api/study/sessions/${sessionId}/progress`);
|
|
}
|
|
|
|
/**
|
|
* 完成學習會話
|
|
*/
|
|
async completeSession(sessionId: string): Promise<{ success: boolean; data: any | null; error?: string }> {
|
|
return await this.makeRequest(`/api/study/sessions/${sessionId}/complete`, {
|
|
method: 'PUT'
|
|
});
|
|
}
|
|
}
|
|
|
|
// 導出服務實例
|
|
export const studySessionService = new StudySessionService(); |