Corp/POLL_VOTERS_LIST.md

5.8 KiB
Raw Blame History

Список проголосовавших в голосованиях

Описание функциональности

Добавлена возможность просмотра списка пользователей, проголосовавших за каждый вариант ответа в не анонимных голосованиях.

Как это работает

Условия отображения

  1. Голосование НЕ анонимное (is_anonymous = false)
  2. За вариант проголосовал хотя бы 1 человек (vote_count > 0)
  3. Пользователь уже проголосовал ИЛИ голосование закрыто (показываются результаты)

UI компоненты

Кликабельная ссылка

Под каждым вариантом ответа отображается кликабельная ссылка:

🔽 3 проголосовало

Раскрывающийся список

При клике на ссылку показывается список проголосовавших:

🔽 3 проголосовало
   👤 Иван Петров
   👤 Мария Сидорова
   👤 Алексей Иванов

Стрелка меняется на 🔼 когда список открыт.

Анимация

  • Плавное появление списка (slide down)
  • Изменение цвета ссылки при наведении
  • Поворот иконки стрелки

Технические детали

Backend изменения

backend/communications/models.py

Метод Poll.get_results() теперь возвращает:

{
    'id': self.id,  # ← Добавлен ID голосования
    'options': [
        {
            'voters': [] if self.is_anonymous else [
                {
                    'voter__id': 123,
                    'voter__first_name': 'Иван',
                    'voter__last_name': 'Петров',
                    'voter__email': 'ivan@example.com'
                }
            ]
        }
    ]
}

Frontend изменения

backend/static/js/components/chatPoll.js

  1. Обработчик клика - добавлен в bindEvents():
const votersToggle = e.target.closest('.poll-voters-toggle');
if (votersToggle) {
    // Показать/скрыть список
    votersList.style.display = isVisible ? 'none' : 'block';
}
  1. Рендеринг списка - обновлен в updatePollWidget():
const voters = option.voters || [];
if (!results.is_anonymous && voters.length > 0) {
    votersHtml = `
        <div class="poll-voters">
            <a href="#" class="poll-voters-toggle">
                <i class="bi-chevron-down"></i>
                ${voteCount} проголосовало
            </a>
            <div class="poll-voters-list" style="display: none;">
                ${voters.map(voter => `
                    <div class="voter-item">
                        <i class="bi-person-fill"></i>
                        ${voter.voter__first_name} ${voter.voter__last_name}
                    </div>
                `).join('')}
            </div>
        </div>
    `;
}
  1. Статический рендеринг - обновлен в renderPoll() с той же логикой

backend/static/css/components/chat-polls.css

Добавлены стили:

  • .poll-voters - контейнер
  • .poll-voters-toggle - кликабельная ссылка с hover эффектом
  • .poll-voters-list - раскрывающийся список с анимацией
  • .voter-item - элемент списка с иконкой
  • @keyframes slideDown - анимация появления

Примеры использования

Анонимное голосование

Вариант 1       45%
█████████░░░░░
3 голоса

Список проголосовавших НЕ показывается.

Не анонимное голосование (с результатами)

✅ Вариант 1       45%
█████████░░░░░
🔽 3 проголосовало    ← Кликабельно!

После клика:

✅ Вариант 1       45%
█████████░░░░░
🔼 3 проголосовало
   👤 Иван Петров
   👤 Мария Сидорова
   👤 Алексей Иванов

Совместимость

  • ✅ Работает с существующими голосованиями
  • ✅ Совместимо с множественным выбором
  • ✅ Совместимо с викторинами
  • ✅ Работает в темной теме
  • ✅ Адаптивный дизайн для мобильных устройств

Безопасность

  • Список проголосовавших показывается только для не анонимных голосований
  • Данные берутся из backend с проверкой доступа к чату
  • Email пользователей не отображается в UI (только имя/фамилия)

Будущие улучшения

Возможные дополнения:

  • Аватары пользователей рядом с именами
  • Ссылки на профили пользователей
  • Индикация времени голосования каждого пользователя
  • Фильтрация/поиск по списку проголосовавших (для больших списков)
  • Группировка пользователей по отделам/ролям