Игорь Надеин 8b0c853f29 feat: add avatar zoom modal on click
- Added Bootstrap modal for enlarged avatar view
- Made avatar image clickable with cursor pointer
- Added modal trigger to both static and dynamically loaded avatars
- Modal displays full-size avatar centered with dark backdrop
- Close button positioned in top-right corner
2025-12-08 11:07:45 +03:00
..

Структура шаблонов EUSRR

📁 Организация проекта

templates/
├── base.html                  # Базовый layout
├── admin/                     # Административные шаблоны
├── auth/                      # Авторизация, регистрация
├── communications/            # Чаты, сообщения
├── documents/                 # Документы
├── emails/                    # Email-шаблоны
├── employees/                 # Сотрудники, отделы
│   └── components/           # Переиспользуемые компоненты
├── feed/                      # Лента новостей
│   └── includes/             # Компоненты ленты
├── includes/                  # Общие компоненты
│   ├── navbar.html
│   ├── sidebar.html
│   └── calendar/             # Компоненты календаря
├── requests_app/              # Заявления сотрудников
│   └── components/           # Компоненты заявлений
└── search/                    # Поиск

REFACTORING_PLAN.md           # План рефакторинга

🎨 Архитектура

Базовый шаблон (base.html)

Все страницы наследуются от base.html:

{% extends "base.html" %}
{% load static %}

{% block title %}Название страницы{% endblock %}

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/components/my-component.css' %}">
{% endblock %}

{% block content %}
  <!-- Содержимое страницы -->
{% endblock %}

{% block extra_js %}
  <script type="module">
    // JavaScript код
  </script>
{% endblock %}

Структура блоков в base.html

  • {% block title %} - Заголовок страницы
  • {% block extra_css %} - Дополнительные CSS файлы
  • {% block content %} - Основное содержимое
  • {% block extra_js %} - Дополнительные JavaScript файлы

🔧 Компоненты

Общие компоненты (includes/)

navbar.html

Навигационная панель приложения:

  • Логотип
  • Поиск
  • Меню пользователя
  • Уведомления
{% include "includes/navbar.html" %}

sidebar.html

Боковая панель навигации:

  • Меню разделов
  • Профиль пользователя
  • Быстрые ссылки
{% include "includes/sidebar.html" %}

calendar/calendar_styles.html

Стили календаря (подключает CSS):

{% include "includes/calendar/calendar_styles.html" %}

Компоненты сотрудников (employees/components/)

department_styles.html

Стили для колеса команды:

{% include "employees/components/department_styles.html" %}

Компоненты ленты (feed/includes/)

_post_card.html

Карточка поста в ленте:

{% include "feed/includes/_post_card.html" with post=post %}

📝 Именование файлов

Соглашения

  • {model}_list.html - Списки (employees_list.html)
  • {model}_detail.html - Детальные страницы (employee_detail.html)
  • {model}_form.html - Формы создания/редактирования (post_form.html)
  • {model}_confirm_delete.html - Подтверждение удаления
  • components/{name}.html - Переиспользуемые компоненты
  • _{name}.html - Партиалы (только в старых файлах, новые без подчёркивания)

🎯 Использование CSS

Подключение стилей

Всегда используйте {% block extra_css %}:

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/variables.css' %}">
  <link rel="stylesheet" href="{% static 'css/components/employee-list.css' %}">
{% endblock %}

Встроенные стили

❌ Избегайте:

<style>
  .my-class {
    color: red;
  }
</style>

✅ Используйте компоненты:

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/components/my-component.css' %}">
{% endblock %}

🚀 JavaScript

ES6 модули

Используйте ES6 модули для JavaScript:

{% block extra_js %}
<script type="module">
  import { myFunction } from '{% static "js/utils/myModule.js" %}';
  
  document.addEventListener('DOMContentLoaded', () => {
    myFunction();
  });
</script>
{% endblock %}

Встроенные скрипты

