Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -1,21 +1,27 @@
|
||||
export const isDev = process.env.NODE_ENV === "development";
|
||||
|
||||
const BASE_NAME = isDev ? '' : '/root/center';
|
||||
|
||||
// @ts-ignore
|
||||
export const basename = BASE_NAME;
|
||||
|
||||
export const wrapBasename = (path: string) => {
|
||||
const hasEnd = path.endsWith('/')
|
||||
let _basename = basename;
|
||||
if (basename) {
|
||||
_basename = `${basename}${path}`;
|
||||
return `${basename}${path}` + (hasEnd ? '' : '/');
|
||||
} else {
|
||||
_basename = path;
|
||||
return path;
|
||||
}
|
||||
if (isDev) {
|
||||
return _basename
|
||||
}
|
||||
return !hasEnd ? _basename + '/' : _basename;
|
||||
}
|
||||
|
||||
// 动态计算 basename,根据当前 URL 路径
|
||||
export const getDynamicBasename = (): string => {
|
||||
const path = window.location.pathname
|
||||
const [user, key, id] = path.split('/').filter(Boolean)
|
||||
if (key === 'v1' && id) {
|
||||
return `/${user}/v1/${id}`
|
||||
}
|
||||
// 默认使用构建时的 basename
|
||||
return basename
|
||||
}
|
||||
|
||||
export const openLink = (path: string, target: string = '_self') => {
|
||||
if (path.startsWith('http://') || path.startsWith('https://')) {
|
||||
window.open(path, target);
|
||||
|
||||
@@ -102,9 +102,9 @@ export const LayoutUser = () => {
|
||||
<div className='flex gap-4'>
|
||||
{items.length > 0 && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<TooltipTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<DropdownMenuTrigger>
|
||||
<Button variant='ghost' size='icon'>
|
||||
<Users />
|
||||
</Button>
|
||||
|
||||
@@ -23,7 +23,7 @@ export const useQuickMenu = () => {
|
||||
{
|
||||
title: '应用',
|
||||
icon: <AppstoreOutlined />,
|
||||
link: '/apps/',
|
||||
link: '/apps',
|
||||
},
|
||||
// {
|
||||
// title: '文件',
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
'use client';
|
||||
import { MenuOutlined, SwapOutlined } from '@ant-design/icons';
|
||||
import { LayoutMenu, useQuickMenu } from './Menu';
|
||||
import { useLayoutStore, usePlatformStore } from './store';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useEffect, useLayoutEffect, useState } from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { LayoutUser } from './LayoutUser';
|
||||
import PandaPNG from '@/assets/panda.jpg';
|
||||
import QRCodePNG from '@/assets/qrcode-8x8.jpg';
|
||||
import clsx from 'clsx';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
|
||||
import { useNavigate, useLocation } from '@tanstack/react-router';
|
||||
import { QrCode } from 'lucide-react';
|
||||
export const IconButton = (props: any) => {
|
||||
return (
|
||||
<button
|
||||
<div
|
||||
className={clsx(
|
||||
'inline-flex items-center justify-center rounded-md p-2 transition-colors hover:bg-slate-100 disabled:opacity-50 disabled:pointer-events-none',
|
||||
props.className,
|
||||
)}
|
||||
{...props}>
|
||||
{props.children}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
import { QrCode } from 'lucide-react';
|
||||
import { openLink } from '../basename';
|
||||
|
||||
type LayoutMainProps = {
|
||||
title?: React.ReactNode;
|
||||
@@ -43,6 +40,8 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
};
|
||||
}),
|
||||
);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const platformStore = usePlatformStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
@@ -55,7 +54,6 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
);
|
||||
const { isMac, mount, isElectron } = platformStore;
|
||||
const quickMenu = useQuickMenu();
|
||||
const pathname = usePathname();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
platformStore.init();
|
||||
@@ -66,9 +64,9 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className='flex w-full h-full flex-col relative'>
|
||||
<div className='flex gap-2 text-lg w-full relative'>
|
||||
<div
|
||||
className={clsx('layout-menu items-center ', !mount && '!invisible')}
|
||||
className={clsx('layout-menu items-center w-full', !mount && 'invisible!')}
|
||||
style={{
|
||||
cursor: isElectron ? 'move' : 'default',
|
||||
}}>
|
||||
@@ -77,16 +75,18 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
<div className='text-xl font-bold '>{props.title}</div>
|
||||
<div className='flex items-center gap-2 text-sm '>
|
||||
{quickMenu.map((item, index) => {
|
||||
const isActive = pathname === item.link;
|
||||
const isActive = location.pathname === item.link;
|
||||
console.log('isActive', location, item.link, isActive);
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={clsx('flex items-center gap-2 px-1', isActive && 'border border-white')}
|
||||
onClick={() => {
|
||||
openLink(item.link, '_self');
|
||||
console.log('navigate to', item.link);
|
||||
navigate({ to: item.link })
|
||||
}}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<TooltipTrigger >
|
||||
<div className='cursor-pointer'>{item.icon}</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{item.title}</TooltipContent>
|
||||
@@ -103,7 +103,7 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
</IconButton>
|
||||
|
||||
<div className='absolute hidden group-hover:flex bg-white p-2 border shadow-md top-10 -left-15 w-40 z-[9999] flex-col items-center justify-center rounded-md'>
|
||||
<img src={QRCodePNG.src} alt='QR Code' />
|
||||
<img src={QRCodePNG} alt='QR Code' />
|
||||
<div className='text-sm text-black'>逸闻设计</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,7 +111,7 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
{menuStore.me?.type === 'org' && (
|
||||
<div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<TooltipTrigger>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
menuStore.switchOrg('', 'user');
|
||||
@@ -127,7 +127,7 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
{menuStore.me?.avatar ? (
|
||||
<img className='w-8 h-8 rounded-full' src={menuStore.me?.avatar} alt='avatar' />
|
||||
) : (
|
||||
<img className='w-8 h-8 rounded-full' src={PandaPNG.src} alt='avatar' />
|
||||
<img className='w-8 h-8 rounded-full' src={PandaPNG} alt='avatar' />
|
||||
)}
|
||||
</div>
|
||||
<div className='cursor-pointer' onClick={() => menuStore.setOpenUser(true)}>
|
||||
@@ -135,13 +135,6 @@ export const LayoutMain = (props: LayoutMainProps) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className='flex'
|
||||
style={{
|
||||
height: 'calc(100vh - 3rem)',
|
||||
}}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
<LayoutUser />
|
||||
</div>
|
||||
|
||||
@@ -1,32 +1,14 @@
|
||||
'use client';
|
||||
import { QueryClient } from '@kevisual/query';
|
||||
import { QueryLoginBrowser } from '@kevisual/api/login';
|
||||
import { toast } from 'sonner';
|
||||
import { Query } from '@kevisual/query';
|
||||
import { QueryLoginBrowser } from '@kevisual/api/query-login'
|
||||
import { useContextKey } from '@kevisual/context';
|
||||
export const query = useContextKey('query', new Query({
|
||||
url: '/api/router',
|
||||
}));
|
||||
|
||||
// Only create instances in browser environment
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
export const queryClient = useContextKey('queryClient', new Query({
|
||||
url: '/client/router',
|
||||
}));
|
||||
|
||||
export const query = isBrowser ? new QueryClient({}) : {} as QueryClient;
|
||||
|
||||
export const queryLogin = isBrowser
|
||||
? new QueryLoginBrowser({
|
||||
query: query as any,
|
||||
})
|
||||
: {} as QueryLoginBrowser;
|
||||
|
||||
if (isBrowser) {
|
||||
(query as any).afterResponse = async (res, ctx) => {
|
||||
const newRes = await queryLogin.run401Action(res, ctx, {
|
||||
afterAlso401: () => {},
|
||||
afterCheck: (res: any) => {
|
||||
if (res.code === 200) {
|
||||
toast.success('刷新登陆信息');
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
});
|
||||
return newRes as any;
|
||||
};
|
||||
}
|
||||
export const queryLogin = useContextKey('queryLogin', new QueryLoginBrowser({
|
||||
query: query
|
||||
}));
|
||||
Reference in New Issue
Block a user