feat: добавлены модели AboutPage и FooterSettings с админ-панелью и интеграцией скриптов
This commit is contained in:
@@ -72,6 +72,7 @@ TEMPLATES = [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'web.context_processors.footer_settings', # Custom context processor
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import Service, Project, Client, Order, Review, BlogPost, Category, ServiceRequest
|
||||
from .models import (
|
||||
Service, Project, Client, Order, Review, BlogPost,
|
||||
Category, ServiceRequest, AboutPage, FooterSettings
|
||||
)
|
||||
from .forms import ProjectForm
|
||||
|
||||
@admin.register(Service)
|
||||
@@ -46,3 +49,104 @@ class ServiceRequestAdmin(admin.ModelAdmin):
|
||||
list_display = ('service','token', 'client', 'created_at')
|
||||
search_fields = ('service','token', 'client')
|
||||
list_filter = ('service','token','client')
|
||||
|
||||
@admin.register(AboutPage)
|
||||
class AboutPageAdmin(admin.ModelAdmin):
|
||||
list_display = ('hero_title', 'is_active', 'updated_at')
|
||||
list_filter = ('is_active', 'updated_at')
|
||||
search_fields = ('hero_title', 'mission_title', 'vision_title')
|
||||
|
||||
fieldsets = (
|
||||
('Hero секция', {
|
||||
'fields': ('hero_badge', 'hero_title', 'hero_description')
|
||||
}),
|
||||
('Статистика', {
|
||||
'fields': ('stat_projects', 'stat_clients', 'stat_years', 'stat_support')
|
||||
}),
|
||||
('Миссия', {
|
||||
'fields': (
|
||||
'mission_badge', 'mission_title', 'mission_description',
|
||||
'mission_point_1_title', 'mission_point_1_text',
|
||||
'mission_point_2_title', 'mission_point_2_text',
|
||||
'mission_point_3_title', 'mission_point_3_text',
|
||||
)
|
||||
}),
|
||||
('Видение', {
|
||||
'fields': ('vision_badge', 'vision_title', 'vision_description')
|
||||
}),
|
||||
('Навыки', {
|
||||
'fields': (
|
||||
'skill_1_name', 'skill_1_percent',
|
||||
'skill_2_name', 'skill_2_percent',
|
||||
'skill_3_name', 'skill_3_percent',
|
||||
'skill_4_name', 'skill_4_percent',
|
||||
)
|
||||
}),
|
||||
('Команда', {
|
||||
'fields': ('team_badge', 'team_title', 'team_description')
|
||||
}),
|
||||
('Ценности', {
|
||||
'fields': (
|
||||
'values_badge', 'values_title',
|
||||
'value_1_icon', 'value_1_title', 'value_1_text',
|
||||
'value_2_icon', 'value_2_title', 'value_2_text',
|
||||
'value_3_icon', 'value_3_title', 'value_3_text',
|
||||
'value_4_icon', 'value_4_title', 'value_4_text',
|
||||
)
|
||||
}),
|
||||
('Контакты', {
|
||||
'fields': ('contact_title', 'contact_description')
|
||||
}),
|
||||
('Настройки', {
|
||||
'fields': ('is_active',)
|
||||
}),
|
||||
)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
return not AboutPage.objects.filter(is_active=True).exists()
|
||||
|
||||
|
||||
@admin.register(FooterSettings)
|
||||
class FooterSettingsAdmin(admin.ModelAdmin):
|
||||
list_display = ('company_name', 'email', 'is_active', 'updated_at')
|
||||
list_filter = ('is_active', 'updated_at')
|
||||
search_fields = ('company_name', 'email')
|
||||
|
||||
fieldsets = (
|
||||
('Информация о компании', {
|
||||
'fields': ('company_name', 'company_description', 'company_logo_icon')
|
||||
}),
|
||||
('Социальные сети', {
|
||||
'fields': ('telegram_url', 'instagram_url', 'linkedin_url', 'github_url', 'facebook_url', 'twitter_url'),
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
('Контактная информация', {
|
||||
'fields': ('email', 'phone', 'address')
|
||||
}),
|
||||
('Меню футера', {
|
||||
'fields': (
|
||||
'show_services_menu', 'services_title',
|
||||
'show_company_menu', 'company_menu_title'
|
||||
),
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
('Copyright', {
|
||||
'fields': ('copyright_text',)
|
||||
}),
|
||||
('Интеграция скриптов', {
|
||||
'fields': ('google_analytics', 'google_adsense', 'yandex_metrika', 'facebook_pixel'),
|
||||
'description': 'Вставьте коды аналитики без тегов <script></script>',
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
('Дополнительные скрипты', {
|
||||
'fields': ('custom_head_scripts', 'custom_body_scripts'),
|
||||
'description': 'Вставьте дополнительные скрипты С тегами <script></script>',
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
('Настройки', {
|
||||
'fields': ('is_active',)
|
||||
}),
|
||||
)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
return not FooterSettings.objects.filter(is_active=True).exists()
|
||||
|
||||
13
smartsoltech/web/context_processors.py
Normal file
13
smartsoltech/web/context_processors.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from .models import FooterSettings
|
||||
|
||||
|
||||
def footer_settings(request):
|
||||
"""Context processor для настроек футера"""
|
||||
try:
|
||||
footer = FooterSettings.objects.filter(is_active=True).first()
|
||||
except:
|
||||
footer = None
|
||||
|
||||
return {
|
||||
'footer_settings': footer
|
||||
}
|
||||
112
smartsoltech/web/management/commands/init_about_footer.py
Normal file
112
smartsoltech/web/management/commands/init_about_footer.py
Normal file
@@ -0,0 +1,112 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from web.models import AboutPage, FooterSettings
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Создает начальные данные для страницы О нас и Footer'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Создать About Page
|
||||
if not AboutPage.objects.exists():
|
||||
AboutPage.objects.create(
|
||||
hero_badge='🚀 О нас',
|
||||
hero_title='Мы создаем <span class="text-gradient">цифровое будущее</span>',
|
||||
hero_description='SmartSolTech - это команда профессионалов, которые превращают идеи в инновационные IT-решения. Мы помогаем бизнесу расти и развиваться в цифровую эпоху.',
|
||||
|
||||
stat_projects=50,
|
||||
stat_clients=30,
|
||||
stat_years=3,
|
||||
stat_support='24/7',
|
||||
|
||||
mission_badge='🎯 Наша миссия',
|
||||
mission_title='Делаем технологии <span class="text-gradient">доступными</span>',
|
||||
mission_description='Мы верим, что каждый бизнес заслуживает доступа к современным технологиям. Наша миссия — демократизировать IT-решения и помочь компаниям любого размера достичь цифрового совершенства.',
|
||||
|
||||
mission_point_1_title='Инновационные решения',
|
||||
mission_point_1_text='Используем передовые технологии для создания уникальных продуктов',
|
||||
|
||||
mission_point_2_title='Клиентоориентированность',
|
||||
mission_point_2_text='Фокусируемся на потребностях и целях каждого клиента',
|
||||
|
||||
mission_point_3_title='Непрерывное развитие',
|
||||
mission_point_3_text='Постоянно совершенствуем наши навыки и знания',
|
||||
|
||||
vision_badge='🔮 Наше видение',
|
||||
vision_title='Будущее начинается <span class="text-gradient">сегодня</span>',
|
||||
vision_description='Мы стремимся стать ведущей IT-компанией в Корее, известной своими инновационными решениями, высоким качеством сервиса и способностью трансформировать бизнес-идеи в успешные цифровые продукты.',
|
||||
|
||||
skill_1_name='Веб-разработка',
|
||||
skill_1_percent=95,
|
||||
|
||||
skill_2_name='Мобильная разработка',
|
||||
skill_2_percent=90,
|
||||
|
||||
skill_3_name='UI/UX Дизайн',
|
||||
skill_3_percent=85,
|
||||
|
||||
skill_4_name='DevOps',
|
||||
skill_4_percent=80,
|
||||
|
||||
team_badge='👥 Команда',
|
||||
team_title='Познакомьтесь с <span class="text-gradient">нашей командой</span>',
|
||||
team_description='Талантливые профессионалы, которые воплощают ваши идеи в реальность',
|
||||
|
||||
values_badge='💎 Наши ценности',
|
||||
values_title='Что нами <span class="text-gradient">движет</span>',
|
||||
|
||||
value_1_icon='fa-lightbulb',
|
||||
value_1_title='Инновации',
|
||||
value_1_text='Мы постоянно ищем новые решения и подходы',
|
||||
|
||||
value_2_icon='fa-handshake',
|
||||
value_2_title='Партнерство',
|
||||
value_2_text='Строим долгосрочные отношения с клиентами',
|
||||
|
||||
value_3_icon='fa-chart-line',
|
||||
value_3_title='Результат',
|
||||
value_3_text='Фокусируемся на достижении целей клиента',
|
||||
|
||||
value_4_icon='fa-shield-alt',
|
||||
value_4_title='Надежность',
|
||||
value_4_text='Гарантируем качество и безопасность',
|
||||
|
||||
contact_title='Готовы начать проект?',
|
||||
contact_description='Свяжитесь с нами сегодня, и мы поможем воплотить ваши идеи в жизнь',
|
||||
|
||||
is_active=True
|
||||
)
|
||||
self.stdout.write(self.style.SUCCESS('✅ AboutPage создана'))
|
||||
else:
|
||||
self.stdout.write(self.style.WARNING('⚠️ AboutPage уже существует'))
|
||||
|
||||
# Создать Footer Settings
|
||||
if not FooterSettings.objects.exists():
|
||||
FooterSettings.objects.create(
|
||||
company_name='SmartSolTech',
|
||||
company_description='Мы создаем инновационные IT-решения, которые помогают бизнесу расти и развиваться в цифровую эпоху.',
|
||||
company_logo_icon='fa-code',
|
||||
|
||||
telegram_url='https://t.me/smartsoltech',
|
||||
instagram_url='https://instagram.com/smartsoltech',
|
||||
linkedin_url='https://linkedin.com/company/smartsoltech',
|
||||
github_url='https://github.com/smartsoltech',
|
||||
|
||||
email='info@smartsoltech.kr',
|
||||
phone='+82-10-XXXX-XXXX',
|
||||
address='Seoul, South Korea',
|
||||
|
||||
show_services_menu=True,
|
||||
services_title='Услуги',
|
||||
|
||||
show_company_menu=True,
|
||||
company_menu_title='Компания',
|
||||
|
||||
copyright_text='© 2025 SmartSolTech. Все права защищены.',
|
||||
|
||||
is_active=True
|
||||
)
|
||||
self.stdout.write(self.style.SUCCESS('✅ FooterSettings созданы'))
|
||||
else:
|
||||
self.stdout.write(self.style.WARNING('⚠️ FooterSettings уже существуют'))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('\n✨ Готово! Данные созданы успешно'))
|
||||
106
smartsoltech/web/migrations/0010_aboutpage_footersettings.py
Normal file
106
smartsoltech/web/migrations/0010_aboutpage_footersettings.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# Generated by Django 5.1.1 on 2025-11-24 00:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('web', '0009_alter_servicerequest_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AboutPage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('hero_badge', models.CharField(default='🚀 О нас', max_length=100, verbose_name='Hero Badge')),
|
||||
('hero_title', models.CharField(default='Мы создаем цифровое будущее', max_length=200, verbose_name='Заголовок Hero')),
|
||||
('hero_description', models.TextField(default='SmartSolTech - это команда профессионалов...', verbose_name='Описание Hero')),
|
||||
('stat_projects', models.IntegerField(default=50, verbose_name='Количество проектов')),
|
||||
('stat_clients', models.IntegerField(default=30, verbose_name='Количество клиентов')),
|
||||
('stat_years', models.IntegerField(default=3, verbose_name='Лет опыта')),
|
||||
('stat_support', models.CharField(default='24/7', max_length=50, verbose_name='Поддержка')),
|
||||
('mission_badge', models.CharField(default='🎯 Наша миссия', max_length=100, verbose_name='Mission Badge')),
|
||||
('mission_title', models.CharField(default='Делаем технологии доступными', max_length=200, verbose_name='Заголовок миссии')),
|
||||
('mission_description', models.TextField(verbose_name='Описание миссии')),
|
||||
('mission_point_1_title', models.CharField(default='Инновационные решения', max_length=200, verbose_name='Пункт миссии 1')),
|
||||
('mission_point_1_text', models.TextField(default='Используем передовые технологии...', verbose_name='Текст пункта 1')),
|
||||
('mission_point_2_title', models.CharField(default='Клиентоориентированность', max_length=200, verbose_name='Пункт миссии 2')),
|
||||
('mission_point_2_text', models.TextField(default='Фокусируемся на потребностях...', verbose_name='Текст пункта 2')),
|
||||
('mission_point_3_title', models.CharField(default='Непрерывное развитие', max_length=200, verbose_name='Пункт миссии 3')),
|
||||
('mission_point_3_text', models.TextField(default='Постоянно совершенствуем...', verbose_name='Текст пункта 3')),
|
||||
('vision_badge', models.CharField(default='🔮 Наше видение', max_length=100, verbose_name='Vision Badge')),
|
||||
('vision_title', models.CharField(default='Будущее начинается сегодня', max_length=200, verbose_name='Заголовок видения')),
|
||||
('vision_description', models.TextField(verbose_name='Описание видения')),
|
||||
('skill_1_name', models.CharField(default='Веб-разработка', max_length=100, verbose_name='Навык 1')),
|
||||
('skill_1_percent', models.IntegerField(default=95, verbose_name='Процент навыка 1')),
|
||||
('skill_2_name', models.CharField(default='Мобильная разработка', max_length=100, verbose_name='Навык 2')),
|
||||
('skill_2_percent', models.IntegerField(default=90, verbose_name='Процент навыка 2')),
|
||||
('skill_3_name', models.CharField(default='UI/UX Дизайн', max_length=100, verbose_name='Навык 3')),
|
||||
('skill_3_percent', models.IntegerField(default=85, verbose_name='Процент навыка 3')),
|
||||
('skill_4_name', models.CharField(default='DevOps', max_length=100, verbose_name='Навык 4')),
|
||||
('skill_4_percent', models.IntegerField(default=80, verbose_name='Процент навыка 4')),
|
||||
('team_badge', models.CharField(default='👥 Команда', max_length=100, verbose_name='Team Badge')),
|
||||
('team_title', models.CharField(default='Познакомьтесь с нашей командой', max_length=200, verbose_name='Заголовок команды')),
|
||||
('team_description', models.TextField(default='Талантливые профессионалы...', verbose_name='Описание команды')),
|
||||
('values_badge', models.CharField(default='💎 Наши ценности', max_length=100, verbose_name='Values Badge')),
|
||||
('values_title', models.CharField(default='Что нами движет', max_length=200, verbose_name='Заголовок ценностей')),
|
||||
('value_1_icon', models.CharField(default='fa-lightbulb', max_length=50, verbose_name='Иконка ценности 1')),
|
||||
('value_1_title', models.CharField(default='Инновации', max_length=100, verbose_name='Ценность 1')),
|
||||
('value_1_text', models.TextField(default='Мы постоянно ищем новые решения...', verbose_name='Текст ценности 1')),
|
||||
('value_2_icon', models.CharField(default='fa-handshake', max_length=50, verbose_name='Иконка ценности 2')),
|
||||
('value_2_title', models.CharField(default='Партнерство', max_length=100, verbose_name='Ценность 2')),
|
||||
('value_2_text', models.TextField(default='Строим долгосрочные отношения...', verbose_name='Текст ценности 2')),
|
||||
('value_3_icon', models.CharField(default='fa-chart-line', max_length=50, verbose_name='Иконка ценности 3')),
|
||||
('value_3_title', models.CharField(default='Результат', max_length=100, verbose_name='Ценность 3')),
|
||||
('value_3_text', models.TextField(default='Фокусируемся на достижении целей...', verbose_name='Текст ценности 3')),
|
||||
('value_4_icon', models.CharField(default='fa-shield-alt', max_length=50, verbose_name='Иконка ценности 4')),
|
||||
('value_4_title', models.CharField(default='Надежность', max_length=100, verbose_name='Ценность 4')),
|
||||
('value_4_text', models.TextField(default='Гарантируем качество и безопасность...', verbose_name='Текст ценности 4')),
|
||||
('contact_title', models.CharField(default='Готовы начать проект?', max_length=200, verbose_name='Заголовок контактов')),
|
||||
('contact_description', models.TextField(default='Свяжитесь с нами сегодня...', verbose_name='Описание контактов')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='Активна')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлено')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Страница О нас',
|
||||
'verbose_name_plural': 'Страницы О нас',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FooterSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('company_name', models.CharField(default='SmartSolTech', max_length=100, verbose_name='Название компании')),
|
||||
('company_description', models.TextField(default='Мы создаем инновационные IT-решения, которые помогают бизнесу расти...', verbose_name='Описание компании')),
|
||||
('company_logo_icon', models.CharField(default='fa-code', max_length=50, verbose_name='Иконка компании')),
|
||||
('telegram_url', models.URLField(blank=True, verbose_name='Telegram URL')),
|
||||
('instagram_url', models.URLField(blank=True, verbose_name='Instagram URL')),
|
||||
('linkedin_url', models.URLField(blank=True, verbose_name='LinkedIn URL')),
|
||||
('github_url', models.URLField(blank=True, verbose_name='GitHub URL')),
|
||||
('facebook_url', models.URLField(blank=True, verbose_name='Facebook URL')),
|
||||
('twitter_url', models.URLField(blank=True, verbose_name='Twitter URL')),
|
||||
('email', models.EmailField(default='info@smartsoltech.kr', max_length=254, verbose_name='Email')),
|
||||
('phone', models.CharField(default='+82-10-XXXX-XXXX', max_length=50, verbose_name='Телефон')),
|
||||
('address', models.TextField(default='Seoul, South Korea', verbose_name='Адрес')),
|
||||
('show_services_menu', models.BooleanField(default=True, verbose_name='Показывать меню услуг')),
|
||||
('services_title', models.CharField(default='Услуги', max_length=100, verbose_name='Заголовок меню услуг')),
|
||||
('show_company_menu', models.BooleanField(default=True, verbose_name='Показывать меню компании')),
|
||||
('company_menu_title', models.CharField(default='Компания', max_length=100, verbose_name='Заголовок меню компании')),
|
||||
('copyright_text', models.CharField(default='© 2025 SmartSolTech. Все права защищены.', max_length=200, verbose_name='Текст Copyright')),
|
||||
('google_analytics', models.TextField(blank=True, help_text='Вставьте код Google Analytics (без тегов <script>)', verbose_name='Google Analytics')),
|
||||
('google_adsense', models.TextField(blank=True, help_text='Вставьте код Google AdSense (без тегов <script>)', verbose_name='Google AdSense')),
|
||||
('yandex_metrika', models.TextField(blank=True, help_text='Вставьте код Яндекс Метрики (без тегов <script>)', verbose_name='Яндекс Метрика')),
|
||||
('facebook_pixel', models.TextField(blank=True, help_text='Вставьте код Facebook Pixel (без тегов <script>)', verbose_name='Facebook Pixel')),
|
||||
('custom_head_scripts', models.TextField(blank=True, help_text='Дополнительные скрипты для вставки в <head> (с тегами <script>)', verbose_name='Скрипты в <head>')),
|
||||
('custom_body_scripts', models.TextField(blank=True, help_text='Дополнительные скрипты для вставки перед закрывающим </body> (с тегами <script>)', verbose_name='Скрипты перед </body>')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='Активно')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлено')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Настройки футера',
|
||||
'verbose_name_plural': 'Настройки футера',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -153,3 +153,191 @@ class Review(models.Model):
|
||||
def __str__(self):
|
||||
return f"Отзыв от {self.client.first_name} {self.client.last_name} for {self.service.name}"
|
||||
|
||||
|
||||
class AboutPage(models.Model):
|
||||
"""Модель для страницы 'О нас' - все данные управляются из админки"""
|
||||
|
||||
# Hero Section
|
||||
hero_badge = models.CharField(max_length=100, default='🚀 О нас', verbose_name='Hero Badge')
|
||||
hero_title = models.CharField(max_length=200, default='Мы создаем цифровое будущее', verbose_name='Заголовок Hero')
|
||||
hero_description = models.TextField(default='SmartSolTech - это команда профессионалов...', verbose_name='Описание Hero')
|
||||
|
||||
# Statistics
|
||||
stat_projects = models.IntegerField(default=50, verbose_name='Количество проектов')
|
||||
stat_clients = models.IntegerField(default=30, verbose_name='Количество клиентов')
|
||||
stat_years = models.IntegerField(default=3, verbose_name='Лет опыта')
|
||||
stat_support = models.CharField(max_length=50, default='24/7', verbose_name='Поддержка')
|
||||
|
||||
# Mission Section
|
||||
mission_badge = models.CharField(max_length=100, default='🎯 Наша миссия', verbose_name='Mission Badge')
|
||||
mission_title = models.CharField(max_length=200, default='Делаем технологии доступными', verbose_name='Заголовок миссии')
|
||||
mission_description = models.TextField(verbose_name='Описание миссии')
|
||||
|
||||
mission_point_1_title = models.CharField(max_length=200, default='Инновационные решения', verbose_name='Пункт миссии 1')
|
||||
mission_point_1_text = models.TextField(default='Используем передовые технологии...', verbose_name='Текст пункта 1')
|
||||
|
||||
mission_point_2_title = models.CharField(max_length=200, default='Клиентоориентированность', verbose_name='Пункт миссии 2')
|
||||
mission_point_2_text = models.TextField(default='Фокусируемся на потребностях...', verbose_name='Текст пункта 2')
|
||||
|
||||
mission_point_3_title = models.CharField(max_length=200, default='Непрерывное развитие', verbose_name='Пункт миссии 3')
|
||||
mission_point_3_text = models.TextField(default='Постоянно совершенствуем...', verbose_name='Текст пункта 3')
|
||||
|
||||
# Vision Section
|
||||
vision_badge = models.CharField(max_length=100, default='🔮 Наше видение', verbose_name='Vision Badge')
|
||||
vision_title = models.CharField(max_length=200, default='Будущее начинается сегодня', verbose_name='Заголовок видения')
|
||||
vision_description = models.TextField(verbose_name='Описание видения')
|
||||
|
||||
# Skills
|
||||
skill_1_name = models.CharField(max_length=100, default='Веб-разработка', verbose_name='Навык 1')
|
||||
skill_1_percent = models.IntegerField(default=95, verbose_name='Процент навыка 1')
|
||||
|
||||
skill_2_name = models.CharField(max_length=100, default='Мобильная разработка', verbose_name='Навык 2')
|
||||
skill_2_percent = models.IntegerField(default=90, verbose_name='Процент навыка 2')
|
||||
|
||||
skill_3_name = models.CharField(max_length=100, default='UI/UX Дизайн', verbose_name='Навык 3')
|
||||
skill_3_percent = models.IntegerField(default=85, verbose_name='Процент навыка 3')
|
||||
|
||||
skill_4_name = models.CharField(max_length=100, default='DevOps', verbose_name='Навык 4')
|
||||
skill_4_percent = models.IntegerField(default=80, verbose_name='Процент навыка 4')
|
||||
|
||||
# Team Section
|
||||
team_badge = models.CharField(max_length=100, default='👥 Команда', verbose_name='Team Badge')
|
||||
team_title = models.CharField(max_length=200, default='Познакомьтесь с нашей командой', verbose_name='Заголовок команды')
|
||||
team_description = models.TextField(default='Талантливые профессионалы...', verbose_name='Описание команды')
|
||||
|
||||
# Values Section
|
||||
values_badge = models.CharField(max_length=100, default='💎 Наши ценности', verbose_name='Values Badge')
|
||||
values_title = models.CharField(max_length=200, default='Что нами движет', verbose_name='Заголовок ценностей')
|
||||
|
||||
value_1_icon = models.CharField(max_length=50, default='fa-lightbulb', verbose_name='Иконка ценности 1')
|
||||
value_1_title = models.CharField(max_length=100, default='Инновации', verbose_name='Ценность 1')
|
||||
value_1_text = models.TextField(default='Мы постоянно ищем новые решения...', verbose_name='Текст ценности 1')
|
||||
|
||||
value_2_icon = models.CharField(max_length=50, default='fa-handshake', verbose_name='Иконка ценности 2')
|
||||
value_2_title = models.CharField(max_length=100, default='Партнерство', verbose_name='Ценность 2')
|
||||
value_2_text = models.TextField(default='Строим долгосрочные отношения...', verbose_name='Текст ценности 2')
|
||||
|
||||
value_3_icon = models.CharField(max_length=50, default='fa-chart-line', verbose_name='Иконка ценности 3')
|
||||
value_3_title = models.CharField(max_length=100, default='Результат', verbose_name='Ценность 3')
|
||||
value_3_text = models.TextField(default='Фокусируемся на достижении целей...', verbose_name='Текст ценности 3')
|
||||
|
||||
value_4_icon = models.CharField(max_length=50, default='fa-shield-alt', verbose_name='Иконка ценности 4')
|
||||
value_4_title = models.CharField(max_length=100, default='Надежность', verbose_name='Ценность 4')
|
||||
value_4_text = models.TextField(default='Гарантируем качество и безопасность...', verbose_name='Текст ценности 4')
|
||||
|
||||
# Contact Section
|
||||
contact_title = models.CharField(max_length=200, default='Готовы начать проект?', verbose_name='Заголовок контактов')
|
||||
contact_description = models.TextField(default='Свяжитесь с нами сегодня...', verbose_name='Описание контактов')
|
||||
|
||||
# Meta
|
||||
is_active = models.BooleanField(default=True, verbose_name='Активна')
|
||||
updated_at = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Страница О нас'
|
||||
verbose_name_plural = 'Страницы О нас'
|
||||
|
||||
def __str__(self):
|
||||
return f"О нас (обновлено: {self.updated_at.strftime('%d.%m.%Y')})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Оставляем только одну активную запись
|
||||
if self.is_active:
|
||||
AboutPage.objects.exclude(pk=self.pk).update(is_active=False)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class FooterSettings(models.Model):
|
||||
"""Настройки футера - все данные управляются из админки"""
|
||||
|
||||
# Company Info
|
||||
company_name = models.CharField(max_length=100, default='SmartSolTech', verbose_name='Название компании')
|
||||
company_description = models.TextField(
|
||||
default='Мы создаем инновационные IT-решения, которые помогают бизнесу расти...',
|
||||
verbose_name='Описание компании'
|
||||
)
|
||||
company_logo_icon = models.CharField(max_length=50, default='fa-code', verbose_name='Иконка компании')
|
||||
|
||||
# Social Links
|
||||
telegram_url = models.URLField(blank=True, verbose_name='Telegram URL')
|
||||
instagram_url = models.URLField(blank=True, verbose_name='Instagram URL')
|
||||
linkedin_url = models.URLField(blank=True, verbose_name='LinkedIn URL')
|
||||
github_url = models.URLField(blank=True, verbose_name='GitHub URL')
|
||||
facebook_url = models.URLField(blank=True, verbose_name='Facebook URL')
|
||||
twitter_url = models.URLField(blank=True, verbose_name='Twitter URL')
|
||||
|
||||
# Contact Info
|
||||
email = models.EmailField(default='info@smartsoltech.kr', verbose_name='Email')
|
||||
phone = models.CharField(max_length=50, default='+82-10-XXXX-XXXX', verbose_name='Телефон')
|
||||
address = models.TextField(default='Seoul, South Korea', verbose_name='Адрес')
|
||||
|
||||
# Services Links (for footer menu)
|
||||
show_services_menu = models.BooleanField(default=True, verbose_name='Показывать меню услуг')
|
||||
services_title = models.CharField(max_length=100, default='Услуги', verbose_name='Заголовок меню услуг')
|
||||
|
||||
# Company Links (for footer menu)
|
||||
show_company_menu = models.BooleanField(default=True, verbose_name='Показывать меню компании')
|
||||
company_menu_title = models.CharField(max_length=100, default='Компания', verbose_name='Заголовок меню компании')
|
||||
|
||||
# Copyright
|
||||
copyright_text = models.CharField(
|
||||
max_length=200,
|
||||
default='© 2025 SmartSolTech. Все права защищены.',
|
||||
verbose_name='Текст Copyright'
|
||||
)
|
||||
|
||||
# Integration Scripts
|
||||
google_analytics = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Google Analytics',
|
||||
help_text='Вставьте код Google Analytics (без тегов <script>)'
|
||||
)
|
||||
|
||||
google_adsense = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Google AdSense',
|
||||
help_text='Вставьте код Google AdSense (без тегов <script>)'
|
||||
)
|
||||
|
||||
yandex_metrika = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Яндекс Метрика',
|
||||
help_text='Вставьте код Яндекс Метрики (без тегов <script>)'
|
||||
)
|
||||
|
||||
facebook_pixel = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Facebook Pixel',
|
||||
help_text='Вставьте код Facebook Pixel (без тегов <script>)'
|
||||
)
|
||||
|
||||
custom_head_scripts = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Скрипты в <head>',
|
||||
help_text='Дополнительные скрипты для вставки в <head> (с тегами <script>)'
|
||||
)
|
||||
|
||||
custom_body_scripts = models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Скрипты перед </body>',
|
||||
help_text='Дополнительные скрипты для вставки перед закрывающим </body> (с тегами <script>)'
|
||||
)
|
||||
|
||||
# Meta
|
||||
is_active = models.BooleanField(default=True, verbose_name='Активно')
|
||||
updated_at = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Настройки футера'
|
||||
verbose_name_plural = 'Настройки футера'
|
||||
|
||||
def __str__(self):
|
||||
return f"Футер (обновлено: {self.updated_at.strftime('%d.%m.%Y')})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Оставляем только одну активную запись
|
||||
if self.is_active:
|
||||
FooterSettings.objects.exclude(pk=self.pk).update(is_active=False)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-6">
|
||||
<span class="badge bg-gradient text-white mb-3 px-3 py-2 rounded-pill">
|
||||
🚀 О нас
|
||||
{{ about.hero_badge|default:"🚀 О нас" }}
|
||||
</span>
|
||||
<h1 class="display-4 fw-bold mb-4">
|
||||
Мы создаем <span class="text-gradient">цифровое будущее</span>
|
||||
{{ about.hero_title|default:"Мы создаем цифровое будущее"|safe }}
|
||||
</h1>
|
||||
<p class="lead text-muted mb-4">
|
||||
SmartSolTech - это команда профессионалов, которые превращают идеи в инновационные IT-решения.
|
||||
Мы помогаем бизнесу расти и развиваться в цифровую эпоху.
|
||||
{{ about.hero_description|default:"SmartSolTech - это команда профессионалов..." }}
|
||||
</p>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<a href="#team" class="btn btn-primary-modern">
|
||||
@@ -40,7 +39,7 @@
|
||||
<div class="stat-icon bg-primary rounded-3 mb-3 mx-auto" style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-code text-white fa-2x"></i>
|
||||
</div>
|
||||
<h3 class="text-gradient fw-bold">50+</h3>
|
||||
<h3 class="text-gradient fw-bold">{{ about.stat_projects|default:"50" }}+</h3>
|
||||
<p class="mb-0 text-muted">Проектов</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +48,7 @@
|
||||
<div class="stat-icon bg-success rounded-3 mb-3 mx-auto" style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-users text-white fa-2x"></i>
|
||||
</div>
|
||||
<h3 class="text-gradient fw-bold">30+</h3>
|
||||
<h3 class="text-gradient fw-bold">{{ about.stat_clients|default:"30" }}+</h3>
|
||||
<p class="mb-0 text-muted">Клиентов</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,7 +57,7 @@
|
||||
<div class="stat-icon bg-warning rounded-3 mb-3 mx-auto" style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-award text-white fa-2x"></i>
|
||||
</div>
|
||||
<h3 class="text-gradient fw-bold">3+</h3>
|
||||
<h3 class="text-gradient fw-bold">{{ about.stat_years|default:"3" }}+</h3>
|
||||
<p class="mb-0 text-muted">Лет опыта</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +66,7 @@
|
||||
<div class="stat-icon bg-info rounded-3 mb-3 mx-auto" style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-rocket text-white fa-2x"></i>
|
||||
</div>
|
||||
<h3 class="text-gradient fw-bold">24/7</h3>
|
||||
<h3 class="text-gradient fw-bold">{{ about.stat_support|default:"24/7" }}</h3>
|
||||
<p class="mb-0 text-muted">Поддержка</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,15 +86,13 @@
|
||||
<div class="col-lg-6">
|
||||
<div class="pe-lg-4">
|
||||
<span class="badge bg-primary text-white mb-3 px-3 py-2 rounded-pill">
|
||||
🎯 Наша миссия
|
||||
{{ about.mission_badge|default:"🎯 Наша миссия" }}
|
||||
</span>
|
||||
<h2 class="display-6 fw-bold mb-4">
|
||||
Делаем технологии <span class="text-gradient">доступными</span>
|
||||
{{ about.mission_title|default:"Делаем технологии доступными"|safe }}
|
||||
</h2>
|
||||
<p class="text-muted mb-4">
|
||||
Мы верим, что каждый бизнес заслуживает доступа к современным технологиям.
|
||||
Наша миссия — демократизировать IT-решения и помочь компаниям любого размера
|
||||
достичь цифрового совершенства.
|
||||
{{ about.mission_description|default:"Мы верим, что каждый бизнес заслуживает..." }}
|
||||
</p>
|
||||
<div class="mission-points">
|
||||
<div class="d-flex align-items-start mb-3">
|
||||
|
||||
@@ -36,6 +36,25 @@
|
||||
<!-- Force unblock script - загружается ПЕРВЫМ для предотвращения блокировки -->
|
||||
<script src="{% static 'assets/js/force-unblock.js' %}"></script>
|
||||
|
||||
<!-- Integration Scripts from Footer Settings -->
|
||||
{% if footer_settings %}
|
||||
{% if footer_settings.google_analytics %}
|
||||
<script>
|
||||
{{ footer_settings.google_analytics|safe }}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if footer_settings.yandex_metrika %}
|
||||
<script>
|
||||
{{ footer_settings.yandex_metrika|safe }}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if footer_settings.custom_head_scripts %}
|
||||
{{ footer_settings.custom_head_scripts|safe }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from .models import Service, Project, Client, BlogPost, Review, Order, ServiceRequest, Category
|
||||
from .models import Service, Project, Client, BlogPost, Review, Order, ServiceRequest, Category, AboutPage, FooterSettings
|
||||
from django.db.models import Avg
|
||||
from comunication.models import TelegramSettings
|
||||
import qrcode
|
||||
@@ -87,7 +87,8 @@ def services_view(request):
|
||||
return render(request, 'web/services_modern.html', context)
|
||||
|
||||
def about_view(request):
|
||||
return render(request, 'web/about_modern.html')
|
||||
about_page = AboutPage.objects.filter(is_active=True).first()
|
||||
return render(request, 'web/about_modern.html', {'about': about_page})
|
||||
|
||||
def create_service_request(request, service_id):
|
||||
if request.method == 'POST':
|
||||
|
||||
Reference in New Issue
Block a user