Загрузка данных


{% extends "base.html" %}
{% block title %}{{ intern.full_name }}{% endblock %}

{% block content %}
<!-- Шапка профиля стажёра -->
<div class="d-flex justify-content-between align-items-start mb-3 flex-wrap gap-2">
  <div>
    <a href="{{ url_for('interns.list_interns') }}" class="btn btn-sm btn-outline-secondary mb-2">
      <i class="bi bi-arrow-left"></i> К списку
    </a>
    <h4 class="mb-1">
      {{ intern.full_name }}
      {% if intern.internship_type == 'online' %}
        <span class="badge bg-info fs-6 align-middle ms-2">Дистанционно</span>
      {% else %}
        <span class="badge bg-secondary fs-6 align-middle ms-2">Очно</span>
      {% endif %}
    </h4>
    <small class="text-muted">
      {{ intern.direction or 'Направление не указано' }} · Наставник: {{ intern.mentor.full_name if intern.mentor else '—' }}
    </small>
  </div>
  <div class="d-flex gap-2">
    <a class="btn btn-success" href="{{ url_for('reports.export_excel', date_from=date_from, date_to=date_to) }}">
      <i class="bi bi-file-earmark-excel"></i> Excel
    </a>
    {% if current_user.is_center %}
    <form method="post" action="{{ url_for('interns.archive_intern', intern_id=intern.id) }}" onsubmit="return confirm('Отправить стажёра в архив?');">
      <button type="submit" class="btn btn-outline-danger">
        <i class="bi bi-archive"></i> В архив
      </button>
    </form>
    {% endif %}
  </div>
</div>

<!-- Карточки со статистикой за 30 дней -->
<div class="row g-3 mb-4">
  <div class="col-6 col-md-3">
    <div class="card stat-card h-100"><div class="card-body">
      <div class="text-muted small">Посещаемость (30 дн.)</div>
      <div class="fs-3 fw-bold text-primary">{{ stats_period.rate }}%</div>
    </div></div>
  </div>
  <div class="col-6 col-md-3">
    <div class="card stat-card h-100"><div class="card-body">
      <div class="text-muted small">Присутствовал</div>
      <div class="fs-4 fw-bold text-success">{{ stats_period.present }}</div>
    </div></div>
  </div>
  <div class="col-6 col-md-3">
    <div class="card stat-card h-100"><div class="card-body">
      <div class="text-muted small">Опоздал / Отсутствовал</div>
      <div class="fs-4 fw-bold">
        <span class="text-warning">{{ stats_period.late }}</span> /
        <span class="text-danger">{{ stats_period.absent }}</span>
      </div>
    </div></div>
  </div>
  <div class="col-6 col-md-3">
    <div class="card stat-card h-100"><div class="card-body">
      <div class="text-muted small">Всего отметок (за всё время)</div>
      <div class="fs-4 fw-bold">{{ stats_all.total }}</div>
    </div></div>
  </div>
</div>

<div class="row mb-4">
  <!-- График посещаемости -->
  <div class="col-md-5">
    <div class="card stat-card h-100">
      <div class="card-body">
        <h6 class="card-title mb-3">Распределение статусов (всё время)</h6>
        <div style="height: 220px; position: relative;">
          <canvas id="attendanceChart"></canvas>
        </div>
      </div>
    </div>
  </div>

  <!-- Календарь -->
  <div class="col-md-7">
    <div class="card stat-card h-100">
      <div class="card-body">
        <!-- Навигация по календарю (стрелки) -->
        <div class="d-flex justify-content-between align-items-center mb-3">
          <a class="btn btn-outline-primary btn-sm" href="?year={{ prev_year }}&month={{ prev_month }}">
            <i class="bi bi-chevron-left"></i> {{ MONTH_NAMES[prev_month] }}
          </a>
          <h5 class="mb-0">{{ MONTH_NAMES[month] }} {{ year }}</h5>
          <a class="btn btn-outline-primary btn-sm" href="?year={{ next_year }}&month={{ next_month }}">
            {{ MONTH_NAMES[next_month] }} <i class="bi bi-chevron-right"></i>
          </a>
        </div>

        <!-- Пресеты по месяцам -->
        <div class="mb-3 d-flex flex-wrap gap-1 justify-content-center">
          {% for m in range(1, 13) %}
            <a href="?year={{ year }}&month={{ m }}" 
               class="btn btn-sm {{ 'btn-primary' if m == month else 'btn-outline-secondary' }} px-2 py-1" 
               style="font-size: 0.75rem;">
              {{ MONTH_NAMES[m][:3] }}
            </a>
          {% endfor %}
        </div>

        <!-- Сетка календаря -->
        <div class="table-responsive">
          <table class="table table-bordered calendar-table mb-0">
            <thead>
              <tr class="text-center table-light">
                <th>Пн</th><th>Вт</th><th>Ср</th><th>Чт</th><th>Пт</th>
                <th class="text-muted">Сб</th><th class="text-muted">Вс</th>
              </tr>
            </thead>
            <tbody>
              {% for week in weeks %}
              <tr>
                {% for day in week %}
                  {% set is_current = (day.month == month) %}
                  {% set record = att_map.get(day.day) if is_current else None %}
                  <td class="{{ '' if is_current else 'empty' }}
                             {% if is_current %}calendar-cell{% endif %}
                             {% if is_current and day == today %}today{% endif %}"
                      {% if is_current %}
                        data-date="{{ day.isoformat() }}"
                        data-intern="{{ intern.id }}"
                        data-status="{{ record.status if record else '' }}"
                      {% endif %}>
                    {% if is_current %}
                      <div class="d-flex justify-content-between align-items-start">
                        <span class="day-number">{{ day.day }}</span>
                        {% if record %}
                          <span class="badge bg-{{ STATUS_COLORS[record.status] }} status-badge" title="{{ STATUS_LABELS[record.status] }}">
                            {{ record.status[0]|upper }}
                          </span>
                        {% endif %}
                      </div>
                      {% if record and record.note %}
                        <div class="note text-truncate" title="{{ record.note }}">{{ record.note }}</div>
                      {% endif %}
                    {% endif %}
                  </td>
                {% endfor %}
              </tr>
              {% endfor %}
            </tbody>
          </table>
        </div>

        <!-- Легенда -->
        <div class="mt-3 d-flex flex-wrap gap-2 small text-muted">
          {% for key, label in STATUS_LABELS.items() %}
            <div><span class="badge bg-{{ STATUS_COLORS[key] }}">&nbsp;</span> {{ label }}</div>
          {% endfor %}
        </div>

      </div>
    </div>
  </div>
