home page #1
@@ -8,7 +8,7 @@ interface ProtectedRouteProps {
|
||||
|
||||
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
|
||||
children,
|
||||
fallbackPath = "/",
|
||||
fallbackPath = "/auth",
|
||||
}) => {
|
||||
const isAuthenticated = authService.isAuthenticated();
|
||||
|
||||
|
||||
@@ -17,16 +17,13 @@ export const Routing = () => {
|
||||
}
|
||||
>
|
||||
<ReactRoutes>
|
||||
<Route path="/" element={<AuthPage />} />
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/auth" element={<AuthPage />} />
|
||||
<Route
|
||||
path="/create-organization"
|
||||
element={<CreateOrganizationPage />}
|
||||
/>
|
||||
<Route
|
||||
path="/home"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<HomePage />
|
||||
<CreateOrganizationPage />
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,6 @@ import type {
|
||||
LoginCredentials,
|
||||
RegisterData,
|
||||
OrganizationCreateData,
|
||||
OrganizationMember,
|
||||
} from "../types/auth.types";
|
||||
|
||||
export const useAuth = () => {
|
||||
@@ -24,7 +23,7 @@ export const useAuth = () => {
|
||||
const orgs = await request(() => authService.getOrganizations());
|
||||
if (orgs && orgs.length > 0) {
|
||||
authService.saveOrganization(orgs[0]);
|
||||
navigate("/home");
|
||||
navigate("/");
|
||||
} else {
|
||||
navigate("/create-organization");
|
||||
}
|
||||
@@ -58,7 +57,7 @@ export const useAuth = () => {
|
||||
|
||||
if (result) {
|
||||
authService.saveOrganization(result);
|
||||
navigate("/home");
|
||||
navigate("/");
|
||||
} else if (error) {
|
||||
setAuthError(error);
|
||||
}
|
||||
|
||||
+15
-2
@@ -1,17 +1,30 @@
|
||||
import { useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { ThemeToggle } from "@/modules/theme-changer/ui/Theme.toggle";
|
||||
import { LoginForm } from "@/modules/auth/components/LoginForm";
|
||||
import { RegisterForm } from "@/modules/auth/components/RegisterForm";
|
||||
|
||||
export const AuthPage = () => {
|
||||
const [isLogin, setIsLogin] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div
|
||||
className="min-h-screen flex items-center justify-center p-4 transition-theme"
|
||||
style={{ backgroundColor: "var(--bg-primary)" }}
|
||||
>
|
||||
<div className="absolute top-4 right-4">
|
||||
<div className="absolute top-4 right-4 flex gap-4">
|
||||
<button
|
||||
onClick={() => navigate("/")}
|
||||
className="px-4 py-2 rounded-lg font-medium transition-all hover:scale-105"
|
||||
style={{
|
||||
backgroundColor: "var(--bg-secondary)",
|
||||
color: "var(--text-primary)",
|
||||
border: `1px solid var(--border)`,
|
||||
}}
|
||||
>
|
||||
На главную
|
||||
</button>
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
|
||||
|
||||
+197
-12
@@ -6,7 +6,6 @@ import {
|
||||
Shield,
|
||||
Users,
|
||||
Bot,
|
||||
Settings,
|
||||
Activity,
|
||||
LogOut,
|
||||
ChevronRight,
|
||||
@@ -20,11 +19,14 @@ import {
|
||||
AlertCircle,
|
||||
CheckCircle,
|
||||
Clock,
|
||||
LogIn,
|
||||
UserPlus,
|
||||
} from "lucide-react";
|
||||
|
||||
export const HomePage = () => {
|
||||
const navigate = useNavigate();
|
||||
const { logout } = useAuth();
|
||||
const isAuthenticated = authService.isAuthenticated();
|
||||
const organization = authService.getCurrentOrganization();
|
||||
const authStorage = localStorage.getItem("auth-storage");
|
||||
const user = authStorage ? JSON.parse(authStorage).state?.user : null;
|
||||
@@ -72,7 +74,35 @@ export const HomePage = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const quickActions = [
|
||||
const features = [
|
||||
{
|
||||
title: "Централизованное управление",
|
||||
description: "Управляйте всеми IPS агентами из единого интерфейса",
|
||||
icon: Server,
|
||||
color: "#6366f1",
|
||||
},
|
||||
{
|
||||
title: "AI Аналитика",
|
||||
description: "Искусственный интеллект помогает находить сложные атаки",
|
||||
icon: Bot,
|
||||
color: "#8b5cf6",
|
||||
},
|
||||
{
|
||||
title: "Мгновенная блокировка",
|
||||
description: "Автоматическая блокировка IP при обнаружении угроз",
|
||||
icon: Zap,
|
||||
color: "#f59e0b",
|
||||
},
|
||||
{
|
||||
title: "Безопасность данных",
|
||||
description: "LLM не получает доступ к чувствительным логам",
|
||||
icon: Lock,
|
||||
color: "#22c55e",
|
||||
},
|
||||
];
|
||||
|
||||
const quickActions = isAuthenticated
|
||||
? [
|
||||
{
|
||||
name: "IPS Агенты",
|
||||
icon: Server,
|
||||
@@ -101,7 +131,8 @@ export const HomePage = () => {
|
||||
description: "Управление доступом",
|
||||
color: "#f59e0b",
|
||||
},
|
||||
];
|
||||
]
|
||||
: [];
|
||||
|
||||
const getSeverityStyles = (severity: string) => {
|
||||
switch (severity) {
|
||||
@@ -169,6 +200,8 @@ export const HomePage = () => {
|
||||
|
||||
{/* Right section */}
|
||||
<div className="flex items-center gap-4">
|
||||
{isAuthenticated ? (
|
||||
<>
|
||||
<button
|
||||
className="relative p-2 rounded-lg transition-all hover:scale-105"
|
||||
style={{ backgroundColor: "var(--bg-secondary)" }}
|
||||
@@ -198,7 +231,10 @@ export const HomePage = () => {
|
||||
>
|
||||
{user?.first_name} {user?.last_name}
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--text-muted)" }}>
|
||||
<p
|
||||
className="text-xs"
|
||||
style={{ color: "var(--text-muted)" }}
|
||||
>
|
||||
Администратор
|
||||
</p>
|
||||
</div>
|
||||
@@ -210,13 +246,42 @@ export const HomePage = () => {
|
||||
>
|
||||
<LogOut className="w-5 h-5 text-white" />
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ThemeToggle />
|
||||
<button
|
||||
onClick={() => navigate("/auth")}
|
||||
className="px-4 py-2 rounded-lg font-medium transition-all flex items-center gap-2 hover:scale-105"
|
||||
style={{
|
||||
backgroundColor: "var(--bg-secondary)",
|
||||
color: "var(--text-primary)",
|
||||
border: `1px solid var(--border)`,
|
||||
}}
|
||||
>
|
||||
<LogIn className="w-4 h-4" />
|
||||
Войти
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate("/auth")}
|
||||
className="px-4 py-2 rounded-lg font-medium transition-all flex items-center gap-2 hover:scale-105"
|
||||
style={{
|
||||
backgroundColor: "var(--accent)",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<UserPlus className="w-4 h-4" />
|
||||
Регистрация
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="container mx-auto px-6 py-8">
|
||||
{/* Welcome Section */}
|
||||
{/* Hero Section */}
|
||||
<div
|
||||
className="rounded-2xl p-8 mb-8 text-white relative overflow-hidden"
|
||||
style={{
|
||||
@@ -227,17 +292,36 @@ export const HomePage = () => {
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold mb-2">
|
||||
Добро пожаловать, {user?.first_name || "Администратор"}!
|
||||
{isAuthenticated
|
||||
? `Добро пожаловать, ${user?.first_name || "Администратор"}!`
|
||||
: "Добро пожаловать в IPS Manager"}
|
||||
</h2>
|
||||
<p className="text-white/80 text-lg">
|
||||
Система IPS мониторинга и защиты
|
||||
{isAuthenticated
|
||||
? "Система IPS мониторинга и защиты"
|
||||
: "Современная платформа для централизованного управления IPS агентами"}
|
||||
</p>
|
||||
{!isAuthenticated && (
|
||||
<div className="flex gap-4 mt-6">
|
||||
<button
|
||||
onClick={() => navigate("/auth")}
|
||||
className="px-6 py-2 rounded-lg font-medium bg-white text-indigo-600 transition-all hover:scale-105 hover:shadow-lg"
|
||||
>
|
||||
Начать работу
|
||||
</button>
|
||||
<button className="px-6 py-2 rounded-lg font-medium border border-white/30 transition-all hover:bg-white/10">
|
||||
Узнать больше
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{isAuthenticated && (
|
||||
<div className="flex items-center gap-2 mt-4">
|
||||
<Zap className="w-5 h-5" />
|
||||
<span className="text-white/90">
|
||||
Все системы работают стабильно
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="hidden lg:block opacity-20">
|
||||
<Cloud className="w-32 h-32" />
|
||||
@@ -246,7 +330,8 @@ export const HomePage = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
{/* Stats Grid - только для авторизованных */}
|
||||
{isAuthenticated && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
{stats.map((stat, index) => {
|
||||
const Icon = stat.icon;
|
||||
@@ -303,7 +388,62 @@ export const HomePage = () => {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Features Section - для всех */}
|
||||
<div className="mb-8">
|
||||
<div className="text-center mb-8">
|
||||
<h2
|
||||
className="text-2xl font-bold mb-2"
|
||||
style={{ color: "var(--text-primary)" }}
|
||||
>
|
||||
Ключевые возможности
|
||||
</h2>
|
||||
<p className="text-sm" style={{ color: "var(--text-secondary)" }}>
|
||||
Всё необходимое для защиты вашей инфраструктуры
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{features.map((feature, index) => {
|
||||
const Icon = feature.icon;
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="rounded-2xl p-6 transition-all hover:scale-105 hover:shadow-xl text-center"
|
||||
style={{
|
||||
backgroundColor: "var(--card-bg)",
|
||||
boxShadow: `0 4px 6px -1px var(--shadow-color)`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 rounded-xl flex items-center justify-center mx-auto mb-4"
|
||||
style={{ backgroundColor: `${feature.color}20` }}
|
||||
>
|
||||
<Icon
|
||||
className="w-7 h-7"
|
||||
style={{ color: feature.color }}
|
||||
/>
|
||||
</div>
|
||||
<h3
|
||||
className="font-bold mb-2"
|
||||
style={{ color: "var(--text-primary)" }}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p
|
||||
className="text-sm"
|
||||
style={{ color: "var(--text-secondary)" }}
|
||||
>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isAuthenticated ? (
|
||||
<>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Quick Actions */}
|
||||
<div className="lg:col-span-2">
|
||||
@@ -497,8 +637,12 @@ export const HomePage = () => {
|
||||
>
|
||||
🔍 Обнаружена аномалия
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--text-secondary)" }}>
|
||||
Повышенная активность с IP-адресов из диапазона 185.xxx.xx.xx
|
||||
<p
|
||||
className="text-xs"
|
||||
style={{ color: "var(--text-secondary)" }}
|
||||
>
|
||||
Повышенная активность с IP-адресов из диапазона
|
||||
185.xxx.xx.xx
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -511,7 +655,10 @@ export const HomePage = () => {
|
||||
>
|
||||
💡 Предложено правил
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--text-secondary)" }}>
|
||||
<p
|
||||
className="text-xs"
|
||||
style={{ color: "var(--text-secondary)" }}
|
||||
>
|
||||
AI предлагает 3 новых правила для блокировки бот-сканеров
|
||||
</p>
|
||||
</div>
|
||||
@@ -525,13 +672,51 @@ export const HomePage = () => {
|
||||
>
|
||||
⚡ Оптимизация
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--text-secondary)" }}>
|
||||
<p
|
||||
className="text-xs"
|
||||
style={{ color: "var(--text-secondary)" }}
|
||||
>
|
||||
Рекомендуется обновить 5 существующих правил для повышения
|
||||
эффективности
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
/* CTA Section для неавторизованных */
|
||||
<div
|
||||
className="rounded-2xl p-8 text-center"
|
||||
style={{
|
||||
backgroundColor: "var(--card-bg)",
|
||||
boxShadow: `0 4px 6px -1px var(--shadow-color)`,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
className="text-2xl font-bold mb-2"
|
||||
style={{ color: "var(--text-primary)" }}
|
||||
>
|
||||
Готовы начать?
|
||||
</h3>
|
||||
<p
|
||||
className="text-sm mb-6"
|
||||
style={{ color: "var(--text-secondary)" }}
|
||||
>
|
||||
Присоединяйтесь к IPS Manager и получите полный контроль над
|
||||
безопасностью
|
||||
</p>
|
||||
<button
|
||||
onClick={() => navigate("/auth")}
|
||||
className="px-6 py-2 rounded-lg font-medium transition-all hover:scale-105"
|
||||
style={{
|
||||
backgroundColor: "var(--accent)",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Начать работу
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user