Files
ACORE/templates/pages/it-manager.html
T
lokses ae5c1f1848 Add RRO, portal section perms, dislocation presets, and hiring intern flow.
Ship cash-register registry, section-based portal access, configurable dislocation columns, and trial-hire intern accounts with credentials PDF.
2026-08-09 14:58:17 +03:00

1136 lines
102 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% load common_tags %}
{% load i18n %}
<div class="page-content">
<div style="margin-bottom:1.5rem;">
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">{% trans "IT-отдел" %}</h1>
<p style="font-size:0.875rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "Инвентаризация оборудования, очередь заявок и журнал выполненных работ" %}</p>
</div>
<!-- Вкладки -->
<div style="display:flex; gap:0.25rem; background:var(--color-muted); border-radius:var(--radius); padding:0.25rem; width:fit-content; margin-bottom:1.5rem;">
<button type="button" class="it-tab-btn it-tab-active" data-tab="equipment" onclick="itTabSwitch('equipment')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:var(--color-card); color:var(--color-card-foreground); box-shadow:0 1px 2px rgb(0 0 0/0.08);">{% trans "Оборудование" %}</button>
<button type="button" class="it-tab-btn" data-tab="tickets" onclick="itTabSwitch('tickets')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:transparent; color:var(--color-muted-foreground);">{% trans "Заявки" %}</button>
<button type="button" class="it-tab-btn" data-tab="worklog" onclick="itTabSwitch('worklog')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:transparent; color:var(--color-muted-foreground);">{% trans "Выполненные работы" %}</button>
<button type="button" class="it-tab-btn" data-tab="consumables" onclick="itTabSwitch('consumables')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:transparent; color:var(--color-muted-foreground);">{% trans "Расходные материалы" %}</button>
<button type="button" class="it-tab-btn" data-tab="providers" onclick="itTabSwitch('providers')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:transparent; color:var(--color-muted-foreground);">{% trans "Провайдеры" %}</button>
<button type="button" class="it-tab-btn" data-tab="servicecalls" onclick="itTabSwitch('servicecalls')"
style="padding:0.375rem 1rem; font-size:0.8125rem; font-weight:500; border:none; border-radius:calc(var(--radius) - 2px); cursor:pointer; background:transparent; color:var(--color-muted-foreground);">{% trans "Обращение" %}</button>
</div>
<!-- ══ ВКЛАДКА: ОБЛАДНАННЯ ══ -->
<div id="it-panel-equipment" class="it-panel">
<div style="display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:0.75rem; margin-bottom:1.5rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Всего единиц" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ equipment_list|length }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "На складе" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ equipment_counts.stock }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Выдано" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ equipment_counts.assigned }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "В ремонте / списано" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ equipment_counts.repair|add:equipment_counts.written_off }}</div>
</div>
</div>
{% if equipment_form_message %}
<div style="background:rgba(22,163,74,0.08); border:1px solid rgba(22,163,74,0.3); border-radius:0.75rem; padding:0.75rem 1rem; margin-bottom:1rem; font-size:0.875rem; color:#16a34a;">{{ equipment_form_message }}</div>
{% endif %}
{% if equipment_form_error %}
<div style="background:color-mix(in srgb, var(--color-destructive) 8%, transparent); border:1px solid color-mix(in srgb, var(--color-destructive) 30%, transparent); border-radius:0.75rem; padding:0.75rem 1rem; margin-bottom:1rem; font-size:0.875rem; color:var(--color-destructive);">{{ equipment_form_error }}</div>
{% endif %}
<div style="display:flex; justify-content:flex-end; gap:0.5rem; margin-bottom:1rem;">
<button type="button" class="btn btn-secondary" style="border:1px solid var(--color-border);" onclick="itPanelOpen('it-equipment-models-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/></svg>
{% trans "Каталог моделей" %} ({{ equipment_models|length }})
</button>
<button type="button" class="btn btn-primary" onclick="itPanelOpen('it-equipment-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Добавить экземпляры" %}
</button>
</div>
<!-- Виїзна панель: масовий ввід екземплярів -->
<div id="it-equipment-panel-overlay" onclick="itPanelClose('it-equipment-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-equipment-panel" style="position:fixed; top:0; right:0; height:100vh; width:28rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/equipment/bulk-create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Добавить экземпляры" %}</span>
<button type="button" onclick="itPanelClose('it-equipment-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Модель из каталога" %} <span style="color:var(--color-destructive);">*</span></label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск модели по названию или бренду...' %}">
<select name="equipment_model_id" required hidden>
<option value="">—</option>
{% for m in equipment_models %}
<option value="{{ m.id }}">{{ m.equipment_type.name }} · {{ m }}</option>
{% endfor %}
</select>
</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.375rem;">{% trans "Нет нужной?" %} <a href="#" onclick="itPanelClose('it-equipment-panel'); itPanelOpen('it-equipment-models-panel'); return false;" style="color:var(--color-primary);">{% trans "Добавить модель в каталог" %}</a></div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Серийные номера" %} <span style="color:var(--color-destructive);">*</span></label>
<textarea name="serial_numbers" required placeholder="{% trans 'По одному в строку — вставьте список серийников, например' %}&#10;HGC09SJD200&#10;HGC09VB5ZKX&#10;HGC09VT0P2H"
style="width:100%; min-height:8rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-mono, monospace); outline:none; box-sizing:border-box;"></textarea>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.375rem;">{% trans "Сколько серийников — столько единиц будет создано. Дубликаты и уже имеющиеся пропускаются." %}</div>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:0.75rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Дата покупки" %}</label>
<input type="date" name="purchase_date" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Гарантия до" %}</label>
<input type="date" name="warranty_until" class="input" style="width:100%;">
</div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Сразу выдать на локацию" %} <span style="font-weight:400; color:var(--color-muted-foreground);">{% trans "(необязательно)" %}</span></label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск по адресу или номеру аптеки...' %}">
<select name="location_id" hidden>
<option value="">{% trans "— на склад" %}</option>
{% for location in it_locations %}
<option value="{{ location.id }}">{{ location }}</option>
{% endfor %}
</select>
</div>
</div>
<div style="display:flex; gap:0.5rem;">
<button type="submit" class="btn btn-primary" style="flex:1;">
{% trans "Создать экземпляры" %}
<span class="btn-label-loading htmx-indicator">{% trans "Сохранение…" %}</span>
</button>
<button type="button" class="btn btn-secondary" style="border:1px solid var(--color-border);" onclick="itPanelClose('it-equipment-panel')">{% trans "Отменить" %}</button>
</div>
</div>
</form>
</div>
<!-- Виїзна панель: каталог моделей -->
<div id="it-equipment-models-panel-overlay" onclick="itPanelClose('it-equipment-models-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-equipment-models-panel" style="position:fixed; top:0; right:0; height:100vh; width:28rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Каталог моделей" %}</span>
<button type="button" onclick="itPanelClose('it-equipment-models-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<form hx-post="/it-manager/equipment/models/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem; border-bottom:1px solid var(--color-border);">
{% csrf_token %}
<div style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground);">{% trans "Новая модель" %}</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Тип" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="equipment_type" required class="input" style="width:100%;" onchange="dqaHandleChange(this, 'equipment_type', 'code')">
{% for value, label in equipment_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый тип..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Бренд" %}</label>
<select name="brand_id" class="input" style="width:100%;" onchange="dqaHandleChange(this, 'equipment_brand', 'id')">
<option value="">—</option>
{% for brand in equipment_brands %}
<option value="{{ brand.id }}">{{ brand.name }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый бренд..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Модель" %} <span style="color:var(--color-destructive);">*</span></label>
<input type="text" name="name" required placeholder="{% trans 'Например: RB952Ui-5ac2nD' %}" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Гарантия (мес.)" %} <span style="font-weight:400; color:var(--color-muted-foreground);">{% trans "(необязательно)" %}</span></label>
<input type="number" min="0" name="warranty_months" class="input" style="width:100%;">
</div>
<button type="submit" class="btn btn-primary" style="width:100%;">
{% trans "Добавить модель" %}
<span class="btn-label-loading htmx-indicator">{% trans "Сохранение…" %}</span>
</button>
</form>
<div style="padding:1rem 1.25rem;">
<div style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.75rem;">{% trans "В каталоге" %} ({{ equipment_models|length }})</div>
<div style="display:flex; flex-direction:column; gap:0.5rem;">
{% for m in equipment_models %}
<div style="display:flex; align-items:center; justify-content:space-between; gap:0.5rem; padding:0.5rem 0.75rem; background:var(--color-muted); border-radius:var(--radius);">
<div style="min-width:0;">
<div style="font-size:0.8125rem; color:var(--color-foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">{{ m }}</div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground);">{{ m.equipment_type.name }}</div>
</div>
<span class="badge badge-muted" style="flex-shrink:0;">{{ m.units_total }} {% trans "ед." %}</span>
</div>
{% empty %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Каталог пуст — добавьте первую модель." %}</div>
{% endfor %}
</div>
</div>
</div>
<!-- Панель масової видачі (з'являється при виборі екземплярів) -->
<div id="it-equipment-bulk-assign" style="display:none; background:var(--color-card); border:1px solid var(--color-primary); border-radius:0.75rem; padding:1rem 1.25rem; margin-bottom:1rem;">
<form hx-post="/it-manager/equipment/bulk-assign/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; align-items:flex-end; gap:0.75rem; flex-wrap:wrap;">
{% csrf_token %}
<div id="it-bulk-assign-inputs"></div>
<div style="font-size:0.875rem; color:var(--color-foreground); font-weight:500; align-self:center;">{% trans "Выдать" %} <span id="it-bulk-assign-count">0</span> {% trans "ед.:" %}</div>
<div style="min-width:16rem; flex:1;">
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "На локацию" %}</label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск по адресу или номеру аптеки...' %}">
<select name="location_id" hidden>
<option value="">—</option>
{% for location in it_locations %}
<option value="{{ location.id }}">{{ location }}</option>
{% endfor %}
</select>
</div>
</div>
<div style="min-width:12rem;">
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Сотруднику" %}</label>
<select name="assigned_to_id" class="input" style="width:100%;">
<option value="">—</option>
{% for emp in it_employees %}
<option value="{{ emp.id }}">{{ emp.last_name }} {{ emp.first_name }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">{% trans "Выдать" %}</button>
<button type="button" class="btn btn-ghost" onclick="itBulkClearSelection()">{% trans "Отменить выбор" %}</button>
</form>
</div>
<!-- Список обладнання -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="width:2.25rem; text-align:center;"><input type="checkbox" onclick="itBulkToggleAll(this)" title="{% trans 'Выделить все на странице' %}" style="cursor:pointer;"></th>
<th style="width:2rem;"></th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Тип / Бренд / Модель" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "С/н · Инв. №" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Локация" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Выдано" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Статус" %}</th>
</tr>
</thead>
<tbody>
{% for equipment in equipment_page %}
<tr class="it-row" style="border-bottom:1px solid var(--color-border); cursor:pointer;" onclick="itToggleRow('equipment-{{ equipment.id }}')">
<td style="padding:0.75rem 0; text-align:center;" onclick="event.stopPropagation();">
<input type="checkbox" class="it-equip-check" value="{{ equipment.id }}" onchange="itBulkUpdate()" style="cursor:pointer;">
</td>
<td style="padding:0.75rem 0; text-align:center; color:var(--color-muted-foreground);">
<span id="it-toggle-equipment-{{ equipment.id }}" style="display:inline-block; transition:transform 150ms;">▸</span>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">
<strong>{{ equipment.equipment_type.name }}</strong>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ equipment.brand.name|default:"" }} {{ equipment.model }}</div>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground); font-size:0.8125rem;">
{{ equipment.serial_number }}{% if equipment.inventory_number %} · {{ equipment.inventory_number }}{% endif %}
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ equipment.location|default:"—" }}</td>
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">{{ equipment.assigned_to.get_full_name|default:"—" }}</td>
<td style="padding:0.75rem 1rem;">
{% if equipment.status.code == 'stock' %}<span class="badge badge-muted">{% trans "На складе" %}</span>
{% elif equipment.status.code == 'assigned' %}<span class="badge badge-success">{% trans "Выдано" %}</span>
{% elif equipment.status.code == 'repair' %}<span class="badge badge-warning">{% trans "В ремонте" %}</span>
{% else %}<span class="badge badge-danger">{% trans "Списано" %}</span>{% endif %}
</td>
</tr>
<tr id="it-row-equipment-{{ equipment.id }}" class="it-detail-row" style="display:none; border-bottom:1px solid var(--color-border); background:var(--color-muted);">
<td></td>
<td></td>
<td colspan="5" style="padding:1rem;">
<form hx-post="/it-manager/equipment/{{ equipment.id }}/update/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; align-items:flex-end; gap:0.75rem; flex-wrap:wrap;" onclick="event.stopPropagation();">
{% csrf_token %}
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Статус" %}</label>
<select name="status" class="input" style="min-width:10rem;">
{% for value, label in equipment_statuses %}
<option value="{{ value }}" {% if value == equipment.status.code %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Выдано кому" %}</label>
<select name="assigned_to_id" class="input" style="min-width:14rem;">
<option value="">{% trans "— (на складе)" %}</option>
{% for emp in it_employees %}
<option value="{{ emp.id }}" {% if emp.id == equipment.assigned_to_id %}selected{% endif %}>{{ emp.last_name }} {{ emp.first_name }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">
{% trans "Сохранить" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
{% if equipment.notes %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); flex-basis:100%;">{% trans "Примечания:" %} {{ equipment.notes }}</div>
{% endif %}
{% if equipment.warranty_until %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); flex-basis:100%;">{% trans "Гарантия:" %} {{ equipment.warranty_status }} ({{ equipment.warranty_until|date:"d.m.Y" }})</div>
{% endif %}
</form>
</td>
</tr>
{% empty %}
<tr><td colspan="7" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Оборудование ещё не добавлено" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=equipment_page base_url="/it-manager/" page_param="equipment_page" size_param="equipment_per_page" item_label="одиниць обладнання" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ОБЛАДНАННЯ ══ -->
<!-- ══ ВКЛАДКА: ЗАЯВКИ ══ -->
<div id="it-panel-tickets" class="it-panel" style="display:none;">
<div style="display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); gap:0.75rem; margin-bottom:1.5rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Новые" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ ticket_counts.new }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "В работе" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ ticket_counts.in_progress }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Ожидание" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ ticket_counts.waiting }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Решённые" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ ticket_counts.resolved|add:ticket_counts.closed }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Просроченные" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:{% if ticket_overdue_count %}var(--color-destructive){% else %}var(--color-foreground){% endif %};">{{ ticket_overdue_count }}</div>
</div>
</div>
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="width:2rem;"></th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "№ / Тема" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Приоритет" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Заявитель" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Исполнитель" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Дата" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Статус" %}</th>
</tr>
</thead>
<tbody>
{% for ticket in tickets_page %}
<tr class="it-row" style="border-bottom:1px solid var(--color-border); cursor:pointer;" onclick="itToggleRow('ticket-{{ ticket.id }}')">
<td style="padding:0.75rem 0; text-align:center; color:var(--color-muted-foreground);">
<span id="it-toggle-ticket-{{ ticket.id }}" style="display:inline-block; transition:transform 150ms;">▸</span>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">
<strong>{{ ticket.number }}</strong>
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ ticket.title }}{% if ticket.is_overdue %} <span class="badge badge-danger">{% trans "просрочено" %}</span>{% endif %}</div>
</td>
<td style="padding:0.75rem 1rem;">
{% if ticket.priority.code == 'critical' %}<span class="badge badge-danger">{% trans "Критический" %}</span>
{% elif ticket.priority.code == 'high' %}<span class="badge badge-warning">{% trans "Высокий" %}</span>
{% elif ticket.priority.code == 'medium' %}<span class="badge badge-info">{% trans "Средний" %}</span>
{% else %}<span class="badge badge-muted">{% trans "Низкий" %}</span>{% endif %}
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ ticket.requester.get_full_name|default:ticket.requester.username }}</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ ticket.assignee.get_full_name|default:"—" }}</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground); font-size:0.8125rem;">{{ ticket.created_at|date:"d.m.Y" }}</td>
<td style="padding:0.75rem 1rem;">
{% if ticket.status.code == 'new' %}<span class="badge badge-info">{% trans "Новая" %}</span>
{% elif ticket.status.code == 'in_progress' %}<span class="badge badge-warning">{% trans "В работе" %}</span>
{% elif ticket.status.code == 'waiting' %}<span class="badge badge-muted">{% trans "Ожидание" %}</span>
{% elif ticket.status.code == 'resolved' %}<span class="badge badge-success">{% trans "Решена" %}</span>
{% else %}<span class="badge badge-muted">{% trans "Закрыта" %}</span>{% endif %}
</td>
</tr>
<tr id="it-row-ticket-{{ ticket.id }}" class="it-detail-row" style="display:none; border-bottom:1px solid var(--color-border); background:var(--color-muted);">
<td></td>
<td colspan="6" style="padding:1rem;">
<div style="font-size:0.8125rem; color:var(--color-foreground); margin-bottom:0.75rem; white-space:pre-wrap;">{{ ticket.description }}</div>
{% if ticket.comments.all %}
<div style="display:flex; flex-direction:column; gap:0.5rem; margin-bottom:0.75rem;">
{% for comment in ticket.comments.all %}
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.5rem; padding:0.5rem 0.75rem;">
<div style="font-size:0.75rem; color:var(--color-muted-foreground); display:flex; justify-content:space-between;">
<span>{{ comment.author.get_full_name|default:comment.author.username }} · {{ comment.created_at|date:"d.m.Y H:i" }}</span>
{% if comment.is_internal %}<span class="badge badge-muted">{% trans "внутренний" %}</span>{% endif %}
</div>
<div style="font-size:0.8125rem; color:var(--color-foreground); margin-top:0.25rem; white-space:pre-wrap;">{{ comment.text }}</div>
</div>
{% endfor %}
</div>
{% endif %}
<form hx-post="/it-manager/tickets/{{ ticket.id }}/update/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; align-items:flex-end; gap:0.75rem; flex-wrap:wrap; margin-bottom:0.75rem;" onclick="event.stopPropagation();">
{% csrf_token %}
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Статус" %}</label>
<select name="status" class="input" style="min-width:10rem;">
{% for value, label in ticket_statuses %}
<option value="{{ value }}" {% if value == ticket.status.code %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Исполнитель" %}</label>
<select name="assignee_id" class="input" style="min-width:12rem;"
onclick="event.stopPropagation();" onmousedown="event.stopPropagation();">
<option value="">{% trans "— не назначено" %}</option>
{% for emp in it_staff %}
<option value="{{ emp.id }}" {% if emp.id == ticket.assignee_id %}selected{% endif %}>{{ emp.last_name }} {{ emp.first_name }}</option>
{% empty %}
<option value="" disabled>{% trans "Нет сотрудников IT / staff — добавьте в группу IT" %}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">
{% trans "Сохранить" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
</form>
<form hx-post="/it-manager/tickets/{{ ticket.id }}/comment/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; gap:0.5rem; align-items:flex-start;" onclick="event.stopPropagation();">
{% csrf_token %}
<input type="text" name="text" placeholder="{% trans 'Комментарий...' %}" class="input" style="flex:1;">
<label style="display:flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:var(--color-muted-foreground); white-space:nowrap; padding-top:0.5rem;">
<input type="checkbox" name="is_internal"> {% trans "внутренний" %}
</label>
<button type="submit" class="btn btn-secondary" style="border:1px solid var(--color-border);">
{% trans "Добавить" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
</form>
</td>
</tr>
{% empty %}
<tr><td colspan="7" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Заявок пока нет" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=tickets_page base_url="/it-manager/" page_param="tickets_page" size_param="tickets_per_page" item_label="заявок" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ЗАЯВКИ ══ -->
<!-- ══ ВКЛАДКА: ВИКОНАНІ РОБОТИ ══ -->
<div id="it-panel-worklog" class="it-panel" style="display:none;">
<div style="display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:0.75rem; margin-bottom:1.5rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Записей в этом месяце" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ month_count }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Часов в этом месяце" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ month_hours }}</div>
</div>
</div>
<div style="display:flex; justify-content:flex-end; margin-bottom:1rem;">
<button type="button" class="btn btn-primary" onclick="itPanelOpen('it-worklog-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Добавить запись" %}
</button>
</div>
<!-- Виїзна панель: новий запис про виконану роботу -->
<div id="it-worklog-panel-overlay" onclick="itPanelClose('it-worklog-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-worklog-panel" style="position:fixed; top:0; right:0; height:100vh; width:26rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/worklog/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Добавить запись о выполненной работе" %}</span>
<button type="button" onclick="itPanelClose('it-worklog-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Дата" %}</label>
<input type="date" name="date" value="{% now 'Y-m-d' %}" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Вид работ" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="work_type" required class="input" style="width:100%;" onchange="dqaHandleChange(this, 'worklog_type', 'code')">
{% for value, label in worklog_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый вид работ..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Локация" %}</label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск по адресу или номеру аптеки...' %}">
<select name="location_id" hidden>
<option value="">—</option>
{% for location in it_locations %}
<option value="{{ location.id }}">{{ location }}</option>
{% endfor %}
</select>
</div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Затрачено часов" %}</label>
<input type="number" step="0.5" min="0" name="hours_spent" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Оборудование" %}</label>
<select name="equipment_id" class="input" style="width:100%;">
<option value="">—</option>
{% for equipment in equipment_list %}
<option value="{{ equipment.id }}">{{ equipment.equipment_model }} [{{ equipment.serial_number }}]</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Заявка" %}</label>
<select name="ticket_id" class="input" style="width:100%;">
<option value="">—</option>
{% for ticket in tickets %}
<option value="{{ ticket.id }}">{{ ticket.number }} — {{ ticket.title }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Описание работ" %} <span style="color:var(--color-destructive);">*</span></label>
<textarea name="description" required style="width:100%; min-height:4rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Результат" %}</label>
<textarea name="result" style="width:100%; min-height:3.5rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<button type="submit" class="btn btn-primary" style="width:100%; justify-content:center;">
{% trans "Добавить запись" %}
<span class="btn-label-loading htmx-indicator">{% trans "Сохранение…" %}</span>
</button>
</div>
</div>
</form>
</div>
<!-- Журнал -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Дата" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Исполнитель" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Вид работ" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Описание" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Локация" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Часов" %}</th>
</tr>
</thead>
<tbody>
{% for log in worklogs_page %}
<tr style="border-bottom:1px solid var(--color-border);">
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground); white-space:nowrap;">{{ log.date|date:"d.m.Y" }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-foreground);">{{ log.technician.get_full_name|default:log.technician.username }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground);">{{ log.work_type.name }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-foreground); max-width:22rem;">{{ log.description|truncatechars:120 }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground); font-size:0.8125rem;">{{ log.location|default:"—" }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-foreground);">{{ log.hours_spent|default:"—" }}</td>
</tr>
{% empty %}
<tr><td colspan="6" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Записей ещё нет" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=worklogs_page base_url="/it-manager/" page_param="worklogs_page" size_param="worklogs_per_page" item_label="записів" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ВИКОНАНІ РОБОТИ ══ -->
<!-- ══ ВКЛАДКА: ВИТРАТНІ МАТЕРІАЛИ ══ -->
<div id="it-panel-consumables" class="it-panel" style="display:none;">
<div style="display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:0.75rem; margin-bottom:1.5rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Всего позиций" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ consumables_count }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Заканчивается / на замену" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:{% if consumable_low_count %}var(--color-destructive){% else %}var(--color-foreground){% endif %};">{{ consumable_low_count }}</div>
</div>
</div>
<div style="display:flex; justify-content:flex-end; margin-bottom:1rem;">
<button type="button" class="btn btn-primary" onclick="itPanelOpen('it-consumable-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Добавить материал" %}
</button>
</div>
<!-- Виїзна панель: новий витратний матеріал -->
<div id="it-consumable-panel-overlay" onclick="itPanelClose('it-consumable-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-consumable-panel" style="position:fixed; top:0; right:0; height:100vh; width:26rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/consumables/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Добавить расходный материал" %}</span>
<button type="button" onclick="itPanelClose('it-consumable-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Тип" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="consumable_type" required class="input" style="width:100%;" onchange="dqaHandleChange(this, 'consumable_type', 'code')">
{% for value, label in consumable_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый тип..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Цвет" %}</label>
<select name="color" class="input" style="width:100%;" onchange="dqaHandleChange(this, 'consumable_color', 'code')">
{% for value, label in consumable_colors %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый цвет..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Производитель" %}</label>
<input type="text" name="brand" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Модель / артикул" %} <span style="color:var(--color-destructive);">*</span></label>
<input type="text" name="model_number" required class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Принтер" %}</label>
<select name="equipment_id" class="input" style="width:100%;">
<option value="">—</option>
{% for printer in printers %}
<option value="{{ printer.id }}">{{ printer.equipment_model }} [{{ printer.serial_number }}]</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Локация хранения" %}</label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск по адресу или номеру аптеки...' %}">
<select name="location_id" hidden>
<option value="">—</option>
{% for location in it_locations %}
<option value="{{ location.id }}">{{ location }}</option>
{% endfor %}
</select>
</div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Ресурс (страниц)" %}</label>
<input type="number" min="0" name="page_yield" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Дата покупки" %}</label>
<input type="date" name="purchase_date" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Примечания" %}</label>
<textarea name="notes" style="width:100%; min-height:3rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<button type="submit" class="btn btn-primary" style="width:100%; justify-content:center;">
{% trans "Добавить" %}
<span class="btn-label-loading htmx-indicator">{% trans "Сохранение…" %}</span>
</button>
</div>
</div>
</form>
</div>
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="width:2rem;"></th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Тип / Модель" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Цвет" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Принтер" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Статус" %}</th>
</tr>
</thead>
<tbody>
{% for consumable in consumables_page %}
<tr class="it-row" style="border-bottom:1px solid var(--color-border); cursor:pointer;" onclick="itToggleRow('consumable-{{ consumable.id }}')">
<td style="padding:0.75rem 0; text-align:center; color:var(--color-muted-foreground);">
<span id="it-toggle-consumable-{{ consumable.id }}" style="display:inline-block; transition:transform 150ms;">▸</span>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">
<strong>{{ consumable.consumable_type.name }}</strong>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ consumable.brand }} {{ consumable.model_number }}</div>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ consumable.color.name }}</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ consumable.equipment|default:"—" }}</td>
<td style="padding:0.75rem 1rem;">
{% if consumable.is_low %}<span class="badge badge-danger">{{ consumable.status.name }}</span>
{% elif consumable.status.code == 'installed' %}<span class="badge badge-success">{{ consumable.status.name }}</span>
{% else %}<span class="badge badge-muted">{{ consumable.status.name }}</span>{% endif %}
</td>
</tr>
<tr id="it-row-consumable-{{ consumable.id }}" class="it-detail-row" style="display:none; border-bottom:1px solid var(--color-border); background:var(--color-muted);">
<td></td>
<td colspan="4" style="padding:1rem;">
<form hx-post="/it-manager/consumables/{{ consumable.id }}/update/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; align-items:flex-end; gap:0.75rem; flex-wrap:wrap;" onclick="event.stopPropagation();">
{% csrf_token %}
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Статус" %}</label>
<select name="status" class="input" style="min-width:12rem;">
{% for value, label in consumable_statuses %}
<option value="{{ value }}" {% if value == consumable.status.code %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">
{% trans "Сохранить" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
{% if consumable.page_yield %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Ресурс:" %} {{ consumable.page_yield }} {% trans "стр." %}</div>
{% endif %}
{% if consumable.notes %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); flex-basis:100%;">{% trans "Примечания:" %} {{ consumable.notes }}</div>
{% endif %}
</form>
</td>
</tr>
{% empty %}
<tr><td colspan="5" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Расходных материалов ещё не добавлено" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=consumables_page base_url="/it-manager/" page_param="consumables_page" size_param="consumables_per_page" item_label="матеріалів" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ВИТРАТНІ МАТЕРІАЛИ ══ -->
<!-- ══ ВКЛАДКА: ПРОВАЙДЕРИ ══ -->
<div id="it-panel-providers" class="it-panel" style="display:none;">
<div style="display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:0.75rem; margin-bottom:1.5rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Провайдеров" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ providers|length }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Договоров" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ contracts_count }}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Заканчиваются через 30 дней" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:{% if contracts_expiring_count %}var(--color-destructive){% else %}var(--color-foreground){% endif %};">{{ contracts_expiring_count }}</div>
</div>
</div>
<div style="display:flex; justify-content:flex-end; gap:0.5rem; margin-bottom:1rem;">
<button type="button" class="btn btn-secondary" onclick="itPanelOpen('it-provider-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Добавить провайдера" %}
</button>
<button type="button" class="btn btn-primary" onclick="itPanelOpen('it-contract-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Добавить договор" %}
</button>
</div>
<!-- Список провайдерів -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden; margin-bottom:1.25rem;">
<div style="padding:0.875rem 1.25rem; border-bottom:1px solid var(--color-border);">
<span style="font-size:0.8125rem; font-weight:500; color:var(--color-foreground);">{% trans "Провайдеры" %}</span>
</div>
<div style="display:flex; flex-wrap:wrap; gap:0.625rem; padding:1rem 1.25rem;">
{% for provider in providers %}
<div style="display:flex; align-items:center; gap:0.5rem; background:var(--color-muted); border-radius:0.5rem; padding:0.5rem 0.75rem;">
<div>
<div style="font-size:0.8125rem; font-weight:500; color:var(--color-foreground);">{{ provider.name }}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground);">{{ provider.phone|default:"—" }}{% if provider.website %} · {{ provider.website }}{% endif %}</div>
</div>
<span class="badge badge-info">{{ provider.active_contracts_count }}</span>
</div>
{% empty %}
<div style="color:var(--color-muted-foreground); font-size:0.8125rem;">{% trans "Провайдеров ещё нет" %}</div>
{% endfor %}
</div>
</div>
<!-- Виїзна панель: новий провайдер -->
<div id="it-provider-panel-overlay" onclick="itPanelClose('it-provider-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-provider-panel" style="position:fixed; top:0; right:0; height:100vh; width:26rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/providers/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Новый провайдер" %}</span>
<button type="button" onclick="itPanelClose('it-provider-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Название" %} <span style="color:var(--color-destructive);">*</span></label>
<input type="text" name="name" required class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Телефон" %}</label>
<input type="text" name="phone" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">Email</label>
<input type="email" name="email" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Сайт" %}</label>
<input type="url" name="website" placeholder="https://" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Телефон техподдержки" %}</label>
<input type="text" name="support_phone" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Email техподдержки" %}</label>
<input type="email" name="support_email" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Примечания" %}</label>
<textarea name="notes" style="width:100%; min-height:3rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<button type="submit" class="btn btn-primary" style="width:100%; justify-content:center;">
{% trans "Добавить провайдера" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
</div>
</div>
</form>
</div>
<!-- Виїзна панель: новий договір -->
<div id="it-contract-panel-overlay" onclick="itPanelClose('it-contract-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-contract-panel" style="position:fixed; top:0; right:0; height:100vh; width:26rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/contracts/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Новый договор" %}</span>
<button type="button" onclick="itPanelClose('it-contract-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Провайдер" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="provider_id" required class="input" style="width:100%;">
<option value="">—</option>
{% for provider in providers %}
<option value="{{ provider.id }}">{{ provider.name }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Локация" %} <span style="color:var(--color-destructive);">*</span></label>
<div class="searchable-select" data-placeholder="{% trans 'Поиск по адресу или номеру аптеки...' %}">
<select name="location_id" required hidden>
<option value="">—</option>
{% for location in it_locations %}
<option value="{{ location.id }}">{{ location }}</option>
{% endfor %}
</select>
</div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Номер договора" %} <span style="color:var(--color-destructive);">*</span></label>
<input type="text" name="contract_number" required class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Тип услуги" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="service_type" required class="input" style="width:100%;" onchange="dqaHandleChange(this, 'contract_service_type', 'code'); itContractServiceToggle(this.value)">
{% for value, label in contract_service_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый тип..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Технология подключения" %}</label>
<select name="connection_type" class="input" style="width:100%;" onchange="dqaHandleChange(this, 'contract_connection_type', 'code')">
<option value="">—</option>
{% for value, label in contract_connection_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новую технологию..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Дата начала" %} <span style="color:var(--color-destructive);">*</span></label>
<input type="date" name="start_date" required class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Дата окончания" %}</label>
<input type="date" name="end_date" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Стоимость/мес." %}</label>
<input type="number" step="0.01" min="0" name="monthly_cost" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Скорость ↓ Мбит/с" %}</label>
<input type="number" min="0" name="bandwidth_down" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Скорость ↑ Мбит/с" %}</label>
<input type="number" min="0" name="bandwidth_up" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Лицевой счёт" %}</label>
<input type="text" name="account_number" class="input" style="width:100%;">
</div>
<div id="it-contract-ip-block" style="display:none; background:var(--color-muted); border-radius:0.625rem; padding:0.875rem 1rem;">
<label style="display:flex; align-items:center; gap:0.5rem; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); cursor:pointer;">
<input type="checkbox" name="dedicated_ip" onchange="document.getElementById('it-contract-ip-field').style.display = this.checked ? '' : 'none'">
{% trans "Выделенный IP" %}
</label>
<div id="it-contract-ip-field" style="display:none; margin-top:0.625rem;">
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "IP-адреса" %}</label>
<textarea name="static_ips" placeholder="{% trans 'По одному IP-адресу на строку' %}" style="width:100%; min-height:3rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Примечания" %}</label>
<textarea name="notes" style="width:100%; min-height:3rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<button type="submit" class="btn btn-primary" style="width:100%; justify-content:center;">
{% trans "Добавить договор" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
</div>
</div>
</form>
</div>
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="width:2rem;"></th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Провайдер / Локация" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Тип услуги" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Скорость" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Окончание" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Статус" %}</th>
</tr>
</thead>
<tbody>
{% for contract in contracts_page %}
<tr class="it-row" style="border-bottom:1px solid var(--color-border); cursor:pointer;" onclick="itToggleRow('contract-{{ contract.id }}')">
<td style="padding:0.75rem 0; text-align:center; color:var(--color-muted-foreground);">
<span id="it-toggle-contract-{{ contract.id }}" style="display:inline-block; transition:transform 150ms;">▸</span>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">
<strong>{{ contract.provider.name }}</strong> <span style="font-size:0.75rem; color:var(--color-muted-foreground);">№{{ contract.contract_number }}</span>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ contract.location }}</div>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">{{ contract.service_type.name }}</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground); font-size:0.8125rem;">{{ contract.bandwidth_display }}</td>
<td style="padding:0.75rem 1rem; color:{% if contract.is_expiring_soon %}var(--color-destructive){% else %}var(--color-muted-foreground){% endif %};">{{ contract.end_date|date:"d.m.Y"|default:"—" }}</td>
<td style="padding:0.75rem 1rem;">
{% if contract.status.code == 'active' %}<span class="badge badge-success">{{ contract.status.name }}</span>
{% elif contract.status.code == 'suspended' %}<span class="badge badge-warning">{{ contract.status.name }}</span>
{% else %}<span class="badge badge-danger">{{ contract.status.name }}</span>{% endif %}
</td>
</tr>
<tr id="it-row-contract-{{ contract.id }}" class="it-detail-row" style="display:none; border-bottom:1px solid var(--color-border); background:var(--color-muted);">
<td></td>
<td colspan="5" style="padding:1rem;">
<form hx-post="/it-manager/contracts/{{ contract.id }}/update/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]"
style="display:flex; align-items:flex-end; gap:0.75rem; flex-wrap:wrap;" onclick="event.stopPropagation();">
{% csrf_token %}
<div>
<label style="display:block; font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Статус" %}</label>
<select name="status" class="input" style="min-width:12rem;">
{% for value, label in contract_statuses %}
<option value="{{ value }}" {% if value == contract.status.code %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">
{% trans "Сохранить" %}
<span class="btn-label-loading htmx-indicator">…</span>
</button>
<div style="font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Счёт:" %} {{ contract.account_number|default:"—" }} · {{ contract.monthly_cost|default:"—" }} {% trans "грн/мес" %}</div>
</form>
</td>
</tr>
{% empty %}
<tr><td colspan="6" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Договоров ещё нет" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=contracts_page base_url="/it-manager/" page_param="contracts_page" size_param="contracts_per_page" item_label="договорів" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ПРОВАЙДЕРИ ══ -->
<!-- ══ ВКЛАДКА: ОБРАЩЕННЯ ══ -->
<div id="it-panel-servicecalls" class="it-panel" style="display:none;">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:1rem;">
<span style="font-size:0.875rem; color:var(--color-muted-foreground);">{{ service_calls_count }} {% trans "обращений" %}</span>
<button type="button" class="btn btn-primary" onclick="itPanelOpen('it-servicecall-panel')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Новое обращение" %}
</button>
</div>
<!-- Виїзна панель: нове звернення -->
<div id="it-servicecall-panel-overlay" onclick="itPanelClose('it-servicecall-panel')" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:1000;"></div>
<div id="it-servicecall-panel" style="position:fixed; top:0; right:0; height:100vh; width:26rem; max-width:92vw; background:var(--color-card); box-shadow:-8px 0 24px rgba(0,0,0,0.18); z-index:1001; transform:translateX(100%); transition:transform 250ms ease; overflow-y:auto;">
<form hx-post="/it-manager/servicecalls/create/" hx-target="#main-content" hx-indicator="#loader, find .btn-label-loading" hx-disabled-elt="find button[type=submit]">
{% csrf_token %}
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; background:var(--color-card); z-index:1;">
<span style="font-size:0.9375rem; font-weight:600; color:var(--color-foreground);">{% trans "Новое обращение" %}</span>
<button type="button" onclick="itPanelClose('it-servicecall-panel')" class="btn btn-ghost btn-icon" aria-label="{% trans 'Закрыть' %}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div style="padding:1.25rem; display:flex; flex-direction:column; gap:1rem;">
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Кто обратился" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="caller_id" required class="input" style="width:100%;">
<option value="">—</option>
{% for emp in it_employees %}
<option value="{{ emp.id }}">{{ emp.last_name }} {{ emp.first_name }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Канал" %} <span style="color:var(--color-destructive);">*</span></label>
<select name="channel" required class="input" style="width:100%;" onchange="dqaHandleChange(this, 'servicecall_channel', 'code')">
{% for value, label in servicecall_channels %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
<option value="__new__">{% trans "+ Добавить новый канал..." %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Затрачено минут" %}</label>
<input type="number" min="0" name="minutes_spent" class="input" style="width:100%;">
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Описание обращения" %} <span style="color:var(--color-destructive);">*</span></label>
<textarea name="description" required style="width:100%; min-height:3.5rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<label style="display:block; font-size:0.8125rem; font-weight:500; color:var(--color-foreground); margin-bottom:0.375rem;">{% trans "Решение" %}</label>
<textarea name="resolution" style="width:100%; min-height:3rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
</div>
<div>
<button type="submit" class="btn btn-primary" style="width:100%; justify-content:center;">
{% trans "Добавить обращение" %}
<span class="btn-label-loading htmx-indicator">{% trans "Сохранение…" %}</span>
</button>
</div>
</div>
</form>
</div>
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Дата" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Кто обратился" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Канал" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Принял" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Описание" %}</th>
<th style="padding:0.75rem 1rem;text-align:left;color:var(--color-muted-foreground);font-weight:600;font-size:0.8125rem;">{% trans "Длительность" %}</th>
</tr>
</thead>
<tbody>
{% for call in service_calls_page %}
<tr style="border-bottom:1px solid var(--color-border);">
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground); white-space:nowrap;">{{ call.date_time|date:"d.m.Y H:i" }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-foreground);">{{ call.caller.get_full_name|default:call.caller.username }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground);">{{ call.channel.name }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground);">{{ call.handler.get_full_name|default:"—" }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-foreground); max-width:20rem;">{{ call.description|truncatechars:100 }}</td>
<td style="padding:0.625rem 1rem; color:var(--color-muted-foreground);">{{ call.duration_display }}</td>
</tr>
{% empty %}
<tr><td colspan="6" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Обращений ещё нет" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "partials/pagination.html" with page=service_calls_page base_url="/it-manager/" page_param="servicecalls_page" size_param="servicecalls_per_page" item_label="звернень" %}
</div>
</div>
<!-- ══ /ВКЛАДКА: ОБРАЩЕННЯ ══ -->
{% if it_active_tab and it_active_tab != 'equipment' %}
<script>itTabSwitch('{{ it_active_tab }}');</script>
{% endif %}
<script>initSearchableSelects(document);</script>
</div>