diff --git a/index.html b/index.html
index c3b2a52..2699a99 100644
--- a/index.html
+++ b/index.html
@@ -1396,19 +1396,25 @@
const nextBtn = document.getElementById('carousel-next');
const servicesProgressBar = document.getElementById('services-progress-bar');
+ let updateServicesProgress = () => {};
+
if (carousel && prevBtn && nextBtn) {
prevBtn.addEventListener('click', () => {
- const cardWidth = carousel.firstElementChild.getBoundingClientRect().width + 32; // ширина карточки + gap-8 (32px)
- carousel.scrollBy({ left: -cardWidth, behavior: 'smooth' });
+ if (carousel.firstElementChild) {
+ const cardWidth = carousel.firstElementChild.getBoundingClientRect().width + 32; // ширина карточки + gap-8 (32px)
+ carousel.scrollBy({ left: -cardWidth, behavior: 'smooth' });
+ }
});
nextBtn.addEventListener('click', () => {
- const cardWidth = carousel.firstElementChild.getBoundingClientRect().width + 32; // ширина карточки + gap-8 (32px)
- carousel.scrollBy({ left: cardWidth, behavior: 'smooth' });
+ if (carousel.firstElementChild) {
+ const cardWidth = carousel.firstElementChild.getBoundingClientRect().width + 32; // ширина карточки + gap-8 (32px)
+ carousel.scrollBy({ left: cardWidth, behavior: 'smooth' });
+ }
});
// Обновление прогресс-бара услуг
- function updateServicesProgress() {
+ updateServicesProgress = function() {
if (servicesProgressBar) {
const scrollWidth = carousel.scrollWidth;
const clientWidth = carousel.clientWidth;
@@ -1430,6 +1436,276 @@
window.addEventListener('load', updateServicesProgress);
}
+ // Динамическая загрузка услуг из базы данных
+ function loadDynamicServices() {
+ if (!carousel) return;
+
+ const serviceStaticMeta = {
+ "web_1": {
+ badge: "⚡ Быстрый разбор",
+ bullets: [
+ { icon: "🔍", text: "Анализ игры" },
+ { icon: "🎯", text: "Работа над механикой и позиционированием" },
+ { icon: "👤", text: "Персональные рекомендации" },
+ { icon: "💬", text: "Фидбек после занятия" }
+ ],
+ image: "Images/coaching_session.png"
+ },
+ "web_2": {
+ badge: "👥 Групповой формат",
+ bullets: [
+ { icon: "👥", text: "Тренировки в мини-группе" },
+ { icon: "🎯", text: "Разбор игровых ситуаций" },
+ { icon: "🤝", text: "Командное взаимодействие" },
+ { icon: "💬", text: "Разбор домашних игр" }
+ ],
+ image: "Images/group_4_coaching.png"
+ },
+ "web_3": {
+ badge: "👥 Групповой формат",
+ bullets: [
+ { icon: "👥", text: "8 тренировок в группе" },
+ { icon: "📊", text: "Трекинг прогресса" },
+ { icon: "⚔️", text: "Участие во внутренних праках" },
+ { icon: "🧠", text: "Психология и тактика" }
+ ],
+ image: "Images/group_8_coaching.png"
+ },
+ "web_4": {
+ badge: "👤 Индивидуально",
+ bullets: [
+ { icon: "🎯", text: "Персональный тренер" },
+ { icon: "🎥", text: "Разбор записей (VOD)" },
+ { icon: "📈", text: "Индивидуальный план" },
+ { icon: "💬", text: "Постоянный контакт в Discord" }
+ ],
+ image: "Images/indiv_4_coaching.png"
+ },
+ "web_5": {
+ badge: "⭐ VIP формат",
+ bullets: [
+ { icon: "👑", text: "Полное сопровождение" },
+ { icon: "📁", text: "Личное портфолио игрока" },
+ { icon: "📞", text: "Прямая связь 24/7" },
+ { icon: "🏆", text: "Подготовка к турнирам" }
+ ],
+ image: "Images/indiv_8_coaching.png"
+ }
+ };
+
+ const colors = [
+ { border: 'border-cyber-blue', shadow: 'shadow-[0_0_15px_rgba(59,130,246,0.2)]', bgGlow: 'bg-cyber-blue/10', borderGlow: 'border-cyber-blue/30', borderGlowLight: 'border-cyber-blue/20', badgeBg: 'bg-cyber-blue', textGlow: 'text-glow-blue', borderBullet: 'border-cyber-blue/40', shadowBullet: 'shadow-[0_0_10px_rgba(59,130,246,0.1)]', borderBtn: 'border-cyber-blue', bulletColor: 'text-cyber-blue', tagIcon: 'text-cyber-blue', shadowColorRgb: '59, 130, 246' },
+ { border: 'border-cyber-purple', shadow: 'shadow-[0_0_15px_rgba(124,58,237,0.2)]', bgGlow: 'bg-cyber-purple/10', borderGlow: 'border-cyber-purple/30', borderGlowLight: 'border-cyber-purple/20', badgeBg: 'bg-cyber-purple', textGlow: 'text-glow-purple', borderBullet: 'border-cyber-purple/40', shadowBullet: 'shadow-[0_0_10px_rgba(124,58,237,0.1)]', borderBtn: 'border-cyber-purple', bulletColor: 'text-cyber-purple', tagIcon: 'text-cyber-purple', shadowColorRgb: '124, 58, 237' },
+ { border: 'border-cyber-pink', shadow: 'shadow-[0_0_15px_rgba(236,72,153,0.2)]', bgGlow: 'bg-cyber-pink/10', borderGlow: 'border-cyber-pink/30', borderGlowLight: 'border-cyber-pink/20', badgeBg: 'bg-cyber-pink', textGlow: 'text-glow-pink', borderBullet: 'border-cyber-pink/40', shadowBullet: 'shadow-[0_0_10px_rgba(236,72,153,0.1)]', borderBtn: 'border-cyber-pink', bulletColor: 'text-cyber-pink', tagIcon: 'text-cyber-pink', shadowColorRgb: '236, 72, 153' }
+ ];
+
+ fetch('/api/services')
+ .then(res => {
+ if (!res.ok) throw new Error('Failed to load services API');
+ return res.json();
+ })
+ .then(data => {
+ if (data.status === 'success' && data.services) {
+ const servicesObj = data.services;
+ const servicesList = Object.keys(servicesObj).map(key => {
+ return { id: key, ...servicesObj[key] };
+ });
+
+ if (servicesList.length === 0) return;
+
+ let cardsHtml = '';
+ servicesList.forEach((svc, index) => {
+ const colorClass = colors[index % colors.length];
+
+ // Format title
+ let titleHtml = svc.name;
+ if (svc.name.includes("Абонемент на")) {
+ titleHtml = svc.name.replace("Абонемент на", "Абонемент
на");
+ } else if (svc.name.includes("Разовая тренировка")) {
+ titleHtml = "Разовая
тренировка";
+ }
+
+ // Format subtitle
+ let subtitle = '';
+ if (svc.description && (svc.description.toLowerCase().includes("counter-strike") || svc.description.toLowerCase().includes("dota") || svc.description.toLowerCase().includes("tanks"))) {
+ subtitle = svc.description.split(/[\n,;]/).map(s => s.trim()).filter(s => s.length > 0).join(" • ");
+ } else if (serviceStaticMeta[svc.id]) {
+ subtitle = "Counter-Strike 2 • Dota 2 • World of Tanks";
+ } else {
+ subtitle = "КУРС ОБУЧЕНИЯ ИКП";
+ }
+
+ // Image fallback logic
+ let image = "Images/coaching_session.png";
+ if (serviceStaticMeta[svc.id]) {
+ image = serviceStaticMeta[svc.id].image;
+ } else {
+ const lowerName = svc.name.toLowerCase();
+ if (lowerName.includes("групп")) {
+ image = "Images/group_4_coaching.png";
+ } else if (lowerName.includes("индивид") || lowerName.includes("vip")) {
+ image = "Images/indiv_4_coaching.png";
+ }
+ }
+
+ // Badge
+ let badge = "⭐ Услуга";
+ if (serviceStaticMeta[svc.id]) {
+ badge = serviceStaticMeta[svc.id].badge;
+ } else {
+ const lowerName = svc.name.toLowerCase();
+ if (lowerName.includes("разов") || lowerName.includes("однократ")) badge = "⚡ Быстрый старт";
+ else if (lowerName.includes("групп")) badge = "👥 Групповой";
+ else if (lowerName.includes("индивид")) badge = "👤 Индивидуально";
+ else if (lowerName.includes("абонемент") || lowerName.includes("пакет")) badge = "📦 Пакет услуг";
+ }
+
+ // Bullets parser logic
+ let bullets = [];
+ if (serviceStaticMeta[svc.id]) {
+ const isDefaultDesc = !svc.description ||
+ svc.description.toLowerCase().includes("counter-strike") ||
+ svc.description.toLowerCase().includes("dota") ||
+ svc.description.toLowerCase().includes("tanks");
+ if (isDefaultDesc) {
+ bullets = serviceStaticMeta[svc.id].bullets;
+ }
+ }
+ if (bullets.length === 0 && svc.description) {
+ const lines = svc.description.split(/[\n;]/).map(l => l.trim()).filter(l => l.length > 0);
+ if (lines.length > 1) {
+ bullets = lines.map(line => {
+ const cleanLine = line.replace(/^[\s\-\*\•\d\.\:\)\>]+/, '').trim();
+ let icon = "⚡";
+ const lower = cleanLine.toLowerCase();
+ if (lower.includes("анализ") || lower.includes("разбор")) icon = "🔍";
+ else if (lower.includes("тренер") || lower.includes("индивидуальн") || lower.includes("персональн")) icon = "👤";
+ else if (lower.includes("механик") || lower.includes("цель") || lower.includes("стрельб")) icon = "🎯";
+ else if (lower.includes("групп") || lower.includes("команд") || lower.includes("совестн")) icon = "👥";
+ else if (lower.includes("прогресс") || lower.includes("план") || lower.includes("отчет")) icon = "📈";
+ else if (lower.includes("дискорд") || lower.includes("discord") || lower.includes("связь") || lower.includes("контакт")) icon = "💬";
+ else if (lower.includes("турнир") || lower.includes("кубок") || lower.includes("побед")) icon = "🏆";
+ return { icon, text: cleanLine };
+ });
+ }
+ }
+ if (bullets.length === 0) {
+ bullets = [
+ { icon: "🎮", text: svc.description || "Практические занятия" },
+ { icon: "📈", text: "Развитие навыков и тактики" },
+ { icon: "👤", text: "Индивидуальный подход" },
+ { icon: "💬", text: "Обратная связь по итогам" }
+ ];
+ }
+
+ let bulletsHtml = '';
+ bullets.forEach(b => {
+ bulletsHtml += `
+
+