Initial commit: TopSysOps site + admin panel

Multi-page public site (Next.js), Node/Express backend with Postgres,
and Vite admin/account app, restructured from a single-page layout
into dedicated service, promotions, cases, about, FAQ, and blog pages
for SEO.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013otXCiTZsxdZ4SJKZ9wUky
This commit is contained in:
ogrechkoandClaude Sonnet 5 committed 2026-08-25 23:12:16 +03:00
commit 130c5382cd
108 files changed
+7146

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
import './globals.css';
import { ThemeProvider } from '../components/ThemeProvider.jsx';
import SupportChat from '../components/SupportChat.jsx';
import VisitTracker from '../components/VisitTracker.jsx';
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://top-sysops.ru';
export const metadata = {
metadataBase: new URL(SITE_URL),
title: {
default: 'TopSysOps — IT-аутсорсинг и автоматизация',
template: '%s | TopSysOps',
},
description:
'Профессиональный IT-аутсорсинг: техподдержка, кибербезопасность, администрирование БД, сетевая инфраструктура, ИИ и автоматизация.',
};
// Выставляет класс "dark" на <html> ДО гидратации React, чтобы не было
// мигания светлой темы при заходе пользователя с сохранённой тёмной темой.
const NO_FLASH_SCRIPT = `
(function () {
try {
var theme = localStorage.getItem('ts-theme');
var dark = theme ? theme === 'dark' : window.matchMedia('(prefers-color-scheme: dark)').matches;
if (dark) document.documentElement.classList.add('dark');
} catch (e) {}
})();
`;
export default function RootLayout({ children }) {
return (
<html lang="ru">
<head>
{/* eslint-disable-next-line react/no-danger */}
<script dangerouslySetInnerHTML={{ __html: NO_FLASH_SCRIPT }} />
</head>
<body className="bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100">
<ThemeProvider>{children}</ThemeProvider>
<SupportChat />
<VisitTracker />
</body>
</html>
);
}