feat: 优化项目目录结构
This commit is contained in:
33
apps/frontend/hooks/admin/user/use-user-list.ts
Normal file
33
apps/frontend/hooks/admin/user/use-user-list.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client"
|
||||
|
||||
import { list, UserListParams, UserListResponse } from '@/lib/api/admin/user'
|
||||
import { useCallback } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import useSWR from 'swr'
|
||||
|
||||
export function useUserList(params?: UserListParams) {
|
||||
const { data, error, isLoading, mutate } = useSWR<UserListResponse>(
|
||||
['/api/admin/user', params],
|
||||
() => list(params),
|
||||
{
|
||||
onError: (e) => {
|
||||
toast.error(`${e.message || e}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
return mutate()
|
||||
}, [mutate])
|
||||
|
||||
return {
|
||||
users: data?.items ?? [],
|
||||
total: data?.total ?? 0,
|
||||
page: data?.page ?? 1,
|
||||
pageSize: data?.pageSize ?? 20,
|
||||
isLoading,
|
||||
error,
|
||||
mutate,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
26
apps/frontend/hooks/admin/user/use-user.ts
Normal file
26
apps/frontend/hooks/admin/user/use-user.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { AdminApi } from "@/lib/api";
|
||||
import { User } from "@/lib/types/user";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function useUser(userId: string) {
|
||||
const { data, error, isLoading, mutate } = useSWR<User>(
|
||||
['/api/admin/user', userId],
|
||||
() => AdminApi.user.get(userId),
|
||||
{
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
dedupingInterval: 0,
|
||||
onError: (e) => {
|
||||
toast.error(`${e.message || e}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
user: data,
|
||||
isLoading,
|
||||
error,
|
||||
mutate,
|
||||
}
|
||||
}
|
||||
30
apps/frontend/hooks/admin/web/blog/use-blog-list.ts
Normal file
30
apps/frontend/hooks/admin/web/blog/use-blog-list.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
"use client"
|
||||
|
||||
import { AdminApi } from "@/lib/api";
|
||||
import { useCallback } from "react";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function useBlogList() {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
['/admin/web/blog'],
|
||||
() => AdminApi.web.blog.list(),
|
||||
{
|
||||
onError: (e) => {
|
||||
toast.error(`${e.message || e}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
return mutate()
|
||||
}, [mutate])
|
||||
|
||||
return {
|
||||
blogs: data,
|
||||
error,
|
||||
isLoading,
|
||||
mutate,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
22
apps/frontend/hooks/admin/web/blog/use-oss-store.ts
Normal file
22
apps/frontend/hooks/admin/web/blog/use-oss-store.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useOssSts } from "@/hooks/oss/use-oss-sts";
|
||||
import { StsToken } from "@/lib/api/oss";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export function useOssStore(options: { onStsTokenDataChanged?: (data: StsToken | undefined) => void; } = {}) {
|
||||
const { stsTokenData, isLoading, error, mutate } = useOssSts();
|
||||
|
||||
useEffect(() => {
|
||||
options.onStsTokenDataChanged?.(stsTokenData);
|
||||
}, [stsTokenData]);
|
||||
|
||||
const refresh = async () => {
|
||||
await mutate();
|
||||
}
|
||||
|
||||
return {
|
||||
stsTokenData,
|
||||
isLoading,
|
||||
error,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
30
apps/frontend/hooks/admin/web/resource/use-resource-list.ts
Normal file
30
apps/frontend/hooks/admin/web/resource/use-resource-list.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
"use client"
|
||||
|
||||
import { AdminApi } from "@/lib/api";
|
||||
import { useCallback } from "react";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function useResourceList() {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
['/admin/web/resource'],
|
||||
() => AdminApi.web.resource.list(),
|
||||
{
|
||||
onError: (e) => {
|
||||
toast.error(`${e.message || e}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
return mutate()
|
||||
}, [mutate])
|
||||
|
||||
return {
|
||||
resources: data,
|
||||
error,
|
||||
isLoading,
|
||||
mutate,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
25
apps/frontend/hooks/oss/use-oss-sts.ts
Normal file
25
apps/frontend/hooks/oss/use-oss-sts.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { OssApi } from "@/lib/api";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function useOssSts() {
|
||||
const { data: stsTokenData, isLoading, error, mutate } = useSWR(
|
||||
'/api/oss/sts',
|
||||
() => OssApi.getStsToken(),
|
||||
{
|
||||
shouldRetryOnError: false,
|
||||
// refreshInterval: 59 * 60 * 1000,
|
||||
revalidateOnFocus: false,
|
||||
onError: (e) => {
|
||||
toast.error(`${e.message || e}`)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
stsTokenData,
|
||||
isLoading,
|
||||
error,
|
||||
mutate,
|
||||
}
|
||||
}
|
||||
19
apps/frontend/hooks/use-mobile.ts
Normal file
19
apps/frontend/hooks/use-mobile.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as React from "react"
|
||||
|
||||
const MOBILE_BREAKPOINT = 768
|
||||
|
||||
export function useIsMobile() {
|
||||
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
||||
|
||||
React.useEffect(() => {
|
||||
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)
|
||||
}, [])
|
||||
|
||||
return !!isMobile
|
||||
}
|
||||
41
apps/frontend/hooks/user/use-user-me.ts
Normal file
41
apps/frontend/hooks/user/use-user-me.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { UserApi } from "@/lib/api";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function useUserMe({ onError }: { onError?: (e: any) => void } = {}) {
|
||||
const isClientSide = typeof window !== 'undefined';
|
||||
|
||||
const { data: user, isLoading, error } = useSWR(
|
||||
'/api/user/me',
|
||||
async () => {
|
||||
if (isClientSide && !localStorage.getItem('token')) {
|
||||
throw Object.assign(new Error('未登录'), { statusCode: -1 });
|
||||
}
|
||||
return await UserApi.me();
|
||||
},
|
||||
{
|
||||
onError: (error) => {
|
||||
if (error.statusCode === 401) {
|
||||
if (isClientSide) {
|
||||
localStorage.removeItem('token');
|
||||
}
|
||||
}
|
||||
|
||||
onError?.(error);
|
||||
},
|
||||
revalidateIfStale: false,
|
||||
revalidateOnFocus: false,
|
||||
shouldRetryOnError: (err) => {
|
||||
if ([-1, 401].includes(err.statusCode)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
user,
|
||||
isLoading,
|
||||
error
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user