Добавить пререндер, партнёров, реквизиты, SEO-улучшения
- SSR-пререндер через Vite + react-dom/server (entry-server.jsx, scripts/prerender.mjs) - Секция партнёров: RU-CENTER, REG.RU, МТВ, КОНТУР - Реквизиты компании в футере (ИНН, ОГРН, банк) - Копирайт с 2011 года - Логотип увеличен (h-8→h-12 навбар, h-7→h-10 футер) - favicon.ico пересобран с 16×16, 32×32, 48×48 из logo.png - og:image и twitter:image переключены на .png - apple-touch-icon.png и og-image.png сгенерированы через sharp - SSR-safe: localStorage и window.location проверяются на typeof Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ function LangSync() {
|
||||
}
|
||||
|
||||
function Router() {
|
||||
const [path, setPath] = useState(window.location.pathname)
|
||||
const [path, setPath] = useState(typeof window !== 'undefined' ? window.location.pathname : '/')
|
||||
useEffect(() => {
|
||||
const handler = () => setPath(window.location.pathname)
|
||||
window.addEventListener('popstate', handler)
|
||||
|
||||
@@ -3,13 +3,14 @@ import { useLanguage } from '../contexts/LanguageContext.jsx'
|
||||
|
||||
export default function Footer() {
|
||||
const { t } = useLanguage()
|
||||
const year = new Date().getFullYear()
|
||||
const year = `2011 – ${new Date().getFullYear()}`
|
||||
const phones = t('contact.phones')
|
||||
|
||||
return (
|
||||
<footer className="bg-slate-900 text-slate-400 py-10">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-7 w-auto brightness-0 invert" />
|
||||
<footer className="bg-slate-900 text-slate-400">
|
||||
{/* Main footer row */}
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-10 flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-10 w-auto brightness-0 invert" />
|
||||
<span className="text-sm">{year} © {t('footer.rights')}</span>
|
||||
<div className="flex flex-wrap justify-center gap-x-6 gap-y-1 text-sm">
|
||||
{phones.map((p, i) => (
|
||||
@@ -18,6 +19,15 @@ export default function Footer() {
|
||||
<a href="mailto:info@sag24.ru" className="hover:text-white transition-colors">info@sag24.ru</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Legal details */}
|
||||
<div className="border-t border-slate-800">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-6 text-xs text-slate-600 leading-relaxed">
|
||||
<p className="mb-1">ООО «Сисадмингрупп» · ИНН 5038080741 · КПП 503801001 · ОГРН 1115038000890</p>
|
||||
<p className="mb-1">Юридический адрес: 141207, Россия, Московская область, г. Пушкино, пр-кт Московский, д. 38/14, кв. 33</p>
|
||||
<p>Р/с 40702810510000179731 · АО «ТБанк» · БИК 044525974 · К/с 30101810145250000974</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export default function Navigation() {
|
||||
<header className="fixed top-0 left-0 right-0 z-50 bg-white shadow-sm">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 h-16 flex items-center justify-between">
|
||||
<a href="#" className="flex items-center">
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-8 w-auto" />
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-12 w-auto" />
|
||||
</a>
|
||||
|
||||
{/* Desktop nav */}
|
||||
|
||||
@@ -7,13 +7,13 @@ const LanguageContext = createContext(null)
|
||||
|
||||
export function LanguageProvider({ children }) {
|
||||
const [lang, setLang] = useState(() => {
|
||||
return localStorage.getItem('lang') || 'ru'
|
||||
return (typeof localStorage !== 'undefined' && localStorage.getItem('lang')) || 'ru'
|
||||
})
|
||||
|
||||
const toggle = () => {
|
||||
const next = lang === 'ru' ? 'en' : 'ru'
|
||||
setLang(next)
|
||||
localStorage.setItem('lang', next)
|
||||
if (typeof localStorage !== 'undefined') localStorage.setItem('lang', next)
|
||||
}
|
||||
|
||||
const t = (key) => {
|
||||
|
||||
7
src/entry-server.jsx
Normal file
7
src/entry-server.jsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from 'react'
|
||||
import { renderToString } from 'react-dom/server'
|
||||
import App from './App.jsx'
|
||||
|
||||
export function render() {
|
||||
return renderToString(<App />)
|
||||
}
|
||||
@@ -109,6 +109,29 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Partners */}
|
||||
<section className="py-16 bg-slate-50 border-t border-slate-100">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6">
|
||||
<div className="text-center mb-10">
|
||||
<h2 className="text-2xl sm:text-3xl font-bold text-slate-900 mb-2">{t('partners.title')}</h2>
|
||||
<p className="text-slate-500">{t('partners.subtitle')}</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
{[
|
||||
{ name: 'RU-CENTER', sub: 'Руцентр' },
|
||||
{ name: 'REG.RU', sub: 'Регистратор доменов' },
|
||||
{ name: 'МТВ', sub: 'Телекоммуникации' },
|
||||
{ name: 'КОНТУР', sub: 'Электронная отчётность' },
|
||||
].map(p => (
|
||||
<div key={p.name} className="bg-white border border-slate-200 rounded-xl px-8 py-5 flex flex-col items-center gap-1 min-w-[160px] hover:border-blue-200 hover:shadow-sm transition-all duration-200">
|
||||
<span className="text-xl font-bold text-slate-800 tracking-tight">{p.name}</span>
|
||||
<span className="text-xs text-slate-400">{p.sub}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Contact */}
|
||||
<section id="contact" className="py-24 bg-slate-900">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6">
|
||||
|
||||
@@ -53,6 +53,10 @@ export const en = {
|
||||
formSubmit: 'Send Request',
|
||||
formSuccess: 'Request sent! We will contact you shortly.',
|
||||
},
|
||||
partners: {
|
||||
title: 'Partners',
|
||||
subtitle: 'We work with trusted suppliers and vendors',
|
||||
},
|
||||
footer: {
|
||||
rights: 'All rights reserved.',
|
||||
},
|
||||
|
||||
@@ -53,6 +53,10 @@ export const ru = {
|
||||
formSubmit: 'Отправить заявку',
|
||||
formSuccess: 'Заявка отправлена! Мы свяжемся с вами в ближайшее время.',
|
||||
},
|
||||
partners: {
|
||||
title: 'Партнёры',
|
||||
subtitle: 'Работаем с надёжными поставщиками и вендорами',
|
||||
},
|
||||
footer: {
|
||||
rights: 'Все права защищены.',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user