Комплексные улучшения: FAQ, форма, карта, WhatsApp/Telegram, SEO
- FloatingContacts: кнопки WhatsApp + Telegram (правый нижний угол) - ScrollToTop: кнопка "наверх" (появляется после 400px скролла) - FAQ секция: 6 вопросов с аккордеоном, id=faq в навбаре - Hero: телефон под CTA кнопками - Форма: поле телефона, реальная отправка (fetch FormSpree или mailto fallback) - Яндекс.Карты embed в блоке контактов - Navigation: убран дубль "Контакты" из links, добавлен FAQ - img width/height на логотипах (антиCLS) - JSON-LD: og-image.svg → .png, добавлен postalCode, уточнен streetAddress - prerender.mjs: динамически обновляет хеш preload шрифта - src/config.js: централизованный конфиг (WhatsApp, Telegram, form endpoint) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,14 +56,15 @@
|
||||
"description": "IT-аутсорсинг, кибербезопасность и техническая поддержка для бизнеса в Пушкино и Московской области.",
|
||||
"url": "https://sag24.ru",
|
||||
"logo": "https://sag24.ru/logo.png",
|
||||
"image": "https://sag24.ru/og-image.svg",
|
||||
"image": "https://sag24.ru/og-image.png",
|
||||
"telephone": ["+74953637476", "+74953637335", "+74959454456"],
|
||||
"email": "info@sag24.ru",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "д. 38/14",
|
||||
"streetAddress": "пр-кт Московский, д. 38/14",
|
||||
"addressLocality": "Пушкино",
|
||||
"addressRegion": "Московская область",
|
||||
"postalCode": "141207",
|
||||
"addressCountry": "RU"
|
||||
},
|
||||
"geo": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { readFileSync, writeFileSync, rmSync } from 'fs'
|
||||
import { readFileSync, writeFileSync, rmSync, readdirSync } from 'fs'
|
||||
import { resolve, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
@@ -8,9 +8,23 @@ const root = resolve(__dirname, '..')
|
||||
// Import SSR bundle built by vite build --ssr
|
||||
const { render } = await import('../dist/server/entry-server.js')
|
||||
|
||||
const template = readFileSync(resolve(root, 'dist/index.html'), 'utf-8')
|
||||
let html = readFileSync(resolve(root, 'dist/index.html'), 'utf-8')
|
||||
|
||||
// Inject prerendered HTML
|
||||
const appHtml = render()
|
||||
const html = template.replace('<div id="root"></div>', `<div id="root">${appHtml}</div>`)
|
||||
html = html.replace('<div id="root"></div>', `<div id="root">${appHtml}</div>`)
|
||||
|
||||
// Fix preload font: find actual cyrillic-700 woff2 hash in dist/assets
|
||||
const assetsDir = resolve(root, 'dist/assets')
|
||||
const fontFile = readdirSync(assetsDir).find(f => f.match(/manrope-cyrillic-700-normal-.+\.woff2/))
|
||||
if (fontFile) {
|
||||
html = html.replace(
|
||||
/href="\/assets\/manrope-cyrillic-700-normal-[^"]+\.woff2"/,
|
||||
`href="/assets/${fontFile}"`
|
||||
)
|
||||
console.log(`✓ Preload font updated: ${fontFile}`)
|
||||
}
|
||||
|
||||
writeFileSync(resolve(root, 'dist/index.html'), html)
|
||||
|
||||
// Cleanup SSR bundle
|
||||
|
||||
@@ -4,6 +4,8 @@ import Navigation from './components/Navigation.jsx'
|
||||
import Footer from './components/Footer.jsx'
|
||||
import Home from './pages/Home.jsx'
|
||||
import NotFound from './pages/NotFound.jsx'
|
||||
import FloatingContacts from './components/FloatingContacts.jsx'
|
||||
import ScrollToTop from './components/ScrollToTop.jsx'
|
||||
|
||||
function LangSync() {
|
||||
const { lang } = useLanguage()
|
||||
@@ -34,6 +36,8 @@ export default function App() {
|
||||
<Router />
|
||||
</main>
|
||||
<Footer />
|
||||
<FloatingContacts />
|
||||
<ScrollToTop />
|
||||
</LanguageProvider>
|
||||
)
|
||||
}
|
||||
|
||||
33
src/components/FloatingContacts.jsx
Normal file
33
src/components/FloatingContacts.jsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from 'react'
|
||||
import { WHATSAPP_PHONE, TELEGRAM_USERNAME } from '../config.js'
|
||||
|
||||
export default function FloatingContacts() {
|
||||
return (
|
||||
<div className="fixed bottom-6 right-6 z-50 flex flex-col gap-3">
|
||||
<a
|
||||
href={`https://t.me/${TELEGRAM_USERNAME}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Написать в Telegram"
|
||||
className="w-12 h-12 rounded-full flex items-center justify-center shadow-lg transition-transform hover:scale-110"
|
||||
style={{ background: '#2AABEE' }}
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="white">
|
||||
<path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm4.93 6.77-1.9 8.96c-.14.62-.5.77-.99.48l-2.76-2.03-1.33 1.28c-.15.15-.27.27-.55.27l.2-2.82 5.1-4.61c.22-.2-.05-.31-.34-.11l-6.31 3.97-2.72-.85c-.59-.18-.6-.59.12-.87l10.63-4.1c.49-.18.93.12.75.83z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href={`https://wa.me/${WHATSAPP_PHONE}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Написать в WhatsApp"
|
||||
className="w-12 h-12 rounded-full flex items-center justify-center shadow-lg transition-transform hover:scale-110"
|
||||
style={{ background: '#25D366' }}
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="white">
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -10,7 +10,7 @@ export default function Footer() {
|
||||
<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" />
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-10 w-auto brightness-0 invert" width="40" height="40" />
|
||||
<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) => (
|
||||
|
||||
@@ -9,14 +9,14 @@ export default function Navigation() {
|
||||
const links = [
|
||||
{ label: t('nav.services'), href: '#services' },
|
||||
{ label: t('nav.about'), href: '#about' },
|
||||
{ label: t('nav.contact'), href: '#contact' },
|
||||
{ label: t('nav.faq'), href: '#faq' },
|
||||
]
|
||||
|
||||
return (
|
||||
<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-12 w-auto" />
|
||||
<img src="/logo.png" alt="Сисадмингрупп" className="h-12 w-auto" width="48" height="48" />
|
||||
</a>
|
||||
|
||||
{/* Desktop nav */}
|
||||
|
||||
24
src/components/ScrollToTop.jsx
Normal file
24
src/components/ScrollToTop.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { ChevronUp } from 'lucide-react'
|
||||
|
||||
export default function ScrollToTop() {
|
||||
const [visible, setVisible] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const onScroll = () => setVisible(window.scrollY > 400)
|
||||
window.addEventListener('scroll', onScroll, { passive: true })
|
||||
return () => window.removeEventListener('scroll', onScroll)
|
||||
}, [])
|
||||
|
||||
if (!visible) return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
|
||||
aria-label="Наверх"
|
||||
className="fixed bottom-6 left-6 z-50 w-10 h-10 rounded-full bg-slate-800/80 hover:bg-slate-700 text-white flex items-center justify-center shadow-lg transition-all hover:scale-110"
|
||||
>
|
||||
<ChevronUp size={20} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
5
src/config.js
Normal file
5
src/config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// Настройки для связи и формы
|
||||
export const WHATSAPP_PHONE = '74953637476' // без +
|
||||
export const TELEGRAM_USERNAME = 'sag24ru' // @username без @
|
||||
export const FORM_ENDPOINT = '' // https://formspree.io/f/XXXXXXX — оставить пустым, будет mailto:
|
||||
export const EMAIL = 'info@sag24.ru'
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { useState } from 'react'
|
||||
import { ChevronRight, Server, Shield, Headphones, Phone, Mail, MapPin, CheckCircle2 } from 'lucide-react'
|
||||
import { ChevronRight, Server, Shield, Headphones, Phone, Mail, MapPin, CheckCircle2, ChevronDown } from 'lucide-react'
|
||||
import { useLanguage } from '../contexts/LanguageContext.jsx'
|
||||
import { useReveal } from '../components/useReveal.js'
|
||||
import { FORM_ENDPOINT, EMAIL } from '../config.js'
|
||||
|
||||
const serviceIcons = [Server, Shield, Headphones]
|
||||
|
||||
@@ -26,20 +27,69 @@ function ServiceCard({ icon: Icon, title, description, points }) {
|
||||
)
|
||||
}
|
||||
|
||||
function FaqItem({ q, a }) {
|
||||
const [open, setOpen] = useState(false)
|
||||
return (
|
||||
<div className="border border-slate-200 rounded-xl overflow-hidden">
|
||||
<button
|
||||
onClick={() => setOpen(!open)}
|
||||
className="w-full flex items-center justify-between px-6 py-4 text-left bg-white hover:bg-slate-50 transition-colors"
|
||||
>
|
||||
<span className="font-semibold text-slate-800 pr-4">{q}</span>
|
||||
<ChevronDown size={18} className={`text-slate-400 flex-shrink-0 transition-transform duration-200 ${open ? 'rotate-180' : ''}`} />
|
||||
</button>
|
||||
{open && (
|
||||
<div className="px-6 py-4 bg-slate-50 border-t border-slate-200 text-slate-600 text-sm leading-relaxed">
|
||||
{a}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const { t } = useLanguage()
|
||||
const [formState, setFormState] = useState({ name: '', company: '', message: '' })
|
||||
const [formState, setFormState] = useState({ name: '', company: '', phone: '', message: '' })
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
const [sending, setSending] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
|
||||
const aboutRef = useReveal()
|
||||
const contactRef = useReveal()
|
||||
const faqRef = useReveal()
|
||||
|
||||
const services = t('services.items')
|
||||
const stats = [t('about.stat1'), t('about.stat2'), t('about.stat3')]
|
||||
const faqItems = t('faq.items')
|
||||
const firstPhone = t('contact.phones')[0]
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault()
|
||||
setSending(true)
|
||||
setError('')
|
||||
|
||||
if (FORM_ENDPOINT) {
|
||||
try {
|
||||
const res = await fetch(FORM_ENDPOINT, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
||||
body: JSON.stringify(formState),
|
||||
})
|
||||
if (res.ok) {
|
||||
setSubmitted(true)
|
||||
} else {
|
||||
setError(t('contact.formError'))
|
||||
}
|
||||
} catch {
|
||||
setError(t('contact.formError'))
|
||||
}
|
||||
} else {
|
||||
// Fallback: mailto
|
||||
const body = `Имя: ${formState.name}\nКомпания: ${formState.company}\nТелефон: ${formState.phone}\n\n${formState.message}`
|
||||
window.location.href = `mailto:${EMAIL}?subject=Заявка с сайта sag24.ru&body=${encodeURIComponent(body)}`
|
||||
setSubmitted(true)
|
||||
}
|
||||
setSending(false)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -61,7 +111,7 @@ export default function Home() {
|
||||
<p className="text-lg sm:text-xl text-slate-300 max-w-2xl mx-auto mb-10 leading-relaxed">
|
||||
{t('hero.subtitle')}
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-10">
|
||||
<a href="#contact" className="px-8 py-4 bg-blue-600 hover:bg-blue-500 text-white font-semibold rounded-lg transition-all duration-300 flex items-center justify-center gap-2 group">
|
||||
{t('hero.cta')}
|
||||
<ChevronRight size={20} className="group-hover:translate-x-1 transition-transform" />
|
||||
@@ -70,6 +120,10 @@ export default function Home() {
|
||||
{t('hero.ctaSecondary')}
|
||||
</a>
|
||||
</div>
|
||||
<a href={`tel:${firstPhone.replace(/\D/g,'')}`} className="inline-flex items-center gap-2 text-blue-300 hover:text-white transition-colors text-lg font-medium">
|
||||
<Phone size={18} />
|
||||
{firstPhone}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -165,6 +219,23 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section id="faq" className="py-24 bg-white border-t border-slate-100">
|
||||
<div className="max-w-3xl mx-auto px-4 sm:px-6">
|
||||
<div ref={faqRef} className="section-reveal">
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-3xl sm:text-4xl font-bold text-slate-900 mb-4">{t('faq.title')}</h2>
|
||||
<p className="text-slate-500 text-lg">{t('faq.subtitle')}</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
{faqItems.map((item, i) => (
|
||||
<FaqItem key={i} q={item.q} a={item.a} />
|
||||
))}
|
||||
</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">
|
||||
@@ -197,8 +268,8 @@ export default function Home() {
|
||||
<a href="mailto:info@sag24.ru" className="text-white font-medium hover:text-blue-400 transition-colors">info@sag24.ru</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 bg-blue-500/10 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-10 h-10 bg-blue-500/10 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||
<MapPin size={20} className="text-blue-400" />
|
||||
</div>
|
||||
<div>
|
||||
@@ -207,6 +278,19 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Yandex Map */}
|
||||
<div className="mt-8 rounded-xl overflow-hidden border border-white/10">
|
||||
<iframe
|
||||
src="https://yandex.ru/map-widget/v1/?ll=37.857200%2C56.009400&z=16&pt=37.857200%2C56.009400%2Cpm2rdm&l=map"
|
||||
width="100%"
|
||||
height="220"
|
||||
frameBorder="0"
|
||||
title="Офис Сисадмингрупп на карте"
|
||||
loading="lazy"
|
||||
allowFullScreen
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white/5 border border-white/10 rounded-xl p-8">
|
||||
@@ -232,19 +316,28 @@ export default function Home() {
|
||||
onChange={e => setFormState({ ...formState, company: e.target.value })}
|
||||
className="w-full bg-white/10 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-slate-400 focus:outline-none focus:border-blue-500 transition-colors text-sm"
|
||||
/>
|
||||
<input
|
||||
type="tel"
|
||||
placeholder={t('contact.formPhone')}
|
||||
value={formState.phone}
|
||||
onChange={e => setFormState({ ...formState, phone: e.target.value })}
|
||||
className="w-full bg-white/10 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-slate-400 focus:outline-none focus:border-blue-500 transition-colors text-sm"
|
||||
/>
|
||||
<textarea
|
||||
required
|
||||
rows={5}
|
||||
rows={4}
|
||||
placeholder={t('contact.formMessage')}
|
||||
value={formState.message}
|
||||
onChange={e => setFormState({ ...formState, message: e.target.value })}
|
||||
className="w-full bg-white/10 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-slate-400 focus:outline-none focus:border-blue-500 transition-colors text-sm resize-none"
|
||||
/>
|
||||
{error && <p className="text-red-400 text-sm">{error}</p>}
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full py-3 bg-blue-600 hover:bg-blue-500 text-white font-semibold rounded-lg transition-colors"
|
||||
disabled={sending}
|
||||
className="w-full py-3 bg-blue-600 hover:bg-blue-500 disabled:opacity-60 text-white font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
{t('contact.formSubmit')}
|
||||
{sending ? t('contact.formSending') : t('contact.formSubmit')}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
||||
@@ -2,6 +2,7 @@ export const en = {
|
||||
nav: {
|
||||
services: 'Services',
|
||||
about: 'About',
|
||||
faq: 'FAQ',
|
||||
contact: 'Contact',
|
||||
},
|
||||
hero: {
|
||||
@@ -50,8 +51,41 @@ export const en = {
|
||||
formName: 'Your name',
|
||||
formCompany: 'Company',
|
||||
formMessage: 'Describe your task',
|
||||
formPhone: 'Your phone',
|
||||
formSubmit: 'Send Request',
|
||||
formSending: 'Sending...',
|
||||
formSuccess: 'Request sent! We will contact you shortly.',
|
||||
formError: 'Send error. Please call us directly.',
|
||||
},
|
||||
faq: {
|
||||
title: 'FAQ',
|
||||
subtitle: 'Common questions about IT outsourcing',
|
||||
items: [
|
||||
{
|
||||
q: 'How much does IT outsourcing cost?',
|
||||
a: 'Cost depends on the number of workstations and service scope. For 5–10 workstations — from 15,000 RUB/month. Contact us for an exact quote.',
|
||||
},
|
||||
{
|
||||
q: 'How fast do you respond to issues?',
|
||||
a: 'SLA from 15 minutes for remote tasks. On-site visit within 2–4 hours in Pushkino and nearby cities.',
|
||||
},
|
||||
{
|
||||
q: 'Do you work outside Pushkino?',
|
||||
a: 'Yes, we serve companies across the Moscow Region. Remote support has no geographic limits.',
|
||||
},
|
||||
{
|
||||
q: 'What is included in the service contract?',
|
||||
a: 'Services are defined in the SLA: 24/7 support, infrastructure monitoring, remote and on-site service, antivirus protection.',
|
||||
},
|
||||
{
|
||||
q: 'Do we need to stop operations during onboarding?',
|
||||
a: 'No. Onboarding takes 1–2 days and does not require stopping any business processes.',
|
||||
},
|
||||
{
|
||||
q: 'Do you only work with small businesses?',
|
||||
a: 'We serve companies from 3 to 200+ workstations, including government institutions and manufacturing enterprises.',
|
||||
},
|
||||
],
|
||||
},
|
||||
partners: {
|
||||
title: 'Partners',
|
||||
|
||||
@@ -2,6 +2,7 @@ export const ru = {
|
||||
nav: {
|
||||
services: 'Услуги',
|
||||
about: 'О нас',
|
||||
faq: 'FAQ',
|
||||
contact: 'Контакты',
|
||||
},
|
||||
hero: {
|
||||
@@ -50,8 +51,41 @@ export const ru = {
|
||||
formName: 'Ваше имя',
|
||||
formCompany: 'Компания',
|
||||
formMessage: 'Опишите задачу',
|
||||
formPhone: 'Ваш телефон',
|
||||
formSubmit: 'Отправить заявку',
|
||||
formSending: 'Отправка...',
|
||||
formSuccess: 'Заявка отправлена! Мы свяжемся с вами в ближайшее время.',
|
||||
formError: 'Ошибка отправки. Позвоните нам напрямую.',
|
||||
},
|
||||
faq: {
|
||||
title: 'Частые вопросы',
|
||||
subtitle: 'Ответы на типовые вопросы об IT-аутсорсинге',
|
||||
items: [
|
||||
{
|
||||
q: 'Сколько стоит IT-аутсорсинг?',
|
||||
a: 'Стоимость зависит от количества рабочих мест и состава услуг. Для 5–10 рабочих мест — от 15 000 руб./мес. Свяжитесь с нами для точного расчёта.',
|
||||
},
|
||||
{
|
||||
q: 'Как быстро вы реагируете на проблемы?',
|
||||
a: 'SLA от 15 минут для удалённых задач. Выезд специалиста в течение 2–4 часов по Пушкино и ближайшим городам.',
|
||||
},
|
||||
{
|
||||
q: 'Работаете ли вы за пределами Пушкино?',
|
||||
a: 'Да, обслуживаем компании по всей Московской области. Удалённая поддержка — без ограничений по географии.',
|
||||
},
|
||||
{
|
||||
q: 'Что входит в договор на обслуживание?',
|
||||
a: 'Перечень услуг фиксируется в SLA: техподдержка 24/7, мониторинг инфраструктуры, удалённое и выездное обслуживание, антивирусная защита.',
|
||||
},
|
||||
{
|
||||
q: 'Нужно ли прерывать работу при подключении?',
|
||||
a: 'Нет. Подключение к обслуживанию занимает 1–2 дня и не требует остановки бизнес-процессов.',
|
||||
},
|
||||
{
|
||||
q: 'Вы работаете только с малым бизнесом?',
|
||||
a: 'Обслуживаем компании от 3 до 200+ рабочих мест, включая государственные учреждения и производственные предприятия.',
|
||||
},
|
||||
],
|
||||
},
|
||||
partners: {
|
||||
title: 'Партнёры',
|
||||
|
||||
Reference in New Issue
Block a user