Добавлена полная документация для лендинга BROJS.RU, включая описание структуры проекта, SSG, пользовательского соглашения и команды для сборки. Реализована автоматическая генерация terms.html из terma.md. Обновлены зависимости и скрипты для сборки. Исправлены ошибки в конфигурации и добавлены новые страницы.
All checks were successful
platform/bro-js/bro.landing/pipeline/head This commit looks good

This commit is contained in:
Primakov Alexandr Alexandrovich
2025-10-24 11:04:15 +03:00
parent e91b861415
commit 9110e79d6b
13 changed files with 3427 additions and 3022 deletions

View File

@@ -1,21 +1,14 @@
import React, { Suspense } from 'react';
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import { Spinner } from '@chakra-ui/react';
import { UnderConstructionPage } from './pages';
import { UnderConstructionPage, TermsPage } from './pages';
export const Dashboard = () => {
return (
<Routes>
<Route
path={'*'}
element={
<Suspense fallback={<Spinner />}>
<UnderConstructionPage />
</Suspense>
}
/>
<Route path={'*'} element={<h1>Страница не найдена</h1>} />
<Route path="/terms" element={<TermsPage />} />
<Route path="/" element={<UnderConstructionPage />} />
<Route path="*" element={<h1>Страница не найдена</h1>} />
</Routes>
);
};

View File

