This commit is contained in:
ryan
2026-07-13 15:17:45 +08:00
parent 08e61ce833
commit e0eb4e5975
334 changed files with 17212 additions and 12321 deletions
+16 -16
View File
@@ -1,27 +1,27 @@
"use client"
'use client';
import {useEffect} from "react"
import {usePathname, useRouter} from "next/navigation"
import { useEffect } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import {useUser} from "@/contexts/user-context"
import { useUser } from '@/contexts/user-context';
/** Redirects unauthenticated users to login while allowing the shell to render first. */
export function useAuthRedirect() {
const router = useRouter()
const pathname = usePathname()
const {user, loading} = useUser()
const router = useRouter();
const pathname = usePathname();
const { user, loading } = useUser();
useEffect(() => {
if (loading || user) {
return
return;
}
const queryString = window.location.search
const callbackUrl = queryString ? `${pathname}${queryString}` : pathname
const loginUrl = new URL("/login", window.location.origin)
const queryString = window.location.search;
const callbackUrl = queryString ? `${pathname}${queryString}` : pathname;
const loginUrl = new URL('/login', window.location.origin);
loginUrl.searchParams.set("callbackUrl", callbackUrl)
sessionStorage.setItem("redirect_after_login", callbackUrl)
router.replace(loginUrl.toString())
}, [loading, pathname, router, user])
}
loginUrl.searchParams.set('callbackUrl', callbackUrl);
sessionStorage.setItem('redirect_after_login', callbackUrl);
router.replace(loginUrl.toString());
}, [loading, pathname, router, user]);
}
+1 -1
View File
@@ -8,7 +8,7 @@ interface CommonControlledStateProps<T> {
/**
* 受控状态 Hook
* 用于处理受控和非受控组件的状态管理
*
*
* @example
* ```tsx
* const [value, setValue] = useControlledState({ value: propValue, onChange: console.log })
+1 -1
View File
@@ -9,7 +9,7 @@ interface UseIsInViewOptions {
/**
* 检测元素是否在视图中
*
*
* @example
* ```tsx
* const { ref, isInView } = useIsInView({ inViewOnce: true })
+13 -11
View File
@@ -1,19 +1,21 @@
import * as React from "react"
import * as React from 'react';
const MOBILE_BREAKPOINT = 768
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener('change', onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener('change', onChange);
}, []);
return !!isMobile
return !!isMobile;
}
+9 -5
View File
@@ -1,5 +1,5 @@
import {useQuery} from '@tanstack/react-query'
import services from '@/lib/services'
import { useQuery } from '@tanstack/react-query';
import services from '@/lib/services';
/**
* 获取公共配置(使用 React Query 进行统一缓存与自动同步)
@@ -10,11 +10,15 @@ import services from '@/lib/services'
* ```
*/
export function usePublicConfig() {
const { data: config, isLoading: loading, error } = useQuery({
const {
data: config,
isLoading: loading,
error,
} = useQuery({
queryKey: ['public-config'],
queryFn: () => services.config.getPublicConfig(),
staleTime: 5 * 60 * 1000, // 5 分钟缓存
})
});
return { config: config || null, loading, error }
return { config: config || null, loading, error };
}