Spaces:
Running
Running
Commit ·
be0c20e
1
Parent(s): c52bdb0
fix
Browse files- index.html +77 -0
- metadata.json +7 -0
- package.json +15 -32
- src/App.css +0 -38
- src/App.js +0 -25
- src/App.test.js +0 -8
- src/App.tsx +62 -0
- src/components/AIMentor.tsx +141 -0
- src/components/Courses.tsx +84 -0
- src/components/Features.tsx +76 -0
- src/components/Footer.tsx +63 -0
- src/components/Header.tsx +39 -0
- src/components/Hero.tsx +83 -0
- src/index.css +0 -13
- src/{index.js → index.tsx} +6 -8
- src/logo.svg +0 -1
- src/reportWebVitals.js +0 -13
- src/setupTests.js +0 -5
- src/types.ts +21 -0
- tsconfig.json +29 -0
- vite.config.ts +23 -0
index.html
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ru">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Neural Academy | AI School</title>
|
| 7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
| 9 |
+
<script>
|
| 10 |
+
tailwind.config = {
|
| 11 |
+
theme: {
|
| 12 |
+
extend: {
|
| 13 |
+
fontFamily: {
|
| 14 |
+
sans: ['Inter', 'sans-serif'],
|
| 15 |
+
mono: ['JetBrains Mono', 'monospace'],
|
| 16 |
+
},
|
| 17 |
+
colors: {
|
| 18 |
+
primary: '#2563eb',
|
| 19 |
+
surface: '#f8fafc',
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
</script>
|
| 25 |
+
<style>
|
| 26 |
+
body {
|
| 27 |
+
font-family: 'Inter', sans-serif;
|
| 28 |
+
scroll-behavior: smooth;
|
| 29 |
+
-webkit-font-smoothing: antialiased;
|
| 30 |
+
}
|
| 31 |
+
.tech-border {
|
| 32 |
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
| 33 |
+
}
|
| 34 |
+
.glass-panel {
|
| 35 |
+
background: rgba(255, 255, 255, 0.85);
|
| 36 |
+
backdrop-filter: blur(16px);
|
| 37 |
+
-webkit-backdrop-filter: blur(16px);
|
| 38 |
+
border: 1px solid rgba(255, 255, 255, 0.6);
|
| 39 |
+
box-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.05);
|
| 40 |
+
}
|
| 41 |
+
.grid-bg {
|
| 42 |
+
background-size: 40px 40px;
|
| 43 |
+
background-image:
|
| 44 |
+
linear-gradient(to right, rgba(0,0,0,0.03) 1px, transparent 1px),
|
| 45 |
+
linear-gradient(to bottom, rgba(0,0,0,0.03) 1px, transparent 1px);
|
| 46 |
+
}
|
| 47 |
+
/* Custom scrollbar */
|
| 48 |
+
::-webkit-scrollbar {
|
| 49 |
+
width: 8px;
|
| 50 |
+
}
|
| 51 |
+
::-webkit-scrollbar-track {
|
| 52 |
+
background: transparent;
|
| 53 |
+
}
|
| 54 |
+
::-webkit-scrollbar-thumb {
|
| 55 |
+
background: #cbd5e1;
|
| 56 |
+
border-radius: 4px;
|
| 57 |
+
}
|
| 58 |
+
::-webkit-scrollbar-thumb:hover {
|
| 59 |
+
background: #94a3b8;
|
| 60 |
+
}
|
| 61 |
+
</style>
|
| 62 |
+
<script type="importmap">
|
| 63 |
+
{
|
| 64 |
+
"imports": {
|
| 65 |
+
"@google/genai": "https://esm.sh/@google/genai@^1.38.0",
|
| 66 |
+
"react-dom/": "https://esm.sh/react-dom@^19.2.4/",
|
| 67 |
+
"react": "https://esm.sh/react@^19.2.4",
|
| 68 |
+
"react/": "https://esm.sh/react@^19.2.4/"
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
</script>
|
| 72 |
+
</head>
|
| 73 |
+
<body class="bg-white text-slate-900 selection:bg-blue-100 selection:text-blue-900">
|
| 74 |
+
<div id="root"></div>
|
| 75 |
+
<script type="module" src="/src/index.tsx"></script>
|
| 76 |
+
</body>
|
| 77 |
+
</html>
|
metadata.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "Neural Academy - AI Excellence",
|
| 3 |
+
"description": "A modern, high-tech landing page for an online artificial intelligence school featuring an interactive AI mentor powered by Gemini.",
|
| 4 |
+
"requestFramePermissions": [
|
| 5 |
+
"microphone"
|
| 6 |
+
]
|
| 7 |
+
}
|
package.json
CHANGED
|
@@ -1,39 +1,22 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "
|
| 3 |
-
"version": "0.1.0",
|
| 4 |
"private": true,
|
| 5 |
-
"
|
| 6 |
-
|
| 7 |
-
"@testing-library/jest-dom": "^6.6.3",
|
| 8 |
-
"@testing-library/react": "^16.3.0",
|
| 9 |
-
"@testing-library/user-event": "^13.5.0",
|
| 10 |
-
"react": "^19.1.0",
|
| 11 |
-
"react-dom": "^19.1.0",
|
| 12 |
-
"react-scripts": "5.0.1",
|
| 13 |
-
"web-vitals": "^2.1.4"
|
| 14 |
-
},
|
| 15 |
"scripts": {
|
| 16 |
-
"
|
| 17 |
-
"build": "
|
| 18 |
-
"
|
| 19 |
-
"eject": "react-scripts eject"
|
| 20 |
},
|
| 21 |
-
"
|
| 22 |
-
"
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
]
|
| 26 |
},
|
| 27 |
-
"
|
| 28 |
-
"
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
],
|
| 33 |
-
"development": [
|
| 34 |
-
"last 1 chrome version",
|
| 35 |
-
"last 1 firefox version",
|
| 36 |
-
"last 1 safari version"
|
| 37 |
-
]
|
| 38 |
}
|
| 39 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "neural-academy---ai-excellence",
|
|
|
|
| 3 |
"private": true,
|
| 4 |
+
"version": "0.0.0",
|
| 5 |
+
"type": "module",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
"scripts": {
|
| 7 |
+
"dev": "vite",
|
| 8 |
+
"build": "vite build",
|
| 9 |
+
"preview": "vite preview"
|
|
|
|
| 10 |
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@google/genai": "^1.38.0",
|
| 13 |
+
"react": "^19.2.4",
|
| 14 |
+
"react-dom": "^19.2.4"
|
|
|
|
| 15 |
},
|
| 16 |
+
"devDependencies": {
|
| 17 |
+
"@types/node": "^22.14.0",
|
| 18 |
+
"@vitejs/plugin-react": "^5.0.0",
|
| 19 |
+
"typescript": "~5.8.2",
|
| 20 |
+
"vite": "^6.2.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
}
|
| 22 |
}
|
src/App.css
DELETED
|
@@ -1,38 +0,0 @@
|
|
| 1 |
-
.App {
|
| 2 |
-
text-align: center;
|
| 3 |
-
}
|
| 4 |
-
|
| 5 |
-
.App-logo {
|
| 6 |
-
height: 40vmin;
|
| 7 |
-
pointer-events: none;
|
| 8 |
-
}
|
| 9 |
-
|
| 10 |
-
@media (prefers-reduced-motion: no-preference) {
|
| 11 |
-
.App-logo {
|
| 12 |
-
animation: App-logo-spin infinite 20s linear;
|
| 13 |
-
}
|
| 14 |
-
}
|
| 15 |
-
|
| 16 |
-
.App-header {
|
| 17 |
-
background-color: #282c34;
|
| 18 |
-
min-height: 100vh;
|
| 19 |
-
display: flex;
|
| 20 |
-
flex-direction: column;
|
| 21 |
-
align-items: center;
|
| 22 |
-
justify-content: center;
|
| 23 |
-
font-size: calc(10px + 2vmin);
|
| 24 |
-
color: white;
|
| 25 |
-
}
|
| 26 |
-
|
| 27 |
-
.App-link {
|
| 28 |
-
color: #61dafb;
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
@keyframes App-logo-spin {
|
| 32 |
-
from {
|
| 33 |
-
transform: rotate(0deg);
|
| 34 |
-
}
|
| 35 |
-
to {
|
| 36 |
-
transform: rotate(360deg);
|
| 37 |
-
}
|
| 38 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/App.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
import logo from './logo.svg';
|
| 2 |
-
import './App.css';
|
| 3 |
-
|
| 4 |
-
function App() {
|
| 5 |
-
return (
|
| 6 |
-
<div className="App">
|
| 7 |
-
<header className="App-header">
|
| 8 |
-
<img src={logo} className="App-logo" alt="logo" />
|
| 9 |
-
<p>
|
| 10 |
-
Edit <code>src/App.js</code> and save to reload.
|
| 11 |
-
</p>
|
| 12 |
-
<a
|
| 13 |
-
className="App-link"
|
| 14 |
-
href="https://reactjs.org"
|
| 15 |
-
target="_blank"
|
| 16 |
-
rel="noopener noreferrer"
|
| 17 |
-
>
|
| 18 |
-
Learn React
|
| 19 |
-
</a>
|
| 20 |
-
</header>
|
| 21 |
-
</div>
|
| 22 |
-
);
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
export default App;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/App.test.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
import { render, screen } from '@testing-library/react';
|
| 2 |
-
import App from './App';
|
| 3 |
-
|
| 4 |
-
test('renders learn react link', () => {
|
| 5 |
-
render(<App />);
|
| 6 |
-
const linkElement = screen.getByText(/learn react/i);
|
| 7 |
-
expect(linkElement).toBeInTheDocument();
|
| 8 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/App.tsx
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState, useEffect } from 'react';
|
| 2 |
+
import Header from './components/Header';
|
| 3 |
+
import Hero from './components/Hero';
|
| 4 |
+
import Features from './components/Features';
|
| 5 |
+
import Courses from './components/Courses';
|
| 6 |
+
import AIMentor from './components/AIMentor';
|
| 7 |
+
import Footer from './components/Footer';
|
| 8 |
+
|
| 9 |
+
const App: React.FC = () => {
|
| 10 |
+
const [isScrolled, setIsScrolled] = useState(false);
|
| 11 |
+
|
| 12 |
+
useEffect(() => {
|
| 13 |
+
const handleScroll = () => {
|
| 14 |
+
setIsScrolled(window.scrollY > 20);
|
| 15 |
+
};
|
| 16 |
+
window.addEventListener('scroll', handleScroll);
|
| 17 |
+
return () => window.removeEventListener('scroll', handleScroll);
|
| 18 |
+
}, []);
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<div className="min-h-screen bg-white relative overflow-x-hidden">
|
| 22 |
+
<div className="fixed inset-0 grid-bg pointer-events-none z-0"></div>
|
| 23 |
+
|
| 24 |
+
{/* Subtle ambient gradients */}
|
| 25 |
+
<div className="fixed top-0 right-0 w-[50vw] h-[50vh] bg-blue-100/40 rounded-full blur-[120px] -z-10 translate-x-1/4 -translate-y-1/4"></div>
|
| 26 |
+
<div className="fixed bottom-0 left-0 w-[50vw] h-[50vh] bg-purple-100/40 rounded-full blur-[120px] -z-10 -translate-x-1/4 translate-y-1/4"></div>
|
| 27 |
+
|
| 28 |
+
<Header isScrolled={isScrolled} />
|
| 29 |
+
|
| 30 |
+
<main className="relative z-10">
|
| 31 |
+
<Hero />
|
| 32 |
+
|
| 33 |
+
<section id="features" className="py-24 px-6 border-y border-slate-100 bg-slate-50/50">
|
| 34 |
+
<Features />
|
| 35 |
+
</section>
|
| 36 |
+
|
| 37 |
+
<section id="courses" className="py-24 px-6">
|
| 38 |
+
<Courses />
|
| 39 |
+
</section>
|
| 40 |
+
|
| 41 |
+
<section id="mentor" className="py-24 px-6 max-w-6xl mx-auto">
|
| 42 |
+
<div className="text-center mb-16 space-y-4">
|
| 43 |
+
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-blue-50 border border-blue-100 text-blue-600 text-xs font-mono font-medium tracking-wide">
|
| 44 |
+
<span>●</span> LIVE DEMO
|
| 45 |
+
</div>
|
| 46 |
+
<h2 className="text-4xl md:text-5xl font-extrabold tracking-tight">
|
| 47 |
+
AI Наставник <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600">v3.0</span>
|
| 48 |
+
</h2>
|
| 49 |
+
<p className="text-lg text-slate-500 max-w-2xl mx-auto">
|
| 50 |
+
Протестируйте нашу модель обучения прямо сейчас. Задайте вопрос о карьере, технологиях или программе.
|
| 51 |
+
</p>
|
| 52 |
+
</div>
|
| 53 |
+
<AIMentor />
|
| 54 |
+
</section>
|
| 55 |
+
</main>
|
| 56 |
+
|
| 57 |
+
<Footer />
|
| 58 |
+
</div>
|
| 59 |
+
);
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
export default App;
|
src/components/AIMentor.tsx
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState, useRef, useEffect } from 'react';
|
| 2 |
+
import { GoogleGenAI } from "@google/genai";
|
| 3 |
+
import { ChatMessage } from '../types';
|
| 4 |
+
|
| 5 |
+
const AIMentor: React.FC = () => {
|
| 6 |
+
const [messages, setMessages] = useState<ChatMessage[]>([
|
| 7 |
+
{ role: 'model', text: 'System initialized. Model Gemini-3.0-Flash ready.\nПривет! Я готов ответить на вопросы о курсах, технологиях и карьере в AI.' }
|
| 8 |
+
]);
|
| 9 |
+
const [input, setInput] = useState('');
|
| 10 |
+
const [isLoading, setIsLoading] = useState(false);
|
| 11 |
+
const scrollRef = useRef<HTMLDivElement>(null);
|
| 12 |
+
|
| 13 |
+
useEffect(() => {
|
| 14 |
+
if (scrollRef.current) {
|
| 15 |
+
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
| 16 |
+
}
|
| 17 |
+
}, [messages, isLoading]);
|
| 18 |
+
|
| 19 |
+
const handleSend = async () => {
|
| 20 |
+
if (!input.trim() || isLoading) return;
|
| 21 |
+
|
| 22 |
+
const userMessage = input.trim();
|
| 23 |
+
setInput('');
|
| 24 |
+
setMessages(prev => [...prev, { role: 'user', text: userMessage }]);
|
| 25 |
+
setIsLoading(true);
|
| 26 |
+
|
| 27 |
+
try {
|
| 28 |
+
// Using Gemini API as backend.
|
| 29 |
+
// Note for Hugging Face deployment: This code runs client-side.
|
| 30 |
+
// Just ensure process.env.API_KEY is available in your build environment or secrets.
|
| 31 |
+
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
| 32 |
+
|
| 33 |
+
const history = messages
|
| 34 |
+
.filter((m, i) => !(i === 0 && m.role === 'model'))
|
| 35 |
+
.map(m => ({
|
| 36 |
+
role: m.role,
|
| 37 |
+
parts: [{ text: m.text }]
|
| 38 |
+
}));
|
| 39 |
+
|
| 40 |
+
const response = await ai.models.generateContent({
|
| 41 |
+
model: 'gemini-3-flash-preview',
|
| 42 |
+
contents: [...history, { role: 'user', parts: [{ text: userMessage }] }],
|
| 43 |
+
config: {
|
| 44 |
+
systemInstruction: "Ты — высокотехнологичный AI-ассистент школы Neural Academy. Отвечай кратко, по делу, используй технические термины где уместно, но оставайся понятным. Твой стиль общения — профессиональный, дружелюбный, экспертный.",
|
| 45 |
+
temperature: 0.7,
|
| 46 |
+
},
|
| 47 |
+
});
|
| 48 |
+
|
| 49 |
+
const responseText = response.text || "Error: No response generated.";
|
| 50 |
+
setMessages(prev => [...prev, { role: 'model', text: responseText }]);
|
| 51 |
+
} catch (error) {
|
| 52 |
+
console.error("API Error:", error);
|
| 53 |
+
setMessages(prev => [...prev, { role: 'model', text: "Connection Error: Unable to reach neural core. Please try again." }]);
|
| 54 |
+
} finally {
|
| 55 |
+
setIsLoading(false);
|
| 56 |
+
}
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
return (
|
| 60 |
+
<div className="w-full bg-slate-900 rounded-xl overflow-hidden shadow-2xl border border-slate-700 font-mono text-sm">
|
| 61 |
+
{/* Terminal Header */}
|
| 62 |
+
<div className="bg-slate-800 p-3 flex items-center justify-between border-b border-slate-700">
|
| 63 |
+
<div className="flex items-center gap-2">
|
| 64 |
+
<div className="flex gap-1.5">
|
| 65 |
+
<div className="w-3 h-3 rounded-full bg-red-500/80"></div>
|
| 66 |
+
<div className="w-3 h-3 rounded-full bg-yellow-500/80"></div>
|
| 67 |
+
<div className="w-3 h-3 rounded-full bg-green-500/80"></div>
|
| 68 |
+
</div>
|
| 69 |
+
<div className="ml-3 text-slate-400 text-xs flex items-center gap-2">
|
| 70 |
+
<span className="text-blue-400">~/neural-academy/mentor</span>
|
| 71 |
+
<span className="w-px h-3 bg-slate-600"></span>
|
| 72 |
+
<span className="text-slate-500">bash</span>
|
| 73 |
+
</div>
|
| 74 |
+
</div>
|
| 75 |
+
<div className="flex items-center gap-3">
|
| 76 |
+
<div className="flex items-center gap-1.5 px-2 py-0.5 rounded bg-slate-700/50 border border-slate-600/50">
|
| 77 |
+
<div className="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></div>
|
| 78 |
+
<span className="text-[10px] text-green-400 font-semibold tracking-wider">CONNECTED</span>
|
| 79 |
+
</div>
|
| 80 |
+
</div>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
{/* Terminal Body */}
|
| 84 |
+
<div
|
| 85 |
+
ref={scrollRef}
|
| 86 |
+
className="h-[450px] overflow-y-auto p-6 space-y-4 bg-slate-900/95 scroll-smooth"
|
| 87 |
+
>
|
| 88 |
+
{messages.map((msg, i) => (
|
| 89 |
+
<div key={i} className={`flex flex-col ${msg.role === 'user' ? 'items-end' : 'items-start'}`}>
|
| 90 |
+
<div className={`flex items-center gap-2 mb-1 text-[10px] uppercase tracking-wider ${msg.role === 'user' ? 'text-blue-400 flex-row-reverse' : 'text-purple-400'}`}>
|
| 91 |
+
<span>{msg.role === 'user' ? 'User@Host' : 'AI@Core'}</span>
|
| 92 |
+
<span className="text-slate-600">[{new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}]</span>
|
| 93 |
+
</div>
|
| 94 |
+
<div className={`max-w-[85%] p-3 rounded-lg border ${
|
| 95 |
+
msg.role === 'user'
|
| 96 |
+
? 'bg-blue-900/20 border-blue-500/30 text-blue-100'
|
| 97 |
+
: 'bg-slate-800/50 border-slate-700 text-slate-300'
|
| 98 |
+
}`}>
|
| 99 |
+
<p className="whitespace-pre-wrap leading-relaxed">{msg.text}</p>
|
| 100 |
+
</div>
|
| 101 |
+
</div>
|
| 102 |
+
))}
|
| 103 |
+
|
| 104 |
+
{isLoading && (
|
| 105 |
+
<div className="flex items-start">
|
| 106 |
+
<div className="text-purple-400 text-[10px] uppercase tracking-wider mb-1 mr-2">AI@Core</div>
|
| 107 |
+
<div className="flex items-center gap-1 h-8">
|
| 108 |
+
<span className="w-1.5 h-4 bg-purple-500 animate-pulse"></span>
|
| 109 |
+
<span className="text-purple-500/50">processing...</span>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
)}
|
| 113 |
+
</div>
|
| 114 |
+
|
| 115 |
+
{/* Input Area */}
|
| 116 |
+
<div className="p-3 bg-slate-800 border-t border-slate-700">
|
| 117 |
+
<div className="flex items-center gap-3">
|
| 118 |
+
<span className="text-green-500 font-bold">{'>'}</span>
|
| 119 |
+
<input
|
| 120 |
+
type="text"
|
| 121 |
+
value={input}
|
| 122 |
+
onChange={(e) => setInput(e.target.value)}
|
| 123 |
+
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
|
| 124 |
+
placeholder="Enter command or message..."
|
| 125 |
+
className="flex-grow bg-transparent border-none outline-none text-slate-200 placeholder:text-slate-600 font-mono"
|
| 126 |
+
autoFocus
|
| 127 |
+
/>
|
| 128 |
+
<button
|
| 129 |
+
onClick={handleSend}
|
| 130 |
+
disabled={isLoading}
|
| 131 |
+
className="px-4 py-1.5 bg-slate-700 hover:bg-slate-600 text-slate-300 text-xs rounded border border-slate-600 transition-colors"
|
| 132 |
+
>
|
| 133 |
+
EXECUTE
|
| 134 |
+
</button>
|
| 135 |
+
</div>
|
| 136 |
+
</div>
|
| 137 |
+
</div>
|
| 138 |
+
);
|
| 139 |
+
};
|
| 140 |
+
|
| 141 |
+
export default AIMentor;
|
src/components/Courses.tsx
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
const courses = [
|
| 4 |
+
{
|
| 5 |
+
title: 'Prompt Engineering',
|
| 6 |
+
tag: 'Popular',
|
| 7 |
+
desc: 'Научитесь управлять языковыми моделями как профи. Магия правильных запросов.',
|
| 8 |
+
price: '9 900 ₽',
|
| 9 |
+
duration: '4 недели',
|
| 10 |
+
image: 'https://picsum.photos/seed/prompt/600/400'
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
title: 'LLM & Generative AI',
|
| 14 |
+
tag: 'Pro',
|
| 15 |
+
desc: 'Создание собственных чат-ботов на базе GPT-4 и Llama-3. Архитектура и дообучение.',
|
| 16 |
+
price: '24 900 ₽',
|
| 17 |
+
duration: '12 недель',
|
| 18 |
+
image: 'https://picsum.photos/seed/llm/600/400'
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
title: 'Computer Vision',
|
| 22 |
+
tag: 'Hardcore',
|
| 23 |
+
desc: 'Распознавание объектов, трекинг и сегментация. От теории до деплоя на Edge устройства.',
|
| 24 |
+
price: '21 500 ₽',
|
| 25 |
+
duration: '10 недель',
|
| 26 |
+
image: 'https://picsum.photos/seed/cv/600/400'
|
| 27 |
+
}
|
| 28 |
+
];
|
| 29 |
+
|
| 30 |
+
const Courses: React.FC = () => {
|
| 31 |
+
return (
|
| 32 |
+
<div className="max-w-7xl mx-auto">
|
| 33 |
+
<div className="flex flex-col md:flex-row justify-between items-end mb-12 gap-6">
|
| 34 |
+
<div className="space-y-2">
|
| 35 |
+
<h2 className="text-3xl font-bold text-slate-900 tracking-tight">
|
| 36 |
+
Образовательные треки
|
| 37 |
+
</h2>
|
| 38 |
+
<p className="text-slate-500">
|
| 39 |
+
Актуальные навыки для рынка 2024-2025 года.
|
| 40 |
+
</p>
|
| 41 |
+
</div>
|
| 42 |
+
<button className="text-blue-600 text-sm font-bold flex items-center gap-2 hover:gap-3 transition-all">
|
| 43 |
+
Полный каталог
|
| 44 |
+
<span>→</span>
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
|
| 48 |
+
<div className="grid lg:grid-cols-3 gap-6">
|
| 49 |
+
{courses.map((course, idx) => (
|
| 50 |
+
<div key={idx} className="group bg-white rounded-2xl border border-slate-100 overflow-hidden hover:shadow-xl transition-all duration-300 hover:-translate-y-1">
|
| 51 |
+
<div className="relative h-48 overflow-hidden">
|
| 52 |
+
<img
|
| 53 |
+
src={course.image}
|
| 54 |
+
alt={course.title}
|
| 55 |
+
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
|
| 56 |
+
/>
|
| 57 |
+
<div className="absolute top-4 right-4">
|
| 58 |
+
<span className="bg-white/90 backdrop-blur px-2 py-1 rounded text-[10px] font-bold uppercase tracking-wider text-slate-900 shadow-sm border border-slate-100">
|
| 59 |
+
{course.tag}
|
| 60 |
+
</span>
|
| 61 |
+
</div>
|
| 62 |
+
</div>
|
| 63 |
+
|
| 64 |
+
<div className="p-6 flex flex-col h-[calc(100%-12rem)]">
|
| 65 |
+
<h3 className="text-xl font-bold text-slate-900 mb-2 font-sans group-hover:text-blue-600 transition-colors">
|
| 66 |
+
{course.title}
|
| 67 |
+
</h3>
|
| 68 |
+
<p className="text-sm text-slate-500 leading-relaxed mb-6 flex-grow">
|
| 69 |
+
{course.desc}
|
| 70 |
+
</p>
|
| 71 |
+
|
| 72 |
+
<div className="flex items-center justify-between pt-4 border-t border-slate-50">
|
| 73 |
+
<div className="font-mono text-sm font-bold text-slate-900">{course.price}</div>
|
| 74 |
+
<div className="text-xs font-medium text-slate-400 bg-slate-50 px-2 py-1 rounded">{course.duration}</div>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
))}
|
| 79 |
+
</div>
|
| 80 |
+
</div>
|
| 81 |
+
);
|
| 82 |
+
};
|
| 83 |
+
|
| 84 |
+
export default Courses;
|
src/components/Features.tsx
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
const Features: React.FC = () => {
|
| 4 |
+
return (
|
| 5 |
+
<div className="max-w-7xl mx-auto">
|
| 6 |
+
<div className="flex flex-col md:flex-row justify-between items-end mb-16 gap-6">
|
| 7 |
+
<div className="max-w-2xl">
|
| 8 |
+
<h2 className="text-4xl font-extrabold text-slate-900 tracking-tight mb-4">
|
| 9 |
+
Экосистема обучения
|
| 10 |
+
</h2>
|
| 11 |
+
<p className="text-lg text-slate-500">
|
| 12 |
+
Мы создали среду, где технологии встречают практику.
|
| 13 |
+
</p>
|
| 14 |
+
</div>
|
| 15 |
+
</div>
|
| 16 |
+
|
| 17 |
+
<div className="grid grid-cols-1 md:grid-cols-3 grid-rows-2 gap-6 h-auto md:h-[600px]">
|
| 18 |
+
{/* Large Item 1 */}
|
| 19 |
+
<div className="md:col-span-2 row-span-1 glass-panel p-8 rounded-2xl relative overflow-hidden group">
|
| 20 |
+
<div className="absolute top-0 right-0 w-64 h-64 bg-blue-50 rounded-full blur-3xl -translate-y-1/2 translate-x-1/2 group-hover:bg-blue-100 transition-colors"></div>
|
| 21 |
+
<div className="relative z-10">
|
| 22 |
+
<div className="w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center mb-6 text-white shadow-lg shadow-blue-200">
|
| 23 |
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" /></svg>
|
| 24 |
+
</div>
|
| 25 |
+
<h3 className="text-2xl font-bold mb-3">Практика на реальных GPU</h3>
|
| 26 |
+
<p className="text-slate-500 max-w-md">Доступ к облачным кластерам с H100 для тренировки ваших моделей. Мы оплачиваем вычислительные мощности.</p>
|
| 27 |
+
</div>
|
| 28 |
+
</div>
|
| 29 |
+
|
| 30 |
+
{/* Tall Item */}
|
| 31 |
+
<div className="md:col-span-1 md:row-span-2 bg-slate-900 text-white p-8 rounded-2xl relative overflow-hidden flex flex-col justify-between group">
|
| 32 |
+
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-slate-900/90 z-10"></div>
|
| 33 |
+
<img src="https://picsum.photos/seed/code/600/800" className="absolute inset-0 w-full h-full object-cover opacity-40 group-hover:scale-105 transition-transform duration-700" alt="Code" />
|
| 34 |
+
<div className="relative z-20">
|
| 35 |
+
<div className="w-12 h-12 bg-white/10 backdrop-blur rounded-lg flex items-center justify-center mb-6 border border-white/20">
|
| 36 |
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04l.054-.09A13.916 13.916 0 008 11a4 4 0 118 0c0 1.017-.07 2.019-.203 3m-2.118 6.844A21.88 21.88 0 0015.171 17m3.839 1.132c.645-2.266.99-4.659.99-7.132A8 8 0 008 4.07M3 15.364c.64-1.319 1-2.8 1-4.364 0-1.457.2-2.973.599-4.23m0 0A9.956 9.956 0 0112 5c4.808 0 8.855 2.578 11.237 6.135" /></svg>
|
| 37 |
+
</div>
|
| 38 |
+
<h3 className="text-2xl font-bold mb-3">Карьерный Трек</h3>
|
| 39 |
+
<p className="text-slate-300">Сопровождение от резюме до оффера в Big Tech компаниях.</p>
|
| 40 |
+
</div>
|
| 41 |
+
<div className="relative z-20 mt-8 pt-8 border-t border-white/10">
|
| 42 |
+
<div className="flex -space-x-3">
|
| 43 |
+
{[1,2,3,4].map(i => (
|
| 44 |
+
<div key={i} className="w-10 h-10 rounded-full border-2 border-slate-900 bg-slate-700 overflow-hidden">
|
| 45 |
+
<img src={`https://picsum.photos/seed/avatar${i}/100/100`} alt="Mentor" />
|
| 46 |
+
</div>
|
| 47 |
+
))}
|
| 48 |
+
<div className="w-10 h-10 rounded-full border-2 border-slate-900 bg-blue-600 flex items-center justify-center text-xs font-bold">+40</div>
|
| 49 |
+
</div>
|
| 50 |
+
<p className="mt-3 text-sm text-slate-400 font-mono">Менторы из Google, Meta, Yandex</p>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
{/* Small Item 1 */}
|
| 55 |
+
<div className="glass-panel p-8 rounded-2xl hover:border-blue-200 transition-colors">
|
| 56 |
+
<div className="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center mb-4 text-purple-600">
|
| 57 |
+
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /></svg>
|
| 58 |
+
</div>
|
| 59 |
+
<h3 className="font-bold text-lg mb-2">Инновации</h3>
|
| 60 |
+
<p className="text-sm text-slate-500">Постоянно обновляемая программа. Только SOTA решения.</p>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
{/* Small Item 2 */}
|
| 64 |
+
<div className="glass-panel p-8 rounded-2xl hover:border-blue-200 transition-colors">
|
| 65 |
+
<div className="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center mb-4 text-green-600">
|
| 66 |
+
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
|
| 67 |
+
</div>
|
| 68 |
+
<h3 className="font-bold text-lg mb-2">Комьюнити</h3>
|
| 69 |
+
<p className="text-sm text-slate-500">Закрытые хакатоны и встречи с инвесторами.</p>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
);
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
export default Features;
|
src/components/Footer.tsx
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
const Footer: React.FC = () => {
|
| 4 |
+
return (
|
| 5 |
+
<footer className="bg-white border-t border-slate-100 pt-20 pb-10 px-6">
|
| 6 |
+
<div className="max-w-7xl mx-auto">
|
| 7 |
+
<div className="grid md:grid-cols-4 gap-12 mb-16">
|
| 8 |
+
<div className="col-span-2 space-y-6">
|
| 9 |
+
<div className="flex items-center gap-2">
|
| 10 |
+
<div className="w-10 h-10 bg-indigo-600 rounded-xl flex items-center justify-center">
|
| 11 |
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
| 12 |
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
|
| 13 |
+
</svg>
|
| 14 |
+
</div>
|
| 15 |
+
<span className="text-2xl font-bold tracking-tight">Neural<span className="text-indigo-600">Academy</span></span>
|
| 16 |
+
</div>
|
| 17 |
+
<p className="text-slate-500 max-w-sm leading-relaxed">
|
| 18 |
+
Мы обучаем профессионалов будущего, способных внедрять технологии искусственного интеллекта в реальный бизнес и повседневную жизнь.
|
| 19 |
+
</p>
|
| 20 |
+
<div className="flex gap-4">
|
| 21 |
+
{['Twitter', 'Discord', 'YouTube', 'Telegram'].map((social) => (
|
| 22 |
+
<a key={social} href="#" className="w-10 h-10 rounded-full bg-slate-50 flex items-center justify-center text-slate-400 hover:bg-indigo-50 hover:text-indigo-600 transition-all">
|
| 23 |
+
<span className="sr-only">{social}</span>
|
| 24 |
+
<div className="w-5 h-5 bg-current mask-icon"></div>
|
| 25 |
+
</a>
|
| 26 |
+
))}
|
| 27 |
+
</div>
|
| 28 |
+
</div>
|
| 29 |
+
|
| 30 |
+
<div>
|
| 31 |
+
<h4 className="font-bold mb-6">Обучение</h4>
|
| 32 |
+
<ul className="space-y-4 text-slate-500 font-medium">
|
| 33 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Курсы по LLM</a></li>
|
| 34 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Computer Vision</a></li>
|
| 35 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Бесплатные уроки</a></li>
|
| 36 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Карьера</a></li>
|
| 37 |
+
</ul>
|
| 38 |
+
</div>
|
| 39 |
+
|
| 40 |
+
<div>
|
| 41 |
+
<h4 className="font-bold mb-6">Компания</h4>
|
| 42 |
+
<ul className="space-y-4 text-slate-500 font-medium">
|
| 43 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">О нас</a></li>
|
| 44 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Блог</a></li>
|
| 45 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">Контакты</a></li>
|
| 46 |
+
<li><a href="#" className="hover:text-indigo-600 transition-colors">FAQ</a></li>
|
| 47 |
+
</ul>
|
| 48 |
+
</div>
|
| 49 |
+
</div>
|
| 50 |
+
|
| 51 |
+
<div className="pt-8 border-t border-slate-100 flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-slate-400 font-medium">
|
| 52 |
+
<p>© 2024 Neural Academy. Все права защищены.</p>
|
| 53 |
+
<div className="flex gap-8">
|
| 54 |
+
<a href="#" className="hover:text-slate-600">Политика конфиденциальности</a>
|
| 55 |
+
<a href="#" className="hover:text-slate-600">Условия использования</a>
|
| 56 |
+
</div>
|
| 57 |
+
</div>
|
| 58 |
+
</div>
|
| 59 |
+
</footer>
|
| 60 |
+
);
|
| 61 |
+
};
|
| 62 |
+
|
| 63 |
+
export default Footer;
|
src/components/Header.tsx
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
interface HeaderProps {
|
| 4 |
+
isScrolled: boolean;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
const Header: React.FC<HeaderProps> = ({ isScrolled }) => {
|
| 8 |
+
return (
|
| 9 |
+
<header className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${isScrolled ? 'py-3' : 'py-6'}`}>
|
| 10 |
+
<div className={`mx-auto max-w-7xl px-6 transition-all duration-300 ${isScrolled ? 'glass-panel rounded-full shadow-sm mx-4 md:mx-auto' : ''}`}>
|
| 11 |
+
<div className="flex items-center justify-between h-12">
|
| 12 |
+
<div className="flex items-center gap-2.5 group cursor-pointer">
|
| 13 |
+
<div className="w-8 h-8 bg-slate-900 rounded-lg flex items-center justify-center text-white transition-transform group-hover:scale-110">
|
| 14 |
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
| 15 |
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
|
| 16 |
+
</svg>
|
| 17 |
+
</div>
|
| 18 |
+
<span className="text-lg font-bold tracking-tight text-slate-900 font-sans">Neural<span className="text-blue-600">Academy</span></span>
|
| 19 |
+
</div>
|
| 20 |
+
|
| 21 |
+
<nav className="hidden md:flex items-center gap-8 text-sm font-medium text-slate-500">
|
| 22 |
+
<a href="#features" className="hover:text-blue-600 transition-colors">О школе</a>
|
| 23 |
+
<a href="#courses" className="hover:text-blue-600 transition-colors">Курсы</a>
|
| 24 |
+
<a href="#mentor" className="hover:text-blue-600 transition-colors">AI Наставник</a>
|
| 25 |
+
</nav>
|
| 26 |
+
|
| 27 |
+
<div className="flex items-center gap-3">
|
| 28 |
+
<button className="hidden sm:block text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">Войти</button>
|
| 29 |
+
<button className="bg-slate-900 text-white text-sm px-5 py-2 rounded-full font-medium hover:bg-blue-600 transition-all shadow-lg shadow-blue-900/20">
|
| 30 |
+
Start
|
| 31 |
+
</button>
|
| 32 |
+
</div>
|
| 33 |
+
</div>
|
| 34 |
+
</div>
|
| 35 |
+
</header>
|
| 36 |
+
);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
export default Header;
|
src/components/Hero.tsx
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
const Hero: React.FC = () => {
|
| 4 |
+
return (
|
| 5 |
+
<section className="pt-32 pb-20 px-6 max-w-7xl mx-auto relative overflow-hidden">
|
| 6 |
+
<div className="grid lg:grid-cols-2 gap-16 items-center">
|
| 7 |
+
<div className="space-y-8 relative z-10">
|
| 8 |
+
<div className="flex items-center gap-2 text-slate-500 font-mono text-xs uppercase tracking-widest animate-in slide-in-from-left duration-700">
|
| 9 |
+
<span className="w-8 h-[1px] bg-blue-600"></span>
|
| 10 |
+
Next Gen Education
|
| 11 |
+
</div>
|
| 12 |
+
|
| 13 |
+
<h1 className="text-6xl lg:text-7xl font-extrabold tracking-tight text-slate-900 leading-[1.05] animate-in slide-in-from-left duration-700 delay-100">
|
| 14 |
+
Искусственный интеллект <br />
|
| 15 |
+
<span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 via-indigo-600 to-purple-600">на практике</span>
|
| 16 |
+
</h1>
|
| 17 |
+
|
| 18 |
+
<p className="text-xl text-slate-600 max-w-lg leading-relaxed animate-in slide-in-from-left duration-700 delay-200">
|
| 19 |
+
Освойте LLM, Computer Vision и нейросети. Мы превращаем сложные теории в работающий код и реальные продукты.
|
| 20 |
+
</p>
|
| 21 |
+
|
| 22 |
+
<div className="flex flex-col sm:flex-row gap-4 animate-in slide-in-from-left duration-700 delay-300">
|
| 23 |
+
<button className="bg-slate-900 text-white px-8 py-4 rounded-lg font-medium hover:bg-blue-700 transition-colors flex items-center justify-center gap-3 group">
|
| 24 |
+
Начать обучение
|
| 25 |
+
<span className="font-mono text-xs text-slate-400 group-hover:text-white/80 transition-colors">-></span>
|
| 26 |
+
</button>
|
| 27 |
+
<button className="px-8 py-4 rounded-lg font-medium border border-slate-200 hover:border-slate-400 hover:bg-slate-50 transition-all flex items-center justify-center gap-2 text-slate-700">
|
| 28 |
+
<span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
|
| 29 |
+
Демо доступ
|
| 30 |
+
</button>
|
| 31 |
+
</div>
|
| 32 |
+
|
| 33 |
+
<div className="pt-8 border-t border-slate-100 grid grid-cols-3 gap-8 animate-in fade-in duration-1000 delay-500">
|
| 34 |
+
<div>
|
| 35 |
+
<div className="font-mono text-3xl font-bold text-slate-900">94%</div>
|
| 36 |
+
<div className="text-xs text-slate-500 mt-1">Трудоустройство</div>
|
| 37 |
+
</div>
|
| 38 |
+
<div>
|
| 39 |
+
<div className="font-mono text-3xl font-bold text-slate-900">24/7</div>
|
| 40 |
+
<div className="text-xs text-slate-500 mt-1">AI Менторство</div>
|
| 41 |
+
</div>
|
| 42 |
+
<div>
|
| 43 |
+
<div className="font-mono text-3xl font-bold text-slate-900">TOP 3</div>
|
| 44 |
+
<div className="text-xs text-slate-500 mt-1">В рейтинге EdTech</div>
|
| 45 |
+
</div>
|
| 46 |
+
</div>
|
| 47 |
+
</div>
|
| 48 |
+
|
| 49 |
+
<div className="relative animate-in zoom-in duration-1000 delay-200">
|
| 50 |
+
<div className="relative z-10 bg-white p-2 rounded-2xl shadow-2xl tech-border rotate-1 hover:rotate-0 transition-transform duration-500">
|
| 51 |
+
<div className="aspect-[4/3] overflow-hidden rounded-xl relative bg-slate-900">
|
| 52 |
+
<img
|
| 53 |
+
src="https://picsum.photos/seed/techlab/1000/800"
|
| 54 |
+
alt="AI Laboratory"
|
| 55 |
+
className="w-full h-full object-cover opacity-80 hover:scale-105 transition-transform duration-1000"
|
| 56 |
+
/>
|
| 57 |
+
<div className="absolute inset-0 bg-gradient-to-t from-slate-900/90 to-transparent"></div>
|
| 58 |
+
|
| 59 |
+
{/* Code Overlay */}
|
| 60 |
+
<div className="absolute bottom-0 left-0 right-0 p-6 font-mono text-xs leading-relaxed text-blue-200/80 backdrop-blur-sm bg-slate-900/50 border-t border-white/10">
|
| 61 |
+
<div className="flex gap-2 mb-2">
|
| 62 |
+
<span className="w-3 h-3 rounded-full bg-red-500"></span>
|
| 63 |
+
<span className="w-3 h-3 rounded-full bg-yellow-500"></span>
|
| 64 |
+
<span className="w-3 h-3 rounded-full bg-green-500"></span>
|
| 65 |
+
</div>
|
| 66 |
+
<p><span className="text-purple-400">const</span> <span className="text-blue-300">future</span> = <span className="text-yellow-300">await</span> neural.train({'{'});</p>
|
| 67 |
+
<p className="pl-4">model: <span className="text-green-300">'Gemini-Pro'</span>,</p>
|
| 68 |
+
<p className="pl-4">skills: [<span className="text-green-300">'Vision'</span>, <span className="text-green-300">'NLP'</span>]</p>
|
| 69 |
+
<p>{'}'});</p>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
{/* Decorative Elements */}
|
| 75 |
+
<div className="absolute top-10 -right-10 w-24 h-24 bg-blue-500 rounded-full blur-[60px] opacity-20"></div>
|
| 76 |
+
<div className="absolute -bottom-10 -left-10 w-32 h-32 bg-purple-500 rounded-full blur-[60px] opacity-20"></div>
|
| 77 |
+
</div>
|
| 78 |
+
</div>
|
| 79 |
+
</section>
|
| 80 |
+
);
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
export default Hero;
|
src/index.css
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
body {
|
| 2 |
-
margin: 0;
|
| 3 |
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
| 4 |
-
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
| 5 |
-
sans-serif;
|
| 6 |
-
-webkit-font-smoothing: antialiased;
|
| 7 |
-
-moz-osx-font-smoothing: grayscale;
|
| 8 |
-
}
|
| 9 |
-
|
| 10 |
-
code {
|
| 11 |
-
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
| 12 |
-
monospace;
|
| 13 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/{index.js → index.tsx}
RENAMED
|
@@ -1,17 +1,15 @@
|
|
| 1 |
import React from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
| 3 |
-
import './index.css';
|
| 4 |
import App from './App';
|
| 5 |
-
import reportWebVitals from './reportWebVitals';
|
| 6 |
|
| 7 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
root.render(
|
| 9 |
<React.StrictMode>
|
| 10 |
<App />
|
| 11 |
</React.StrictMode>
|
| 12 |
);
|
| 13 |
-
|
| 14 |
-
// If you want to start measuring performance in your app, pass a function
|
| 15 |
-
// to log results (for example: reportWebVitals(console.log))
|
| 16 |
-
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
| 17 |
-
reportWebVitals();
|
|
|
|
| 1 |
import React from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
|
|
|
| 3 |
import App from './App';
|
|
|
|
| 4 |
|
| 5 |
+
const rootElement = document.getElementById('root');
|
| 6 |
+
if (!rootElement) {
|
| 7 |
+
throw new Error("Could not find root element to mount to");
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
const root = ReactDOM.createRoot(rootElement);
|
| 11 |
root.render(
|
| 12 |
<React.StrictMode>
|
| 13 |
<App />
|
| 14 |
</React.StrictMode>
|
| 15 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/logo.svg
DELETED
src/reportWebVitals.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
const reportWebVitals = onPerfEntry => {
|
| 2 |
-
if (onPerfEntry && onPerfEntry instanceof Function) {
|
| 3 |
-
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
| 4 |
-
getCLS(onPerfEntry);
|
| 5 |
-
getFID(onPerfEntry);
|
| 6 |
-
getFCP(onPerfEntry);
|
| 7 |
-
getLCP(onPerfEntry);
|
| 8 |
-
getTTFB(onPerfEntry);
|
| 9 |
-
});
|
| 10 |
-
}
|
| 11 |
-
};
|
| 12 |
-
|
| 13 |
-
export default reportWebVitals;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/setupTests.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
| 2 |
-
// allows you to do things like:
|
| 3 |
-
// expect(element).toHaveTextContent(/react/i)
|
| 4 |
-
// learn more: https://github.com/testing-library/jest-dom
|
| 5 |
-
import '@testing-library/jest-dom';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/types.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
export interface Course {
|
| 4 |
+
id: string;
|
| 5 |
+
title: string;
|
| 6 |
+
description: string;
|
| 7 |
+
level: 'Beginner' | 'Intermediate' | 'Advanced';
|
| 8 |
+
duration: string;
|
| 9 |
+
icon: string;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
export interface Feature {
|
| 13 |
+
title: string;
|
| 14 |
+
description: string;
|
| 15 |
+
icon: React.ReactNode;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
export interface ChatMessage {
|
| 19 |
+
role: 'user' | 'model';
|
| 20 |
+
text: string;
|
| 21 |
+
}
|
tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"target": "ES2022",
|
| 4 |
+
"experimentalDecorators": true,
|
| 5 |
+
"useDefineForClassFields": false,
|
| 6 |
+
"module": "ESNext",
|
| 7 |
+
"lib": [
|
| 8 |
+
"ES2022",
|
| 9 |
+
"DOM",
|
| 10 |
+
"DOM.Iterable"
|
| 11 |
+
],
|
| 12 |
+
"skipLibCheck": true,
|
| 13 |
+
"types": [
|
| 14 |
+
"node"
|
| 15 |
+
],
|
| 16 |
+
"moduleResolution": "bundler",
|
| 17 |
+
"isolatedModules": true,
|
| 18 |
+
"moduleDetection": "force",
|
| 19 |
+
"allowJs": true,
|
| 20 |
+
"jsx": "react-jsx",
|
| 21 |
+
"paths": {
|
| 22 |
+
"@/*": [
|
| 23 |
+
"./*"
|
| 24 |
+
]
|
| 25 |
+
},
|
| 26 |
+
"allowImportingTsExtensions": true,
|
| 27 |
+
"noEmit": true
|
| 28 |
+
}
|
| 29 |
+
}
|
vite.config.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import path from 'path';
|
| 2 |
+
import { defineConfig, loadEnv } from 'vite';
|
| 3 |
+
import react from '@vitejs/plugin-react';
|
| 4 |
+
|
| 5 |
+
export default defineConfig(({ mode }) => {
|
| 6 |
+
const env = loadEnv(mode, '.', '');
|
| 7 |
+
return {
|
| 8 |
+
server: {
|
| 9 |
+
port: 3000,
|
| 10 |
+
host: '0.0.0.0',
|
| 11 |
+
},
|
| 12 |
+
plugins: [react()],
|
| 13 |
+
define: {
|
| 14 |
+
'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
| 15 |
+
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
|
| 16 |
+
},
|
| 17 |
+
resolve: {
|
| 18 |
+
alias: {
|
| 19 |
+
'@': path.resolve(__dirname, '.'),
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
};
|
| 23 |
+
});
|