feat: 添加训练计划和打卡功能
- 新增训练计划页面,允许用户制定个性化的训练计划 - 集成打卡功能,用户可以记录每日的训练情况 - 更新 Redux 状态管理,添加训练计划相关的 reducer - 在首页中添加训练计划卡片,支持用户点击跳转 - 更新样式和布局,以适应新功能的展示和交互 - 添加日期选择器和相关依赖,支持用户选择训练日期
This commit is contained in:
63
hooks/useAuthGuard.ts
Normal file
63
hooks/useAuthGuard.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { usePathname, useRouter } from 'expo-router';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useAppSelector } from '@/hooks/redux';
|
||||
|
||||
type RedirectParams = Record<string, string | number | boolean | undefined>;
|
||||
|
||||
type EnsureOptions = {
|
||||
redirectTo?: string;
|
||||
redirectParams?: RedirectParams;
|
||||
};
|
||||
|
||||
export function useAuthGuard() {
|
||||
const router = useRouter();
|
||||
const currentPath = usePathname();
|
||||
const token = useAppSelector((s) => (s as any)?.user?.token as string | null);
|
||||
const isLoggedIn = !!token;
|
||||
|
||||
const ensureLoggedIn = useCallback(async (options?: EnsureOptions): Promise<boolean> => {
|
||||
if (isLoggedIn) return true;
|
||||
|
||||
const redirectTo = options?.redirectTo ?? currentPath ?? '/(tabs)';
|
||||
const paramsJson = options?.redirectParams ? JSON.stringify(options.redirectParams) : undefined;
|
||||
|
||||
router.push({
|
||||
pathname: '/auth/login',
|
||||
params: {
|
||||
redirectTo,
|
||||
...(paramsJson ? { redirectParams: paramsJson } : {}),
|
||||
},
|
||||
} as any);
|
||||
return false;
|
||||
}, [isLoggedIn, router, currentPath]);
|
||||
|
||||
const pushIfAuthedElseLogin = useCallback((pathname: string, params?: RedirectParams) => {
|
||||
if (isLoggedIn) {
|
||||
router.push({ pathname, params } as any);
|
||||
return;
|
||||
}
|
||||
const paramsJson = params ? JSON.stringify(params) : undefined;
|
||||
router.push({ pathname: '/auth/login', params: { redirectTo: pathname, ...(paramsJson ? { redirectParams: paramsJson } : {}) } } as any);
|
||||
}, [isLoggedIn, router]);
|
||||
|
||||
const guardHandler = useCallback(
|
||||
<T extends any[]>(fn: (...args: T) => any | Promise<any>, options?: EnsureOptions) => {
|
||||
return async (...args: T) => {
|
||||
const ok = await ensureLoggedIn(options);
|
||||
if (!ok) return;
|
||||
return fn(...args);
|
||||
};
|
||||
},
|
||||
[ensureLoggedIn]
|
||||
);
|
||||
|
||||
return {
|
||||
isLoggedIn,
|
||||
ensureLoggedIn,
|
||||
pushIfAuthedElseLogin,
|
||||
guardHandler,
|
||||
} as const;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user