96 lines
2.3 KiB
TypeScript
96 lines
2.3 KiB
TypeScript
/**
|
||
* 新用户引导页面数据获取 Hook
|
||
*
|
||
* 封装引导状态检查的 SWR 请求 + 品牌创建的 mutation,替代手动 useState + useEffect 模式。
|
||
* - 引导状态检查:mount 时自动获取
|
||
* - 品牌创建:mutation(由用户交互触发)
|
||
*/
|
||
|
||
import { useCallback } from "react";
|
||
import { useApi, useApiMutation } from "./use-api";
|
||
import type { SWRConfiguration } from "swr";
|
||
|
||
interface OnboardingStatusResponse {
|
||
completed: boolean;
|
||
}
|
||
|
||
interface CreateBrandResponse {
|
||
brand_id: string;
|
||
}
|
||
|
||
export interface CreateBrandPayload {
|
||
name: string;
|
||
competitors: string[];
|
||
platforms: string[];
|
||
frequency: "daily" | "weekly" | "monthly";
|
||
}
|
||
|
||
export interface UseOnboardingDataReturn {
|
||
/** 引导状态数据 */
|
||
onboardingStatus: OnboardingStatusResponse | undefined;
|
||
/** 是否已完成引导 */
|
||
isCompleted: boolean;
|
||
/** 是否正在加载 */
|
||
isLoading: boolean;
|
||
/** 错误信息 */
|
||
error: Error | undefined;
|
||
/** 刷新引导状态 */
|
||
refresh: () => void;
|
||
/** 创建品牌 */
|
||
createBrand: (data: CreateBrandPayload) => Promise<string | null>;
|
||
/** 是否正在创建品牌 */
|
||
isCreatingBrand: boolean;
|
||
/** 创建品牌错误 */
|
||
mutationError: Error | undefined;
|
||
}
|
||
|
||
export interface UseOnboardingDataOptions {
|
||
/** SWR 配置(用于测试时禁用重试等) */
|
||
swrOptions?: SWRConfiguration;
|
||
}
|
||
|
||
export function useOnboardingData(
|
||
options?: UseOnboardingDataOptions
|
||
): UseOnboardingDataReturn {
|
||
const swrOptions = options?.swrOptions;
|
||
|
||
// 引导状态检查
|
||
const {
|
||
data: onboardingStatus,
|
||
isLoading,
|
||
error,
|
||
refresh,
|
||
} = useApi<OnboardingStatusResponse>("/api/v1/onboarding/status", swrOptions);
|
||
|
||
const isCompleted = onboardingStatus?.completed ?? false;
|
||
|
||
// 创建品牌(mutation)
|
||
const {
|
||
trigger: createBrandTrigger,
|
||
isMutating: isCreatingBrand,
|
||
error: mutationError,
|
||
} = useApiMutation<CreateBrandResponse, CreateBrandPayload>(
|
||
"/api/v1/onboarding/brand",
|
||
"POST"
|
||
);
|
||
|
||
const createBrand = useCallback(
|
||
async (data: CreateBrandPayload): Promise<string | null> => {
|
||
const result = await createBrandTrigger(data);
|
||
return result?.brand_id ?? null;
|
||
},
|
||
[createBrandTrigger]
|
||
);
|
||
|
||
return {
|
||
onboardingStatus,
|
||
isCompleted,
|
||
isLoading,
|
||
error,
|
||
refresh,
|
||
createBrand,
|
||
isCreatingBrand,
|
||
mutationError,
|
||
};
|
||
}
|