Browse Source
- usePrivacyDetailSetting:按 id 拉取隐私二级设置并切换开关 - useDndSetting:勿扰模式读取与更新 - useKeywordBlock:关键词屏蔽的读取与增删 - useAccountCancel:注销前置信息拉取与提交 - useDeleteAllData:可删除分类拉取与提交 - useLegalDocument:隐私政策 / 用户协议正文拉取 均基于 useAsyncData 封装,统一在 src/hooks/index.ts 导出master
6 changed files with 204 additions and 0 deletions
@ -0,0 +1,31 @@ |
|||
/** |
|||
* 账号注销 hook,获取前置信息并提交注销申请。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchAccountCancel, submitAccountCancel } from '../api'; |
|||
import type { AccountCancelData } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface AccountCancelState { |
|||
data: AccountCancelData | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
submit: (reason: string) => Promise<{ success: boolean; message: string }>; |
|||
} |
|||
|
|||
export function useAccountCancel(): AccountCancelState { |
|||
const fetcher = useCallback(async (): Promise<AccountCancelData> => fetchAccountCancel(), []); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
const submit = useCallback(async (reason: string) => { |
|||
try { |
|||
return await submitAccountCancel(reason); |
|||
} catch (err) { |
|||
console.error('[useAccountCancel] submit error', err); |
|||
return { success: false, message: '提交失败,请稍后重试' }; |
|||
} |
|||
}, []); |
|||
|
|||
return { data: data ?? null, loading, error, refresh, submit }; |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
/** |
|||
* 删除全部数据 hook,获取可删除分类并提交删除申请。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchDeleteAllData, submitDeleteData } from '../api'; |
|||
import type { DeleteAllData } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface DeleteAllDataState { |
|||
data: DeleteAllData | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
submit: (categoryIds: string[]) => Promise<{ success: boolean; message: string }>; |
|||
} |
|||
|
|||
export function useDeleteAllData(): DeleteAllDataState { |
|||
const fetcher = useCallback(async (): Promise<DeleteAllData> => fetchDeleteAllData(), []); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
const submit = useCallback(async (categoryIds: string[]) => { |
|||
try { |
|||
return await submitDeleteData(categoryIds); |
|||
} catch (err) { |
|||
console.error('[useDeleteAllData] submit error', err); |
|||
return { success: false, message: '提交失败,请稍后重试' }; |
|||
} |
|||
}, []); |
|||
|
|||
return { data: data ?? null, loading, error, refresh, submit }; |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* 勿扰模式设置 hook。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchDndSetting, updateDndSetting } from '../api'; |
|||
import type { DndSetting } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface DndSettingState { |
|||
setting: DndSetting | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
update: (payload: Partial<DndSetting>) => Promise<void>; |
|||
} |
|||
|
|||
export function useDndSetting(): DndSettingState { |
|||
const fetcher = useCallback(async (): Promise<DndSetting> => fetchDndSetting(), []); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
const update = useCallback( |
|||
async (payload: Partial<DndSetting>) => { |
|||
try { |
|||
await updateDndSetting(payload); |
|||
refresh(); |
|||
} catch (err) { |
|||
console.error('[useDndSetting] update error', err); |
|||
} |
|||
}, |
|||
[refresh], |
|||
); |
|||
|
|||
return { setting: data ?? null, loading, error, refresh, update }; |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
/** |
|||
* 关键词屏蔽设置 hook,支持关键词的增删。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchKeywordBlock, addBlockKeyword, removeBlockKeyword } from '../api'; |
|||
import type { KeywordBlockSetting } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface KeywordBlockState { |
|||
setting: KeywordBlockSetting | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
addKeyword: (keyword: string) => Promise<void>; |
|||
removeKeyword: (keyword: string) => Promise<void>; |
|||
} |
|||
|
|||
export function useKeywordBlock(): KeywordBlockState { |
|||
const fetcher = useCallback(async (): Promise<KeywordBlockSetting> => fetchKeywordBlock(), []); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
const addKeyword = useCallback( |
|||
async (keyword: string) => { |
|||
try { |
|||
await addBlockKeyword(keyword); |
|||
refresh(); |
|||
} catch (err) { |
|||
console.error('[useKeywordBlock] add error', err); |
|||
} |
|||
}, |
|||
[refresh], |
|||
); |
|||
|
|||
const removeKeyword = useCallback( |
|||
async (keyword: string) => { |
|||
try { |
|||
await removeBlockKeyword(keyword); |
|||
refresh(); |
|||
} catch (err) { |
|||
console.error('[useKeywordBlock] remove error', err); |
|||
} |
|||
}, |
|||
[refresh], |
|||
); |
|||
|
|||
return { setting: data ?? null, loading, error, refresh, addKeyword, removeKeyword }; |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
/** |
|||
* 法律文档(隐私政策 / 用户协议)hook,按 id 拉取正文。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchLegalDocument } from '../api'; |
|||
import type { LegalDocument } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface LegalDocumentState { |
|||
doc: LegalDocument | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
} |
|||
|
|||
export function useLegalDocument(id: string): LegalDocumentState { |
|||
const fetcher = useCallback( |
|||
async (): Promise<LegalDocument | null> => fetchLegalDocument(id), |
|||
[id], |
|||
); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
return { doc: data ?? null, loading, error, refresh }; |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* 隐私二级设置(开关类子页)hook,按页面 id 拉取并切换开关。 |
|||
*/ |
|||
import { useCallback } from 'react'; |
|||
import { fetchPrivacyDetailSetting, updatePrivacyDetailSetting } from '../api'; |
|||
import type { PrivacyDetailSetting } from '../types'; |
|||
import { useAsyncData } from './useAsyncData'; |
|||
|
|||
export interface PrivacyDetailState { |
|||
detail: PrivacyDetailSetting | null; |
|||
loading: boolean; |
|||
error: Error | null; |
|||
refresh: () => void; |
|||
toggle: (optionId: string, enabled: boolean) => Promise<void>; |
|||
} |
|||
|
|||
export function usePrivacyDetailSetting(id: string): PrivacyDetailState { |
|||
const fetcher = useCallback( |
|||
async (): Promise<PrivacyDetailSetting | null> => fetchPrivacyDetailSetting(id), |
|||
[id], |
|||
); |
|||
const { data, loading, error, refresh } = useAsyncData(fetcher); |
|||
|
|||
const toggle = useCallback( |
|||
async (optionId: string, enabled: boolean) => { |
|||
try { |
|||
await updatePrivacyDetailSetting(id, optionId, enabled); |
|||
refresh(); |
|||
} catch (err) { |
|||
console.error('[usePrivacyDetailSetting] toggle error', err); |
|||
} |
|||
}, |
|||
[id, refresh], |
|||
); |
|||
|
|||
return { detail: data ?? null, loading, error, refresh, toggle }; |
|||
} |
|||
Loading…
Reference in new issue