demtemp 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. demtemp/__init__.py +0 -0
  2. demtemp/cli.py +44 -0
  3. demtemp/project_template/manage.py +20 -0
  4. demtemp/project_template/static/css/style.css +178 -0
  5. demtemp/project_template/static/icon/icon.png +0 -0
  6. demtemp/project_template/static/img//342/225/250/320/260/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/223/342/225/250/342/225/234/342/225/250/342/225/233/342/225/250/342/225/2211.jpg +0 -0
  7. demtemp/project_template/static/img//342/225/250/320/260/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/223/342/225/250/342/225/234/342/225/250/342/225/233/342/225/250/342/225/2212.jpg +0 -0
  8. demtemp/project_template/static/img//342/225/250/320/260/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/223/342/225/250/342/225/234/342/225/250/342/225/233/342/225/250/342/225/2213.jpg +0 -0
  9. demtemp/project_template/templates/base.html +86 -0
  10. demtemp/project_template/templates/catalog.html +92 -0
  11. demtemp/project_template/templates/create_appointment.html +37 -0
  12. demtemp/project_template/templates/home.html +129 -0
  13. demtemp/project_template/templates/my_appointments.html +78 -0
  14. demtemp/project_template/templates/registration/login.html +37 -0
  15. demtemp/project_template/templates/registration/register.html +38 -0
  16. demtemp/project_template/templates/services_masters.html +186 -0
  17. demtemp/project_template/testikproject/__init__.py +0 -0
  18. demtemp/project_template/testikproject/asgi.py +16 -0
  19. demtemp/project_template/testikproject/settings.py +125 -0
  20. demtemp/project_template/testikproject/urls.py +22 -0
  21. demtemp/project_template/testikproject/wsgi.py +16 -0
  22. demtemp/project_template/users/__init__.py +0 -0
  23. demtemp/project_template/users/admin.py +32 -0
  24. demtemp/project_template/users/apps.py +5 -0
  25. demtemp/project_template/users/forms.py +95 -0
  26. demtemp/project_template/users/migrations/0001_initial.py +110 -0
  27. demtemp/project_template/users/migrations/__init__.py +0 -0
  28. demtemp/project_template/users/models.py +86 -0
  29. demtemp/project_template/users/tests.py +3 -0
  30. demtemp/project_template/users/urls.py +12 -0
  31. demtemp/project_template/users/views.py +104 -0
  32. demtemp-0.1.1.dist-info/METADATA +16 -0
  33. demtemp-0.1.1.dist-info/RECORD +36 -0
  34. demtemp-0.1.1.dist-info/WHEEL +5 -0
  35. demtemp-0.1.1.dist-info/entry_points.txt +2 -0
  36. demtemp-0.1.1.dist-info/top_level.txt +1 -0