</div>

<!-- Модалка отметки -->
<div class="modal fade" id="markModal" tabindex="-1">
  <div class="modal-dialog">
    <form method="post" action="{{ url_for('attendance.mark') }}" class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Отметка посещаемости</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body">
        <input type="hidden" name="intern_id" value="{{ intern.id }}">
        <input type="hidden" name="date" id="markDate">
        <p class="mb-3">Дата: <strong id="markDateLabel"></strong></p>

        <div class="mb-3">
          <label class="form-label">Статус</label>
          <select name="status" id="markStatus" class="form-select" required>
            <option value="present">Присутствовал</option>
            <option value="absent">Отсутствовал</option>
            <option value="late">Опоздал</option>
            <option value="excused">Уважительная причина</option>
          </select>
        </div>
        <div class="mb-2">
          <label class="form-label">Заметка (необязательно)</label>
          <input type="text" name="note" class="form-control" maxlength="255">
        </div>
      </div>
      <div class="modal-footer justify-content-between">
        <button type="submit" class="btn btn-outline-danger"
                formaction="{{ url_for('attendance.clear') }}"
                onclick="return confirm('Удалить отметку за этот день?')">
          <i class="bi bi-trash"></i> Удалить
        </button>
        <div>
          <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Отмена</button>
          <button type="submit" class="btn btn-primary">Сохранить</button>
        </div>
      </div>
    </form>
  </div>
</div>
{% endblock %}

{% block scripts %}
<!-- Подключение Chart.js для графика -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
  // --- 1. Логика модального окна для календаря ---
  const markModalEl = document.getElementById('markModal');
  const markModal = new bootstrap.Modal(markModalEl);
  const dateInput = document.getElementById('markDate');
  const dateLabel = document.getElementById('markDateLabel');
  const statusSelect = document.getElementById('markStatus');

  document.querySelectorAll('.calendar-cell').forEach(cell => {
    cell.addEventListener('click', () => {
      const d = cell.dataset.date;
      dateInput.value = d;
      const [y, m, day] = d.split('-');
      dateLabel.textContent = `${day}.${m}.${y}`;
      const s = cell.dataset.status;
      statusSelect.value = s || 'present';
      markModal.show();
    });
  });

  // --- 2. Логика графика Chart.js ---
  const stats = {
    present: {{ stats_all.present|default(0) }},
    late: {{ stats_all.late|default(0) }},
    absent: {{ stats_all.absent|default(0) }},
    excused: {{ stats_all.excused|default(0) }}
  };

  const ctx = document.getElementById('attendanceChart').getContext('2d');
  new Chart(ctx, {
    type: 'doughnut', // Кольцевая диаграмма
    data: {
      labels: ['Присутствовал', 'Опоздал', 'Отсутствовал', 'Уважительная'],
      datasets: [{
        data: [stats.present, stats.late, stats.absent, stats.excused],
        backgroundColor: ['#198754', '#ffc107', '#dc3545', '#0dcaf0'], // Цвета Bootstrap
        borderWidth: 1,
        hoverOffset: 4
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: {
          position: 'right',
          labels: {
            boxWidth: 12,
            font: { size: 11 }
          }
        }
      },
      cutout: '65%' // Делает диаграмму более тонкой и аккуратной
    }
  });
</script>
{% endblock %}