81 lines
3.1 KiB
TypeScript
81 lines
3.1 KiB
TypeScript
import { useContextKey } from '@kevisual/context';
|
|
import '@kevisual/kv-login';
|
|
import { checkPluginLogin } from '@kevisual/kv-login'
|
|
import { useEffect } from 'react';
|
|
import { useLayoutStore } from './store';
|
|
import { useShallow } from 'zustand/shallow';
|
|
import { useNavigate } from '@tanstack/react-router';
|
|
|
|
export const LoginComponent = ({ onLoginSuccess }: { onLoginSuccess: () => void }) => {
|
|
useEffect(() => {
|
|
// 监听登录成功事件
|
|
const handleLoginSuccess = () => {
|
|
console.log('监听到登录成功事件,关闭弹窗');
|
|
onLoginSuccess();
|
|
};
|
|
const loginEmitter = useContextKey('login-emitter')
|
|
console.log('KvLogin Types:', loginEmitter);
|
|
|
|
loginEmitter.on('login-success', handleLoginSuccess);
|
|
|
|
// 清理监听器
|
|
return () => {
|
|
loginEmitter.off('login-success', handleLoginSuccess);
|
|
};
|
|
}, [onLoginSuccess]);
|
|
|
|
// @ts-ignore
|
|
return (<kv-login></kv-login>)
|
|
}
|
|
export const App = () => {
|
|
const store = useLayoutStore(useShallow((state) => ({
|
|
init: state.init,
|
|
loginPageConfig: state.loginPageConfig,
|
|
})));
|
|
useEffect(() => {
|
|
checkPluginLogin();
|
|
}, []);
|
|
const navigate = useNavigate();
|
|
const handleLoginSuccess = async () => {
|
|
await store.init()
|
|
navigate({ to: '/' })
|
|
};
|
|
const { title, subtitle, footer } = store.loginPageConfig;
|
|
return (
|
|
<div className='w-full h-full relative overflow-hidden bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900'>
|
|
{/* 背景装饰 - 圆形光晕 */}
|
|
<div className='absolute top-1/4 -left-32 w-96 h-96 bg-purple-500/30 rounded-full blur-3xl'></div>
|
|
<div className='absolute bottom-1/4 -right-32 w-96 h-96 bg-blue-500/30 rounded-full blur-3xl'></div>
|
|
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-indigo-500/20 rounded-full blur-3xl'></div>
|
|
|
|
{/* 背景装饰 - 网格图案 */}
|
|
<div className='absolute inset-0 opacity-[0.03] bg-[linear-gradient(rgba(255,255,255,0.1)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.1)_1px,transparent_1px)] bg-[size:50px_50px]'></div>
|
|
|
|
{/* 顶部装饰文字 */}
|
|
<div className='absolute top-10 left-0 right-0 text-center'>
|
|
<h1 className='text-4xl font-bold text-white/90 tracking-wider'>{title}</h1>
|
|
<p className='mt-2 text-white/50 text-sm tracking-widest'>{subtitle}</p>
|
|
</div>
|
|
|
|
{/* 登录卡片容器 */}
|
|
<div className='w-full h-full flex items-center justify-center p-8'>
|
|
<div className='relative'>
|
|
{/* 卡片外圈光效 */}
|
|
<div className='absolute -inset-1 bg-gradient-to-r from-purple-500 via-blue-500 to-indigo-500 rounded-2xl blur opacity-30'></div>
|
|
|
|
{/* 登录组件容器 */}
|
|
<div className='relative bg-slate-900/80 backdrop-blur-xl rounded-2xl border border-white/10 shadow-2xl overflow-hidden'>
|
|
<LoginComponent onLoginSuccess={handleLoginSuccess} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 底部装饰 */}
|
|
<div className='absolute bottom-6 left-0 right-0 text-center'>
|
|
<p className='text-white/30 text-xs'>{footer}</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App; |