dramaling-vocab-learning/frontend/lib/services/studySession.ts

167 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 學習會話服務
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',
// 開發階段不發送無效的token讓後端使用測試用戶
// '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();