1
0
This commit is contained in:
2025-06-24 17:37:16 +08:00
parent fdb1812e8e
commit 2a818cba7f
8 changed files with 367 additions and 68 deletions

View File

@@ -1,34 +1,43 @@
import { Github, Mail, Phone, MapPin, ChevronDown, ExternalLink, Shield, Book, Globe, Brain } from 'lucide-react';
export const App = () => {
import { Mail, Phone, MapPin, Book, Globe, Brain, Save } from 'lucide-react';
import { chain, TextEditor } from './components/TextEditor';
// import { ToastContainer } from 'react-toastify';
// @ts-ignore
import Logo from './assets/logo-1.png';
export const Main = () => {
return (
<div className='min-h-screen bg-gray-50'>
{/* Hero Section */}
<header className='bg-gradient-to-r from-blue-600 to-indigo-700 text-white'>
<nav className='container mx-auto px-6 py-4 flex justify-between items-center'>
<header className=''>
<nav className='px-4 mx-auto h-16 flex justify-between items-center bg-white border-b border-b-gray-200 w-full'>
<div className='flex items-center space-x-4'>
<img src='https://kevisual.cn/root/center/panda.jpg' alt='Kevisual Logo' className='h-10 w-10 object-contain' />
<span className='text-xl font-bold'>Kevisual </span>
<img src={Logo} alt='可视化助手 Logo' className='h-10 w-20 ' />
</div>
<div className='hidden md:flex space-x-6'>
<a href='#features' className='hover:text-gray-200'>
<a href='#features' className='hover:text-gray-400'>
</a>
<a href='#about' className='hover:text-gray-200'>
</a>
<a href='#contact' className='hover:text-gray-200'>
<a href='#contact' className='hover:text-gray-400'>
</a>
</div>
</nav>
<div className='container mx-auto px-6 py-24 text-center'>
<h1 className='text-4xl md:text-6xl font-bold mb-6'></h1>
<p className='text-xl md:text-2xl mb-8 opacity-90'>线</p>
<ChevronDown className='w-8 h-8 mx-auto animate-bounce' />
</div>
</header>
<main
className='flex flex-col overflow-hidden'
style={{
height: 'calc(100vh - 64px)',
}}>
<nav className='h-12 bg-white'>
<button className='flex items-center px-4 h-full bg-white border-b border-b-gray-200 hover:bg-gray-50 cursor-pointer' onClick={() => {}}>
<span className='text-gray-700'></span>
<Save className='ml-2 w-4 h-4 text-gray-500' />
</button>
</nav>
<div className='p-2 rounded shadow' style={{ height: 'calc(100% - 48px - 48px)' }}>
<TextEditor content='' chain={chain} />
</div>
<footer className='h-12'></footer>
</main>
{/* Features Section */}
<section id='features' className='py-20 bg-white'>
@@ -44,44 +53,14 @@ export const App = () => {
<div className='p-6 rounded-lg shadow-lg bg-white'>
<Brain className='w-12 h-12 text-blue-600 mb-4' />
<h3 className='text-xl font-semibold mb-4'>AI (Dev)</h3>
<p className='text-gray-600'></p>
<h3 className='text-xl font-semibold mb-4'></h3>
<p className='text-gray-600'>访</p>
</div>
<div className='p-6 rounded-lg shadow-lg bg-white'>
<Book className='w-12 h-12 text-blue-600 mb-4' />
<h3 className='text-xl font-semibold mb-4'>(Dev)</h3>
<p className='text-gray-600'>AI驱动的笔记工具</p>
</div>
</div>
</div>
</section>
{/* About Section */}
<section id='about' className='py-20 bg-gray-50'>
<div className='container mx-auto px-6'>
<h2 className='text-3xl font-bold text-center mb-16'></h2>
<div className='max-w-3xl mx-auto text-center'>
<p className='text-gray-600 mb-8'>使便</p>
<div className='grid md:grid-cols-2 gap-8'>
<div>
<h3 className='text-xl font-semibold mb-4'>使</h3>
<ul className='text-left text-gray-600 space-y-2'>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
</ul>
</div>
<div>
<h3 className='text-xl font-semibold mb-4'></h3>
<ul className='text-left text-gray-600 space-y-2'>
<li> 便</li>
<li> </li>
<li> </li>
<li> </li>
</ul>
</div>
<h3 className='text-xl font-semibold mb-4'></h3>
<p className='text-gray-600'></p>
</div>
</div>
</div>
@@ -91,11 +70,11 @@ export const App = () => {
<section id='contact' className='py-20 bg-white'>
<div className='container mx-auto px-6'>
<h2 className='text-3xl font-bold text-center mb-16'></h2>
<div className='max-w-2xl mx-auto'>
<div className='max-w-2xl mx-auto w-[200px]'>
<div className='space-y-6'>
<div className='flex items-center space-x-4'>
<Mail className='w-6 h-6 text-blue-600' />
<span>envision@kevisual.cn</span>
<span>kevisual@kevisual.cn</span>
</div>
<div className='flex items-center space-x-4'>
<Phone className='w-6 h-6 text-blue-600' />
@@ -103,7 +82,7 @@ export const App = () => {
</div>
<div className='flex items-center space-x-4'>
<MapPin className='w-6 h-6 text-blue-600' />
<span>西230A区3楼2954室</span>
<span></span>
</div>
</div>
</div>
@@ -126,11 +105,6 @@ export const App = () => {
</a>
</li>
<li>
<a href='#about' className='hover:text-white'>
</a>
</li>
<li>
<a href='#contact' className='hover:text-white'>
@@ -142,12 +116,12 @@ export const App = () => {
<h3 className='text-lg font-semibold mb-4'></h3>
<ul className='space-y-2 text-gray-400'>
<li>
<a href='/privacy' className='hover:text-white'>
<a href='./privacy' className='hover:text-white'>
</a>
</li>
<li>
<a href='/terms' className='hover:text-white'>
<a href='./terms' className='hover:text-white'>
</a>
</li>
@@ -159,9 +133,6 @@ export const App = () => {
<a href='mailto:feedback@kevisual.cn' className='text-gray-400 hover:text-white'>
<Mail className='w-6 h-6' />
</a>
<a href='https://github.com/' className='text-gray-400 hover:text-white'>
<Github className='w-6 h-6' />
</a>
</div>
</div>
</div>
@@ -179,4 +150,11 @@ export const App = () => {
);
};
export default App;
export const App = () => {
return (
<>
{/* <ToastContainer></ToastContainer> */}
<App />
</>
);
};

BIN
src/assets/logo-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

7
src/components/Icon.tsx Normal file
View File

@@ -0,0 +1,7 @@
export const Github = () => {
return (
<svg aria-hidden='true' height='24' viewBox='0 0 24 24' version='1.1' width='24' data-view-component='true' className='octicon octicon-mark-github'>
<path d='M12 1C5.923 1 1 5.923 1 12c0 4.867 3.149 8.979 7.521 10.436.55.096.756-.233.756-.522 0-.262-.013-1.128-.013-2.049-2.764.509-3.479-.674-3.699-1.292-.124-.317-.66-1.293-1.127-1.554-.385-.207-.936-.715-.014-.729.866-.014 1.485.797 1.691 1.128.99 1.663 2.571 1.196 3.204.907.096-.715.385-1.196.701-1.471-2.448-.275-5.005-1.224-5.005-5.432 0-1.196.426-2.186 1.128-2.956-.111-.275-.496-1.402.11-2.915 0 0 .921-.288 3.024 1.128a10.193 10.193 0 0 1 2.75-.371c.936 0 1.871.123 2.75.371 2.104-1.43 3.025-1.128 3.025-1.128.605 1.513.221 2.64.111 2.915.701.77 1.127 1.747 1.127 2.956 0 4.222-2.571 5.157-5.019 5.432.399.344.743 1.004.743 2.035 0 1.471-.014 2.654-.014 3.025 0 .289.206.632.756.522C19.851 20.979 23 16.854 23 12c0-6.077-4.922-11-11-11Z'></path>
</svg>
);
};

View File

@@ -0,0 +1,39 @@
import { createEditor } from '@kevisual/codemirror';
import { Chain } from '@kevisual/codemirror/utils';
import { useEffect, useRef } from 'react';
export const chain = new Chain();
type TextEditorProps = {
content: string;
chain?: Chain;
};
export const TextEditor = ({ content, chain }: TextEditorProps) => {
const editorElRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<ReturnType<typeof createEditor>>(null);
useEffect(() => {
initEditor();
return () => {
if (editorRef.current) {
chain?.destroy?.();
}
};
}, []);
useEffect(() => {
if (editorRef.current) {
chain?.setContent?.(content);
}
}, [content]);
const initEditor = async () => {
if (!editorElRef.current) return;
const editor = createEditor(editorElRef.current, {
type: 'html',
});
const cmScroller = editorElRef.current.querySelector('.cm-scroller');
if (cmScroller) {
cmScroller.classList.add('scrollbar');
}
chain?.setEditor?.(editor);
editorRef.current = editor;
};
return <div className='h-full overflow-hidden' ref={editorElRef}></div>;
};