demtemp/__init__.py ADDED
File without changes
demtemp/cli.py ADDED
@@ -0,0 +1,44 @@
1
+ import shutil
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ def main():
6
+ # Текущая папка, где пользователь запустил команду
7
+ target_dir = Path.cwd()
8
+
9
+ # Папка с шаблоном проекта внутри пакета
10
+ template_dir = Path(__file__).parent / 'project_template'
11
+
12
+ if not template_dir.exists():
13
+ print("Ошибка: шаблон проекта не найден.")
14
+ sys.exit(1)
15
+
16
+ print(f"Создание проекта в: {target_dir}")
17
+
18
+ # Копируем всё содержимое template_dir в target_dir
19
+ for item in template_dir.iterdir():
20
+ src = item
21
+ dst = target_dir / item.name
22
+
23
+ if dst.exists():
24
+ print(f"Пропускаем {dst.name} — уже существует")
25
+ continue
26
+
27
+ if item.is_dir():
28
+ shutil.copytree(src, dst)
29
+ print(f"Создана папка {dst.name}")
30
+ else:
31
+ shutil.copy2(src, dst)
32
+ print(f"Создан файл {dst.name}")
33
+
34
+ print("\nПроект успешно создан!")
35
+ print("\nДальнейшие шаги:")
36
+ print(" 1. Создайте виртуальное окружение: python -m venv venv")
37
+ print(" 2. Активируйте его: source venv/bin/activate (Linux/Mac) или venv\\Scripts\\activate (Windows)")
38
+ print(" 3. Установите зависимости: pip install -r requirements.txt")
39
+ print(" 4. Выполните миграции: python manage.py migrate")
40
+ print(" 5. Создайте суперпользователя: python manage.py createsuperuser")
41
+ print(" 6. Запустите сервер: python manage.py runserver")
42
+
43
+ if __name__ == '__main__':
44
+ main()
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env python
2
+ """Django's command-line utility for administrative tasks."""
3
+ import os
4
+ import sys
5
+
6
+ def main():
7
+ """Run administrative tasks."""
8
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testikproject.settings')
9
+ try:
10
+ from django.core.management import execute_from_command_line
11
+ except ImportError as exc:
12
+ raise ImportError(
13
+ "Couldn't import Django. Are you sure it's installed and "
14
+ "available on your PYTHONPATH environment variable? Did you "
15
+ "forget to activate a virtual environment?"
16
+ ) from exc
17
+ execute_from_command_line(sys.argv)
18
+
19
+ if __name__ == '__main__':
20
+ main()
@@ -0,0 +1,178 @@
1
+ :root {
2
+ --sharp-bg: #f5f1ea;
3
+ --sharp-dark: #171717;
4
+ --sharp-gold: #b8894a;
5
+ --sharp-muted: #6f6a61;
6
+ --sharp-soft: #fffaf2;
7
+ }
8
+ body {
9
+ min-height: 100vh;
10
+ color: var(--sharp-dark);
11
+ background: var(--sharp-bg);
12
+ }
13
+ .brand-mark {
14
+ display: inline-grid;
15
+ width: 42px;
16
+ height: 42px;
17
+ place-items: center;
18
+ border-radius: 14px;
19
+ color: #fff;
20
+ background: var(--sharp-dark);
21
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
22
+ }
23
+ .nav-link,
24
+ .btn,
25
+ .card-sharp,
26
+ .form-control,
27
+ .form-select {
28
+ transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease, background-color .2s ease;
29
+ }
30
+ .nav-link:hover {
31
+ color: var(--sharp-gold) !important;
32
+ transform: translateY(-1px);
33
+ }
34
+ .btn:hover {
35
+ transform: translateY(-2px);
36
+ }
37
+ .hero-carousel {
38
+ border-radius: 2rem;
39
+ overflow: hidden;
40
+ background: #111;
41
+ }
42
+ .carousel-img {
43
+ height: 520px;
44
+ object-fit: cover;
45
+ display: block;
46
+ }
47
+ .carousel-overlay {
48
+ position: absolute;
49
+ top: 0;
50
+ left: 0;
51
+ width: 100%;
52
+ height: 100%;
53
+ background: rgba(0, 0, 0, 0.55);
54
+ pointer-events: none;
55
+ z-index: 5;
56
+ }
57
+ .carousel-caption {
58
+ right: auto;
59
+ bottom: 3rem;
60
+ left: 3rem;
61
+ max-width: 640px;
62
+ z-index: 10;
63
+ }
64
+ .card-sharp:hover {
65
+ transform: translateY(-6px);
66
+ box-shadow: 0 1rem 2.5rem rgba(23, 23, 23, 0.12) !important;
67
+ }
68
+ .avatar-circle {
69
+ display: grid;
70
+ width: 58px;
71
+ height: 58px;
72
+ place-items: center;
73
+ border-radius: 50%;
74
+ color: #fff;
75
+ background: var(--sharp-dark);
76
+ font-size: 1.35rem;
77
+ font-weight: 800;
78
+ }
79
+ .form-control:focus,
80
+ .form-select:focus {
81
+ border-color: var(--sharp-gold);
82
+ box-shadow: 0 0 0 .25rem rgba(184, 137, 74, .18);
83
+ }
84
+ .status-badge {
85
+ display: inline-flex;
86
+ align-items: center;
87
+ height: 28px;
88
+ padding: 0 .65rem;
89
+ border-radius: 999px;
90
+ white-space: nowrap;
91
+ font-size: .78rem;
92
+ font-weight: 800;
93
+ }
94
+ .status-new {
95
+ color: #75510f;
96
+ background: #fff1c2;
97
+ }
98
+ .status-confirmed {
99
+ color: #0b5d4f;
100
+ background: #d7f8ef;
101
+ }
102
+ .status-client_arrived {
103
+ color: #073b79;
104
+ background: #d8e9ff;
105
+ }
106
+ .status-completed {
107
+ color: #155724;
108
+ background: #dff5e6;
109
+ }
110
+ .status-cancelled {
111
+ color: #842029;
112
+ background: #f8d7da;
113
+ }
114
+ .fade-up {
115
+ animation: fadeUp .55s ease both;
116
+ }
117
+ .error-pop,
118
+ .sharp-alert {
119
+ animation: fadeIn .25s ease both;
120
+ }
121
+ @keyframes fadeUp {
122
+ from {
123
+ opacity: 0;
124
+ transform: translateY(18px);
125
+ }
126
+ to {
127
+ opacity: 1;
128
+ transform: translateY(0);
129
+ }
130
+ }
131
+ @keyframes fadeIn {
132
+ from { opacity: 0; }
133
+ to { opacity: 1; }
134
+ }
135
+ .navbar-dark .navbar-nav .nav-link.active {
136
+ color: #fff !important;
137
+ background: rgba(255, 255, 255, 0.15);
138
+ border-radius: 40px;
139
+ }
140
+ .navbar-dark .navbar-nav .nav-link:hover {
141
+ color: #f8f9fa !important;
142
+ }
143
+ footer.bg-dark {
144
+ background-color: #171717 !important;
145
+ }
146
+ @media (max-width: 576px) {
147
+ .container {
148
+ width: min(100% - 24px, 390px);
149
+ }
150
+ .navbar-brand {
151
+ font-size: 1rem;
152
+ }
153
+ .brand-mark {
154
+ width: 38px;
155
+ height: 38px;
156
+ border-radius: 12px;
157
+ }
158
+ .carousel-img {
159
+ height: 340px;
160
+ }
161
+ .carousel-caption {
162
+ left: 1.25rem;
163
+ right: 1.25rem;
164
+ bottom: 2rem;
165
+ }
166
+ .carousel-caption .display-5,
167
+ .carousel-caption .display-6 {
168
+ font-size: 1.8rem;
169
+ }
170
+ .carousel-caption .lead {
171
+ font-size: 0.95rem;
172
+ }
173
+ .auth-page {
174
+ min-height: calc(100vh - 140px);
175
+ display: grid;
176
+ align-items: center;
177
+ }
178
+ }
@@ -0,0 +1,86 @@
1
+ {% load static %}
2
+ <!doctype html>
3
+ <html lang="ru">
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <title>{% block title %}Sharp Cut{% endblock %}</title>
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
10
+ <link rel="stylesheet" href="{% static 'css/style.css' %}">
11
+ <link rel="icon" href="{% static 'icon/icon.png' %}" type="image/png">
12
+ {% block extra_head %}{% endblock %}
13
+ </head>
14
+ <body>
15
+ <header class="sticky-top shadow">
16
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
17
+ <div class="container py-2">
18
+ <a class="navbar-brand fw-bold d-flex align-items-center gap-2" href="{% url 'home' %}">
19
+ <span class="brand-mark">SC</span>
20
+ <span>Sharp Cut</span>
21
+ </a>
22
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNav">
23
+ <span class="navbar-toggler-icon"></span>
24
+ </button>
25
+ <div class="collapse navbar-collapse" id="mainNav">
26
+ <ul class="navbar-nav ms-auto align-items-lg-center gap-lg-2">
27
+ <li class="nav-item">
28
+ <a class="nav-link {% if request.resolver_match.url_name == 'home' %}active{% endif %}"
29
+ href="{% url 'home' %}">Главная</a>
30
+ </li>
31
+ <li class="nav-item">
32
+ <a class="nav-link {% if request.resolver_match.url_name == 'catalog' %}active{% endif %}"
33
+ href="{% url 'catalog' %}">Каталог</a>
34
+ </li>
35
+ {% if user.is_authenticated %}
36
+ <li class="nav-item">
37
+ <a class="nav-link {% if request.resolver_match.url_name == 'appointment_create' %}active{% endif %}"
38
+ href="{% url 'appointment_create' %}">Записаться</a>
39
+ </li>
40
+ <li class="nav-item">
41
+ <a class="nav-link {% if request.resolver_match.url_name == 'my_appointments' %}active{% endif %}"
42
+ href="{% url 'my_appointments' %}">Мои записи</a>
43
+ </li>
44
+ <li class="nav-item">
45
+ <a class="btn btn-outline-light rounded-pill px-3" href="{% url 'logout' %}">Выйти</a>
46
+ </li>
47
+ {% else %}
48
+ <li class="nav-item">
49
+ <a class="nav-link {% if request.resolver_match.url_name == 'login' %}active{% endif %}"
50
+ href="{% url 'login' %}">Авторизация</a>
51
+ </li>
52
+ <li class="nav-item">
53
+ <a class="btn btn-outline-light rounded-pill px-3" href="{% url 'register' %}">Регистрация</a>
54
+ </li>
55
+ {% endif %}
56
+ <li class="nav-item">
57
+ <a class="nav-link" href="/admin/">Админка</a>
58
+ </li>
59
+ </ul>
60
+ </div>
61
+ </div>
62
+ </nav>
63
+ </header>
64
+ {% if messages %}
65
+ <section class="container mt-3">
66
+ {% for message in messages %}
67
+ <div class="alert alert-{{ message.tags|default:'info' }} alert-dismissible fade show sharp-alert" role="alert">
68
+ {{ message }}
69
+ <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Закрыть"></button>
70
+ </div>
71
+ {% endfor %}
72
+ </section>
73
+ {% endif %}
74
+ <main>
75
+ {% block content %}{% endblock %}
76
+ </main>
77
+ <footer class="bg-dark text-white-50 py-4 mt-5 border-top border-secondary">
78
+ <div class="container d-flex flex-column flex-md-row justify-content-between gap-2 small">
79
+ <span>Sharp Cut — барбершоп онлайн-записи</span>
80
+ <span>SharpCut Ltg. Все права защищены</span>
81
+ </div>
82
+ </footer>
83
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
84
+ {% block extra_scripts %}{% endblock %}
85
+ </body>
86
+ </html>
@@ -0,0 +1,92 @@
1
+ {% extends 'base.html' %}
2
+ {% load static %}
3
+ {% block title %}Каталог — Sharp Cut{% endblock %}
4
+ {% block content %}
5
+ <section class="container py-4">
6
+ <div class="d-flex flex-column flex-lg-row justify-content-between gap-3 mb-4 fade-up">
7
+ <div>
8
+ <span class="text-uppercase small fw-bold text-muted">Каталог</span>
9
+ <h1 class="display-6 fw-bold mb-2">Услуги и мастера</h1>
10
+ <p class="text-muted mb-0">Выберите услугу, посмотрите мастеров и перейдите к оформлению записи.</p>
11
+ </div>
12
+ <div class="align-self-lg-end">
13
+ {% if user.is_authenticated %}
14
+ <a class="btn btn-dark rounded-pill px-4" href="{% url 'appointment_create' %}">Оформить запись</a>
15
+ {% else %}
16
+ <a class="btn btn-outline-dark rounded-pill px-4" href="{% url 'login' %}">Войти для записи</a>
17
+ {% endif %}
18
+ </div>
19
+ </div>
20
+ <div class="d-flex flex-wrap align-items-center justify-content-between bg-white rounded-5 shadow-sm p-3 p-md-4 my-4 fade-up">
21
+ <div class="filter-group d-flex flex-wrap gap-2">
22
+ <a href="?available=" class="btn btn-outline-dark rounded-pill {% if not availability %}active{% endif %}">Все</a>
23
+ <a href="?available=1" class="btn btn-outline-dark rounded-pill {% if availability == '1' %}active{% endif %}">Доступные</a>
24
+ </div>
25
+ <form method="get" class="d-flex gap-2">
26
+ <label>
27
+ <input class="form-control rounded-pill" type="search" name="q" value="{{ query }}" placeholder="Поиск услуги...">
28
+ </label>
29
+ <button class="btn btn-dark rounded-pill" type="submit">Найти</button>
30
+ </form>
31
+ </div>
32
+ <h2 class="h3 fw-bold mb-3 fade-up">Услуги</h2>
33
+ <div class="row g-4 mb-5">
34
+ {% for service in services %}
35
+ <div class="col-12 col-md-6 col-xl-4 fade-up">
36
+ <article class="card card-sharp border-0 shadow-sm rounded-5 h-100">
37
+ <div class="card-body p-4 d-flex flex-column">
38
+ <div class="d-flex justify-content-between gap-2 mb-3">
39
+ <h3 class="h5 fw-bold mb-0">{{ service.name }}</h3>
40
+ {% if service.is_available %}
41
+ <span class="badge text-bg-success rounded-pill align-self-start">Доступна</span>
42
+ {% else %}
43
+ <span class="badge text-bg-secondary rounded-pill align-self-start">Недоступна</span>
44
+ {% endif %}
45
+ </div>
46
+ <p class="text-muted flex-grow-1">{{ service.description }}</p>
47
+ <div class="d-flex justify-content-between align-items-center border-top pt-3">
48
+ <div>
49
+ <div class="fw-bold fs-5">{{ service.price }} ₽</div>
50
+ <div class="text-muted small">{{ service.duration }} минут</div>
51
+ </div>
52
+ {% if service.is_available and user.is_authenticated %}
53
+ <a class="btn btn-outline-dark rounded-pill" href="{% url 'appointment_create' %}?service={{ service.id }}">Записаться</a>
54
+ {% elif service.is_available %}
55
+ <a class="btn btn-outline-dark rounded-pill" href="{% url 'login' %}">Войти</a>
56
+ {% else %}
57
+ <button class="btn btn-outline-secondary rounded-pill" disabled>Недоступна</button>
58
+ {% endif %}
59
+ </div>
60
+ </div>
61
+ </article>
62
+ </div>
63
+ {% empty %}
64
+ <div class="col-12"><div class="alert alert-info rounded-4">Услуги не найдены.</div></div>
65
+ {% endfor %}
66
+ </div>
67
+ <h2 class="h3 fw-bold mb-3 fade-up">Мастера</h2>
68
+ <div class="row g-4 mb-5">
69
+ {% for master in masters %}
70
+ <div class="col-12 col-md-6 col-xl-3 fade-up">
71
+ <article class="card card-sharp border-0 shadow-sm rounded-5 h-100">
72
+ <div class="card-body p-4">
73
+ <div class="avatar-circle mb-3">{{ master.name|first }}</div>
74
+ <h3 class="h5 fw-bold mb-1">{{ master.name }}</h3>
75
+ <p class="text-muted mb-3">{{ master.specialization }}</p>
76
+ <div class="d-flex justify-content-between align-items-center">
77
+ <span class="small fw-semibold">Опыт: {{ master.experience }} лет</span>
78
+ {% if master.is_active %}
79
+ <span class="badge text-bg-success rounded-pill">Активен</span>
80
+ {% else %}
81
+ <span class="badge text-bg-secondary rounded-pill">Неактивен</span>
82
+ {% endif %}
83
+ </div>
84
+ </div>
85
+ </article>
86
+ </div>
87
+ {% empty %}
88
+ <div class="col-12"><div class="alert alert-info rounded-4">Мастера не добавлены.</div></div>
89
+ {% endfor %}
90
+ </div>
91
+ </section>
92
+ {% endblock %}
@@ -0,0 +1,37 @@
1
+ {% extends 'base.html' %}
2
+ {% block title %}Оформление записи — Sharp Cut{% endblock %}
3
+ {% block content %}
4
+ <section class="container py-5">
5
+ <div class="row justify-content-center">
6
+ <div class="col-12 col-lg-7">
7
+ <div class="card border-0 shadow-sm rounded-5 fade-up">
8
+ <div class="card-body p-4 p-md-5">
9
+ <span class="text-uppercase small fw-bold text-muted">Онлайн-запись</span>
10
+ <h1 class="h2 fw-bold mt-2 mb-3">Оформление записи</h1>
11
+ <p class="text-muted">Выберите услугу, активного мастера, дату и время визита.</p>
12
+ <form method="post" class="vstack gap-3" novalidate>
13
+ {% csrf_token %}
14
+ {% for field in form %}
15
+ <div>
16
+ <label class="form-label fw-semibold" for="{{ field.id_for_label }}">{{ field.label }}</label>
17
+ {{ field }}
18
+ {% if field.help_text %}<div class="form-text">{{ field.help_text }}</div>{% endif %}
19
+ {% for error in field.errors %}
20
+ <div class="invalid-feedback d-block error-pop">{{ error }}</div>
21
+ {% endfor %}
22
+ </div>
23
+ {% endfor %}
24
+ {% for error in form.non_field_errors %}
25
+ <div class="alert alert-danger error-pop">{{ error }}</div>
26
+ {% endfor %}
27
+ <div class="d-grid d-sm-flex gap-2">
28
+ <button class="btn btn-dark rounded-pill px-4" type="submit">Записаться</button>
29
+ <a class="btn btn-outline-dark rounded-pill px-4" href="{% url 'catalog' %}">Назад к услугам</a>
30
+ </div>
31
+ </form>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </section>
37
+ {% endblock %}
@@ -0,0 +1,129 @@
1
+ {% extends 'base.html' %}
2
+ {% load static %}
3
+ {% block title %}Sharp Cut — главная{% endblock %}
4
+ {% block content %}
5
+ <section class="container py-4">
6
+ <div id="sharpCutCarousel" class="carousel slide hero-carousel shadow-lg mb-4" data-bs-ride="carousel" data-bs-interval="4000">
7
+ <div class="carousel-indicators">
8
+ <button type="button" data-bs-target="#sharpCutCarousel" data-bs-slide-to="0" class="active"></button>
9
+ <button type="button" data-bs-target="#sharpCutCarousel" data-bs-slide-to="1"></button>
10
+ <button type="button" data-bs-target="#sharpCutCarousel" data-bs-slide-to="2"></button>
11
+ </div>
12
+ <div class="carousel-inner rounded-5 overflow-hidden">
13
+ <div class="carousel-item active">
14
+ <img src="{% static 'img/Рисунок1.jpg' %}" class="d-block w-100 carousel-img" alt="Стрижка">
15
+ <div class="carousel-overlay"></div>
16
+ <div class="carousel-caption text-start">
17
+ <span class="badge text-bg-light mb-2">Sharp Cut</span>
18
+ <h1 class="display-5 fw-bold">Онлайн-запись в барбершоп</h1>
19
+ <p class="lead">Выберите услугу, мастера и удобное время визита.</p>
20
+ </div>
21
+ </div>
22
+ <div class="carousel-item">
23
+ <img src="{% static 'img/Рисунок2.jpg' %}" class="d-block w-100 carousel-img" alt="Мастер">
24
+ <div class="carousel-overlay"></div>
25
+ <div class="carousel-caption text-start">
26
+ <span class="badge text-bg-light mb-2">Мастера</span>
27
+ <h2 class="display-6 fw-bold">Опытные специалисты</h2>
28
+ <p class="lead">На странице каталога можно посмотреть мастеров и их специализацию.</p>
29
+ </div>
30
+ </div>
31
+ <div class="carousel-item">
32
+ <img src="{% static 'img/Рисунок3.jpg' %}" class="d-block w-100 carousel-img" alt="Запись">
33
+ <div class="carousel-overlay"></div>
34
+ <div class="carousel-caption text-start">
35
+ <span class="badge text-bg-light mb-2">Личный кабинет</span>
36
+ <h2 class="display-6 fw-bold">Контроль статуса записи</h2>
37
+ <p class="lead">После записи клиент видит статус визита в личном кабинете.</p>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ <button class="carousel-control-prev" type="button" data-bs-target="#sharpCutCarousel" data-bs-slide="prev">
42
+ <span class="carousel-control-prev-icon"></span>
43
+ </button>
44
+ <button class="carousel-control-next" type="button" data-bs-target="#sharpCutCarousel" data-bs-slide="next">
45
+ <span class="carousel-control-next-icon"></span>
46
+ </button>
47
+ </div>
48
+ <div class="row text-center g-3 my-4">
49
+ <div class="col-6 col-md-3 fade-up">
50
+ <div class="stat-box p-3 bg-white rounded-4 shadow-sm">
51
+ <div class="display-6 fw-bold">{{ clients_count|default:"5000" }}+</div>
52
+ <div class="text-muted">Довольных клиентов</div>
53
+ </div>
54
+ </div>
55
+ <div class="col-6 col-md-3 fade-up">
56
+ <div class="stat-box p-3 bg-white rounded-4 shadow-sm">
57
+ <div class="display-6 fw-bold">{{ years_on_market|default:"10" }}+</div>
58
+ <div class="text-muted">Лет на рынке</div>
59
+ </div>
60
+ </div>
61
+ <div class="col-6 col-md-3 fade-up">
62
+ <div class="stat-box p-3 bg-white rounded-4 shadow-sm">
63
+ <div class="display-6 fw-bold">{{ active_masters_count|default:"4" }}</div>
64
+ <div class="text-muted">Профессиональных мастера</div>
65
+ </div>
66
+ </div>
67
+ <div class="col-6 col-md-3 fade-up">
68
+ <div class="stat-box p-3 bg-white rounded-4 shadow-sm">
69
+ <div class="display-6 fw-bold">{{ positive_percent|default:"98" }}%</div>
70
+ <div class="text-muted">Положительных отзывов</div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ <div class="my-5 fade-up">
75
+ <h3 class="text-center fw-bold mb-4">Почему выбирают нас</h3>
76
+ <div class="row g-3">
77
+ <div class="col-md-3">
78
+ <div class="feature-item p-3 bg-white rounded-4 shadow-sm text-center">
79
+ <i class="fas fa-user-tie fs-1 text-dark"></i>
80
+ <h6 class="fw-bold mt-2">Опытные мастера</h6>
81
+ <p class="small text-muted">Наши барьеры имеют более 5 лет опыта и регулярно повышают квалификацию</p>
82
+ </div>
83
+ </div>
84
+ <div class="col-md-3">
85
+ <div class="feature-item p-3 bg-white rounded-4 shadow-sm text-center">
86
+ <i class="fas fa-flask fs-1 text-dark"></i>
87
+ <h6 class="fw-bold mt-2">Премиум материалы</h6>
88
+ <p class="small text-muted">Используем только профессиональную косметику ведущих мировых брендов</p>
89
+ </div>
90
+ </div>
91
+ <div class="col-md-3">
92
+ <div class="feature-item p-3 bg-white rounded-4 shadow-sm text-center">
93
+ <i class="fas fa-calendar-check fs-1 text-dark"></i>
94
+ <h6 class="fw-bold mt-2">Удобная запись</h6>
95
+ <p class="small text-muted">Онлайн-бронирование в любое удобное время без звонков и ожидания</p>
96
+ </div>
97
+ </div>
98
+ <div class="col-md-3">
99
+ <div class="feature-item p-3 bg-white rounded-4 shadow-sm text-center">
100
+ <i class="fas fa-coffee fs-1 text-dark"></i>
101
+ <h6 class="fw-bold mt-2">Комфортная атмосфера</h6>
102
+ <p class="small text-muted">Современный интерьер, кофе и приятная музыка во время стрижки</p>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ <div class="row align-items-center bg-white rounded-5 shadow-sm p-4 p-md-5 my-5 fade-up">
108
+ <div class="col-md-6">
109
+ <h2 class="fw-bold">О нас</h2>
110
+ <p class="text-muted">
111
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
112
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
113
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
114
+ </p>
115
+ <p class="text-muted">
116
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
117
+ </p>
118
+ </div>
119
+ <div class="col-md-6 text-center">
120
+ <img src="{% static '' %}" alt="О нас" class="img-fluid rounded-4 shadow" style="max-height: 300px; object-fit: cover;">
121
+ </div>
122
+ </div>
123
+ <div class="text-center bg-white rounded-5 shadow-sm p-4 p-md-5 fade-up">
124
+ <h3 class="fw-bold">Готовы к новому образу?</h3>
125
+ <p class="text-muted">Запишитесь онлайн за 1 минуту и выберите удобное время</p>
126
+ <a href="{% url 'appointment_create' %}" class="btn btn-dark rounded-pill px-5 py-2">Записаться онлайн</a>
127
+ </div>
128
+ </section>
129
+ {% endblock %}