❌ Избегайте больших скриптов:

<script>
  // 500 строк кода...
</script>

✅ Создавайте модули:

// static/js/components/myComponent.js
export class MyComponent {
  // ...
}

📦 Переиспользуемые компоненты

Передача контекста

Компоненты получают данные через with:

{% include "includes/avatar.html" with user=employee size="lg" %}

Создание компонента

{# includes/components/avatar.html #}
{% load static %}

<div class="avatar avatar-{{ size|default:'md' }}" 
     title="{{ user.get_full_name }}">
  {% if user.avatar %}
    <img src="{{ user.avatar.url }}" alt="{{ user.get_short_name }}">
  {% else %}
    <i class="bi-person"></i>
  {% endif %}
</div>

✨ Лучшие практики

1. Всегда загружайте static

{% load static %}

2. Используйте CSRF токены

<form method="post">
  {% csrf_token %}
  <!-- ... -->
</form>

3. Безопасный вывод

{{ user.name|escape }}  {# Экранирование HTML #}
{{ post.content|safe }}  {# Только для доверенного контента #}

4. Условный рендеринг

{% if user.is_authenticated %}
  <p>Добро пожаловать, {{ user.get_short_name }}!</p>
{% else %}
  <a href="{% url 'login' %}">Войти</a>
{% endif %}

5. Циклы с empty

{% for employee in employees %}
  <div class="employee-card">{{ employee.name }}</div>
{% empty %}
  <p>Сотрудников не найдено</p>
{% endfor %}

🔍 Отладка

Проверка переменных

<pre>{{ variable|pprint }}</pre>

Debug toolbar

{% if debug %}
  <!-- Контент только для разработки -->
{% endif %}

📊 Статистика рефакторинга

До рефакторинга

  • Файлов: 61
  • Строк кода: 11,479
  • Встроенных CSS: 1,359 строк
  • Встроенных JS: 4,522 строк
  • Дублирующих файлов: 3

После рефакторинга (Фаза 5)

  • Файлов: 58
  • CSS компонентов: 21
  • Встроенных CSS: 0 строк ✅
  • Встроенных JS: ~200 строк
  • Дублирующих файлов: 0 ✅

Улучшения

  • ✅ Устранено 100% дублирования
  • ✅ Извлечено 3,529 строк CSS в компоненты
  • ✅ Создана единая архитектура стилей
  • ✅ Все шаблоны используют централизованные CSS

🚧 Текущие задачи

Фаза 6 (В процессе)

  • ✅ Создать variables.css с полным набором переменных
  • ✅ Документировать CSS структуру
  • ⏳ Документировать JavaScript структуру
  • ⏳ Создать финальный отчёт

🔗 Связанные документы

📞 Контакты

Автор рефакторинга: GitHub Copilot
Дата создания: 28 октября 2025
Версия: 1.0


Быстрый старт

Создание новой страницы

  1. Создайте HTML шаблон:
{# myapp/my_page.html #}
{% extends "base.html" %}
{% load static %}

{% block title %}Моя страница{% endblock %}

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/components/my-component.css' %}">
{% endblock %}

{% block content %}
  <div class="container">
    <h1>Моя страница</h1>
    <!-- Содержимое -->
  </div>
{% endblock %}
{% endblock %}
  1. Создайте CSS компонент (если нужен):
/* static/css/components/my-component.css */
/**
 * my-component.css
 * Описание компонента
 */

.my-class {
  border-radius: var(--feed-radius);
  box-shadow: var(--feed-shadow);
}
  1. Создайте view:
# myapp/views.py
from django.views.generic import TemplateView

class MyPageView(TemplateView):
    template_name = "myapp/my_page.html"
  1. Добавьте URL:
# myapp/urls.py
from django.urls import path
from .views import MyPageView

urlpatterns = [
    path('my-page/', MyPageView.as_view(), name='my_page'),
]

Готово! 🎉