轻松聘
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

64 lines
2.0 KiB

/**
* AI 模拟面试 hook:拉取面试配置 + 开始面试。
*/
import { useCallback, useState } from 'react';
import { fetchAIInterviewData, startInterview } from '../api';
import type { AIInterviewData, InterviewMode, InterviewQuestionTypeCode, InterviewSession } from '../types';
import { useAsyncData } from './useAsyncData';
export function useAIInterview() {
const fetcher = useCallback(() => fetchAIInterviewData(), []);
const { data, loading, error, refresh } = useAsyncData<AIInterviewData>(fetcher);
/** 本地交互状态:模式 / 题型 / 专项 */
const [mode, setMode] = useState<InterviewMode | null>(null);
const [questionTypes, setQuestionTypes] = useState<InterviewQuestionTypeCode[]>([]);
const [specials, setSpecials] = useState<string[]>([]);
const [starting, setStarting] = useState(false);
const resolvedMode = mode ?? data?.mode ?? 'full';
const resolvedTypes = questionTypes.length
? questionTypes
: (data?.questionTypes.filter((t) => t.selected).map((t) => t.id) ?? []);
const resolvedSpecials = specials.length
? specials
: (data?.specials.filter((s) => s.selected).map((s) => s.id) ?? []);
const toggleQuestionType = useCallback((id: InterviewQuestionTypeCode) => {
setQuestionTypes((prev) => {
const base =
prev.length > 0
? prev
: ([] as InterviewQuestionTypeCode[]);
return base.includes(id) ? base.filter((t) => t !== id) : [...base, id];
});
}, []);
const toggleSpecial = useCallback((id: string) => {
setSpecials((prev) => (prev.includes(id) ? prev.filter((s) => s !== id) : [...prev, id]));
}, []);
const start = useCallback(async (): Promise<InterviewSession> => {
setStarting(true);
try {
return await startInterview();
} finally {
setStarting(false);
}
}, []);
return {
data: data ?? null,
loading,
error,
refresh,
mode: resolvedMode,
setMode,
questionTypes: resolvedTypes,
toggleQuestionType,
specials: resolvedSpecials,
toggleSpecial,
start,
starting,
};
}