@@ -1,7 +1,7 @@
import React from 'react';
import i18next from 'i18next';
import { i18nextReactInitConfig } from '@brojs/cli/lib/i18next';
import { createRoot } from 'react-dom/client'
import { i18nextReactInitConfig } from '@brojs/cli';
import { createRoot, hydrateRoot } from 'react-dom/client'
import App from './app';
@@ -11,14 +11,22 @@ const MOUNT_NODE = document.getElementById('app');
(async () => {
await Promise.all([i18nextPromise]);
const rootElement = createRoot(MOUNT_NODE)
rootElement.render(<App />);
if (module.hot) {
module.hot.accept('./app', async () => {
await i18next.reloadResources();
rootElement.render(<App />);
});
// Если страница была пре-рендерена, используем hydrate вместо render
const hasPrerenderedContent = MOUNT_NODE.hasChildNodes();
if (hasPrerenderedContent) {
hydrateRoot(MOUNT_NODE, <App />);
} else {
const rootElement = createRoot(MOUNT_NODE);
rootElement.render(<App />);
if (module.hot) {
module.hot.accept('./app', async () => {
await i18next.reloadResources();
rootElement.render(<App />);
});
}
}
})();

View File

@@ -1,3 +1,2 @@
import { lazy } from 'react';
export const UnderConstructionPage = lazy(() => import('./under-construction'));
export { default as UnderConstructionPage } from './under-construction';
export { Terms as TermsPage } from './terms';

291
src/pages/terms/Terms.tsx Normal file
View File

@@ -0,0 +1,291 @@
import React from 'react';
import { Box, Container, Heading, Text, VStack, Divider, Link } from '@chakra-ui/react';
import { Helmet } from 'react-helmet';
export const Terms = () => {
return (
<>
<Helmet>
<title>Пользовательское соглашение - BROJS.RU</title>
<meta name="description" content="Пользовательское соглашение для платформы обучения фронтенд-разработке BROJS.RU" />
</Helmet>
<Box bg="gray.50" minH="100vh" py={8}>
<Container maxW="4xl" bg="white" shadow="lg" borderRadius="md" p={{ base: 6, md: 10 }}>
<VStack spacing={6} align="stretch">
{/* Заголовок */}
<Box textAlign="center" mb={4}>
<Heading as="h1" size="2xl" mb={2} color="blue.600">
Пользовательское соглашение
</Heading>
<Text fontSize="sm" color="gray.600">
для BROJS.RU
</Text>
<Text fontSize="sm" color="gray.500" mt={2}>
Последнее обновление: 25 мая 2025 г.
</Text>
</Box>
<Divider />
{/* 1. Термины */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
1. Термины
</Heading>
<VStack spacing={2} align="stretch">
<Text><strong>Платформа</strong> сайт <Link href="https://brojs.ru" color="blue.500" isExternal>https://brojs.ru</Link>, предоставляющий услуги обучения фронтенд-разработке.</Text>
<Text><strong>Пользователь</strong> лицо, зарегистрированное на Платформе.</Text>
<Text><strong>Микрофронтенд-проект</strong> код, конфигурации и иные материалы, созданные Пользователем.</Text>
<Text><strong>Gravatar</strong> сторонний сервис (<Link href="https://gravatar.com" color="blue.500" isExternal>https://gravatar.com</Link>), предоставляющий аватары на основе email-адресов пользователей.</Text>
<Text><strong>Интеллектуальная собственность</strong> результаты интеллектуальной деятельности, включая, но не ограничиваясь, программные коды, дизайны, тексты, графику и другие объекты, защищенные законом.</Text>
</VStack>
</Box>
{/* 2. Условия использования */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
2. Условия использования
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
2.1. Регистрация
</Heading>
<Text mb={2}>Регистрация осуществляется через:</Text>
<Box as="ul" pl={6} mb={3}>
<li>Аккаунт Yandex;</li>
<li>Email (с подтверждением через ссылку).</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
2.2. Обязанности Пользователя
</Heading>
<Text mb={2}>Пользователь обязуется:</Text>
<Box as="ul" pl={6}>
<li>Не передавать учетные данные третьим лицам;</li>
<li>Не использовать Платформу для распространения незаконного контента или совершения мошеннических действий;</li>
<li>Соблюдать конфиденциальность личных данных других участников Платформы.</li>
</Box>
</Box>
{/* 3. Персональные данные */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
3. Персональные данные
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.1. Собираемые данные
</Heading>
<Text mb={2}>Платформа собирает:</Text>
<Box as="ul" pl={6} mb={3}>
<li>Никнейм;</li>
<li>Email;</li>
<li>ФИО (при наличии договора с учебным заведением);</li>
<li>Данные о посещении занятий (через QR-код).</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.2. Аватар через Gravatar
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Платформа не хранит аватары на своих серверах. Для отображения используется Gravatar.</li>
<li>Ссылка на аватар формируется на основе хэша email пользователя.</li>
<li>Пользователь может активировать/отозвать согласие на использование Gravatar в настройках профиля.</li>
<li>Отказ от Gravatar приведет к отображению стандартного изображения.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.3. Цели обработки данных
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Предоставление доступа к Платформе;</li>
<li>Передача данных о посещении учебным заведениям (ФИО, email, дата и время) в формате Excel.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.4. Хранение и передача данных
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Персональные данные хранятся в СУБД PostgreSQL через Keycloak.</li>
<li>Данные о посещении передаются учебным заведениям на основании договоров с преподавателями.</li>
<li>Передача данных осуществляется с применением шифрования и протоколов безопасности.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.5. Срок хранения
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Персональные данные удаляются в течение 30 дней после удаления аккаунта.</li>
<li>Микрофронтенд-проекты хранятся 6 месяцев после завершения обучения.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
3.6. Отзыв согласия
</Heading>
<Box as="ul" pl={6}>
<li>Для отзыва согласия на обработку персональных данных необходимо направить письмо на <Link href="mailto:primakov.pro@yandex.ru" color="blue.500">primakov.pro@yandex.ru</Link>.</li>
<li>Отзыв приведет к удалению всех данных пользователя вручную.</li>
<li>Частичное удаление отдельных категорий данных возможно по заявлению пользователя.</li>
</Box>
</Box>
{/* 4. Интеллектуальная собственность */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
4. Интеллектуальная собственность
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
4.1. Права Пользователя
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Пользователь сохраняет авторские права на созданные проекты.</li>
<li>Платформа не имеет прав на использование материалов Пользователя без явного согласия.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
4.2. Права Администрации
</Heading>
<Box as="ul" pl={6}>
<li>Администрация вправе удалить контент при нарушении условий соглашения или через 6 месяцев после завершения обучения.</li>
<li>Проверка подлинности загружаемого материала осуществляется преподавателем, отвечающим за группу.</li>
</Box>
</Box>
{/* 5. Ответственность */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
5. Ответственность
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
5.1. Ограничение ответственности
</Heading>
<Text mb={2}>Администрация не несет ответственности за:</Text>
<Box as="ul" pl={6} mb={3}>
<li>Утрату данных из-за действий Пользователя;</li>
<li>Использование данных учебными заведениями после их передачи;</li>
<li>Некорректное отображение аватаров через Gravatar.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
5.2. Основания для блокировки аккаунта
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Нарушение авторских прав;</li>
<li>Распространение спама/вирусов;</li>
<li>Предоставление недостоверных данных (включая ФИО).</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
5.3. Компенсация ущерба
</Heading>
<Box as="ul" pl={6}>
<li>В случае нарушения правил или утечки данных, Администрация обязана принять меры для минимизации последствий.</li>
</Box>
</Box>
{/* 6. Уведомления */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
6. Уведомления
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
6.1. Информационные сообщения
</Heading>
<Text mb={2}>Платформа вправе отправлять Пользователю:</Text>
<Box as="ul" pl={6} mb={3}>
<li>Уведомления о технических работах, изменениях функционала;</li>
<li>Сообщения о нарушениях или блокировке аккаунта;</li>
<li>Рекламу собственных услуг или услуг третьих лиц.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
6.2. Отказ от уведомлений
</Heading>
<Box as="ul" pl={6}>
<li>Отказ от рекламных сообщений возможен через настройки Личного кабинета.</li>
<li>Отказ от информационных уведомлений может ограничить доступ к функциям Платформы.</li>
</Box>
</Box>
{/* 7. Безопасность данных */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
7. Безопасность данных
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
7.1. Технические меры
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Данные хранятся в СУБД PostgreSQL через Keycloak.</li>
<li>Шифрование данных при передаче (HTTPS).</li>
<li>Периодические тестирования системы на уязвимости.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
7.2. Двухфакторная аутентификация
</Heading>
<Box as="ul" pl={6}>
<li>Пользователи могут добровольно активировать двухфакторную аутентификацию (OTP) через Личный кабинет.</li>
</Box>
</Box>
{/* 8. Применимое право и разрешение споров */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
8. Применимое право и разрешение споров
</Heading>
<Heading as="h3" size="md" mb={2} color="gray.700">
8.1. Применимое право
</Heading>
<Box as="ul" pl={6} mb={3}>
<li>Соглашение регулируется законодательством РФ. Для пользователей из стран СНГ применяются нормы ЕАЭС.</li>
<li>При расширении географии услуг Платформа будет соблюдать законодательство стран ЕСВР и ЕС.</li>
</Box>
<Heading as="h3" size="md" mb={2} color="gray.700">
8.2. Разрешение споров
</Heading>
<Box as="ul" pl={6}>
<li>Споры разрешаются в суде по месту нахождения администрации Платформы.</li>
</Box>
</Box>
{/* 9. Изменения соглашения */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
9. Изменения соглашения
</Heading>
<Text>Изменения вступают в силу после публикации на сайте.</Text>
</Box>
{/* 10. Контакты */}
<Box>
<Heading as="h2" size="lg" mb={3} color="gray.800">
10. Контакты
</Heading>
<Text>
Для обращений: <Link href="mailto:primakov.pro@yandex.ru" color="blue.500">primakov.pro@yandex.ru</Link>
</Text>
</Box>
<Divider mt={6} />
{/* Footer */}
<Box textAlign="center" pt={4}>
<Text fontSize="sm" color="gray.500">
© 2025 BROJS.RU. Все права защищены.
</Text>
</Box>
</VStack>
</Container>
</Box>
</>
);
};

2
src/pages/terms/index.ts Normal file
View File

@@ -0,0 +1,2 @@
export { Terms } from './Terms';