feat: update dependencies and enhance authentication flow with context hooks

This commit is contained in:
2026-02-22 04:28:26 +08:00
parent 26f8d24b89
commit 3630144fb1
4 changed files with 55 additions and 29 deletions

View File

@@ -55,6 +55,6 @@
"tailwindcss": "^4.2.0", "tailwindcss": "^4.2.0",
"tw-animate-css": "^1.4.0", "tw-animate-css": "^1.4.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vite": "v8.0.0-beta.14" "vite": "v8.0.0-beta.15"
} }
} }

View File

@@ -1,13 +1,23 @@
import { Query } from '@kevisual/query'; import { Query, DataOpts } from '@kevisual/query';
import { QueryLoginBrowser } from '@kevisual/api/query-login' import { QueryLoginBrowser } from '@kevisual/api/query-login'
export const query = new Query({ import { useContextKey } from '@kevisual/context';
export const query = useContextKey('query', new Query({
url: '/api/router', url: '/api/router',
}); }));
const afterResponse: DataOpts['afterResponse'] = async (response, ctx) => {
if (response.code === 401) {
await queryLogin.logout();
setTimeout(() => { location.reload() }, 2000);
}
return response;
}
query.after(afterResponse);
export const queryClient = new Query({ export const queryClient = useContextKey('queryClient', new Query({
url: '/client/router', url: '/client/router',
}); }));
export const queryLogin = new QueryLoginBrowser({ queryClient.after(afterResponse);
export const queryLogin = useContextKey('queryLogin', new QueryLoginBrowser({
query: query query: query
}); }));

View File

@@ -15,7 +15,7 @@ export const AuthProvider = ({ children, mustLogin }: Props) => {
useEffect(() => { useEffect(() => {
store.init() store.init()
}, []) }, [])
const loginUrl = '/root/login?redirect=' + encodeURIComponent(window.location.href); const loginUrl = '/root/login/?redirect=' + encodeURIComponent(window.location.href);
if (mustLogin && !store.me) { if (mustLogin && !store.me) {
return ( return (
<div className="w-full h-full min-h-screen flex items-center justify-center bg-background"> <div className="w-full h-full min-h-screen flex items-center justify-center bg-background">
@@ -27,13 +27,15 @@ export const AuthProvider = ({ children, mustLogin }: Props) => {
<h2 className="text-xl font-semibold text-foreground"></h2> <h2 className="text-xl font-semibold text-foreground"></h2>
<p className="text-sm text-muted-foreground">访</p> <p className="text-sm text-muted-foreground">访</p>
</div> </div>
<a <div
href={loginUrl}
className="inline-flex items-center justify-center gap-2 w-full px-6 py-2.5 rounded-lg bg-foreground text-background text-sm font-medium transition-opacity hover:opacity-80 active:opacity-70" className="inline-flex items-center justify-center gap-2 w-full px-6 py-2.5 rounded-lg bg-foreground text-background text-sm font-medium transition-opacity hover:opacity-80 active:opacity-70"
onClick={() => {
window.open(loginUrl, '_self')
}}
> >
<LogIn className="w-4 h-4" /> <LogIn className="w-4 h-4" />
</a> </div>
</div> </div>
</div> </div>
) )

View File

@@ -1,17 +1,24 @@
import { Link, Outlet, createRootRoute, useNavigate } from '@tanstack/react-router' // import { LayoutMain } from '@/modules/layout'
const LayoutMain = null;
import { Link, Outlet, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
import { Toaster } from '@/components/ui/sonner' import { Toaster } from '@/components/ui/sonner'
import { AuthProvider } from '@/pages/auth' import { AuthProvider } from '@/pages/auth'
import { TooltipProvider } from '@/components/ui/tooltip' import { TooltipProvider } from '@/components/ui/tooltip'
import { Home } from 'lucide-react';
export const Route = createRootRoute({ export const Route = createRootRoute({
component: RootComponent, component: RootComponent,
}) })
function RootComponent() { const BaseHeader = (props: { main?: React.ComponentType | null }) => {
if (props.main) {
const MainComponent = props.main
return <MainComponent />
}
return ( return (
<div className='h-full overflow-hidden'> <>
<div className="flex gap-2 text-lg w-full h-12 items-center">
<div className="p-2 flex gap-2 text-lg"> <div className='px-2'>
<Link <Link
to="/" to="/"
activeProps={{ activeProps={{
@@ -19,13 +26,21 @@ function RootComponent() {
}} }}
activeOptions={{ exact: true }} activeOptions={{ exact: true }}
> >
Home <Home className='w-5 h-5' />
</Link> </Link>
</div> </div>
</div>
<hr /> <hr />
<AuthProvider> </>
)
}
function RootComponent() {
return (
<div className='h-full overflow-hidden'>
<BaseHeader main={LayoutMain} />
<AuthProvider mustLogin={true}>
<TooltipProvider> <TooltipProvider>
<main className='h-[calc(100%-4rem)] overflow-auto scrollbar'> <main className='h-[calc(100%-3rem)] overflow-auto scrollbar'>
<Outlet /> <Outlet />
</main> </main>
</TooltipProvider> </TooltipProvider>
@@ -33,6 +48,5 @@ function RootComponent() {
<TanStackRouterDevtools position="bottom-right" /> <TanStackRouterDevtools position="bottom-right" />
<Toaster /> <Toaster />
</div> </div>
) )
} }