Files
ACORE/templates/partials/hr-vacancies-panel.html
T
lokses ac0418083b hiring: вакансии и найм, HR-портал
Модель вакансий, флоу рекрутинга и панели HR-портала (заявки/вакансии).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 18:03:32 +03:00

197 lines
14 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 i18n %}
{% if vacancy_message %}
<div style="margin-bottom:1rem; padding:0.65rem 0.9rem; border-radius:0.5rem; background:color-mix(in srgb, #16a34a 12%, var(--color-card)); border:1px solid color-mix(in srgb, #16a34a 30%, var(--color-border)); font-size:0.8125rem;">{{ vacancy_message }}</div>
{% endif %}
{% if vacancy_error %}
<div style="margin-bottom:1rem; padding:0.65rem 0.9rem; border-radius:0.5rem; background:color-mix(in srgb, #dc2626 12%, var(--color-card)); border:1px solid color-mix(in srgb, #dc2626 30%, var(--color-border)); font-size:0.8125rem;">{{ vacancy_error }}</div>
{% endif %}
<div style="display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0.75rem; margin-bottom:1.25rem;">
<div class="stat-card">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">{% trans "Открытых вакансий" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ vacancies_open }}</div>
{% if vacancies_urgent %}<div style="font-size:0.75rem; color:var(--color-destructive); margin-top:0.25rem;">{{ vacancies_urgent }} {% trans "срочных" %}</div>{% endif %}
</div>
<div class="stat-card">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">{% trans "Кандидатов" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ vacancies_candidates }}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "на открытых" %}</div>
</div>
<div class="stat-card">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">{% trans "Закрыто наймом" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ vacancies_filled_month }}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "за месяц" %}</div>
</div>
<div class="stat-card">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.5rem;">{% trans "Всего в списке" %}</div>
<div style="font-size:1.5rem; font-weight:500; color:var(--color-foreground);">{{ vacancies|length }}</div>
</div>
</div>
{% if can_manage_vacancies %}
<div style="display:flex; justify-content:flex-end; margin-bottom:0.75rem;">
<button type="button" id="hr-vacancy-form-toggle" class="btn btn-primary" style="font-size:0.8125rem;"
onclick="hrToggleVacancyForm()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right:0.25rem; vertical-align:-2px;">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
{% trans "Новая вакансия" %}
</button>
</div>
<div id="hr-vacancy-form-wrap" style="{% if vacancy_error %}display:block;{% else %}display:none;{% endif %} margin-bottom:1.25rem;">
<form method="post" action="{% url 'vacancy_save' %}"
style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; overflow:hidden; box-shadow:0 1px 2px rgb(0 0 0/0.05);">
{% csrf_token %}
<div style="padding:0.75rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; justify-content:space-between; gap:0.75rem;">
<span style="font-size:0.8125rem; font-weight:500; color:var(--color-foreground);">{% trans "Новая вакансия" %}</span>
<button type="button" class="btn btn-ghost" style="font-size:0.75rem;" onclick="hrHideVacancyForm()">{% trans "Закрыть" %}</button>
</div>
<div style="padding:1rem 1.25rem;">
<div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(11rem,1fr)); gap:0.75rem; margin-bottom:0.75rem;">
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Название" %}</label>
<input type="text" name="title" required class="input" style="width:100%;" placeholder="{% trans 'Фармацевт' %}">
</div>
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Должность" %}</label>
<select name="post_id" class="input" style="width:100%;">
<option value="">—</option>
{% for p in vacancy_posts %}
<option value="{{ p.id }}">{{ p.name }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Приоритет" %}</label>
<select name="priority" class="input" style="width:100%;">
<option value="normal">{% trans "Обычный" %}</option>
<option value="medium">{% trans "Средний" %}</option>
<option value="urgent">{% trans "Срочно" %}</option>
</select>
</div>
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Кандидатов" %}</label>
<input type="number" name="candidates_count" min="0" value="0" class="input" style="width:100%;">
</div>
{% if can_manage_hiring %}
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Тип локации" %}</label>
<select name="user_location_type" id="hr-vacancy-loc-type" class="input" style="width:100%;" onchange="hrVacancyLocToggle(this.value)">
<option value="pharmacy">{% trans "Аптека" %}</option>
<option value="office">{% trans "Офис" %}</option>
<option value="warehouse">{% trans "Склад" %}</option>
</select>
</div>
<div id="hr-vacancy-pharmacy-field">
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Аптека" %}</label>
<select name="pharmacy_id" class="input" style="width:100%;">
<option value="">—</option>
{% for ph in vacancy_pharmacies %}
<option value="{{ ph.id }}">{{ ph }}</option>
{% endfor %}
</select>
</div>
<div id="hr-vacancy-department-field" style="display:none;">
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Отдел" %}</label>
<select name="department_id" class="input" style="width:100%;">
<option value="">—</option>
{% for d in vacancy_departments %}
<option value="{{ d.id }}">{{ d.name }}</option>
{% endfor %}
</select>
</div>
{% else %}
<input type="hidden" name="user_location_type" value="pharmacy">
{% if vacancy_pharmacies %}
<input type="hidden" name="pharmacy_id" value="{{ vacancy_pharmacies.0.id }}">
<div>
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Аптека" %}</label>
<div style="font-size:0.8125rem; padding:0.45rem 0;">{{ vacancy_pharmacies.0 }}</div>
</div>
{% endif %}
{% endif %}
</div>
<div style="margin-bottom:0.75rem;">
<label style="display:block; font-size:0.7rem; color:var(--color-muted-foreground); margin-bottom:0.2rem;">{% trans "Описание" %}</label>
<input type="text" name="description" class="input" style="width:100%;">
</div>
<div style="display:flex; gap:0.5rem; flex-wrap:wrap;">
<button type="submit" class="btn btn-primary" style="font-size:0.8125rem;">{% trans "Создать вакансию" %}</button>
<button type="button" class="btn btn-secondary" style="font-size:0.8125rem; border:1px solid var(--color-border);" onclick="hrHideVacancyForm()">{% trans "Отмена" %}</button>
</div>
</div>
</form>
</div>
{% else %}
<div style="margin-bottom:1rem; padding:0.75rem 1rem; border-radius:0.625rem; border:1px solid var(--color-border); background:var(--color-muted); font-size:0.8125rem; color:var(--color-muted-foreground);">
{% trans "Создавать вакансии могут HR и заведующий. Фармацевт подаёт запрос на подмену во вкладке «Заявки и отпуска»." %}
</div>
{% endif %}
<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);">
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border);">
<h3 style="font-weight:600; color:var(--color-card-foreground); font-size:0.9375rem;">{% trans "Вакансии" %}</h3>
</div>
<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>
{% if can_manage_vacancies %}<th style="padding:0.75rem 1rem;"></th>{% endif %}
</tr>
</thead>
<tbody>
{% for v in vacancies %}
<tr style="border-bottom:1px solid var(--color-border);" class="tr-hover">
<td style="padding:0.85rem 1rem; font-weight:500; color:var(--color-card-foreground);">
{{ v.title }}
{% if v.post %}<div style="font-size:0.75rem; color:var(--color-muted-foreground); font-weight:400;">{{ v.post.name }}</div>{% endif %}
</td>
<td style="padding:0.85rem 1rem; color:var(--color-muted-foreground);">{{ v.place_label }}</td>
<td style="padding:0.85rem 1rem; color:var(--color-foreground);">{{ v.candidates_count }}</td>
<td style="padding:0.85rem 1rem;">
{% if v.priority == 'urgent' %}<span class="badge badge-danger">{% trans "Срочно" %}</span>
{% elif v.priority == 'medium' %}<span class="badge badge-warning">{% trans "Средний" %}</span>
{% else %}<span class="badge badge-success">{% trans "Обычный" %}</span>{% endif %}
</td>
<td style="padding:0.85rem 1rem;">{{ v.get_status_display }}</td>
<td style="padding:0.85rem 1rem; color:var(--color-muted-foreground);">{{ v.opened_at|date:"d.m.Y" }}</td>
{% if can_manage_vacancies %}
<td style="padding:0.85rem 1rem; text-align:right; white-space:nowrap;">
{% if v.status == 'open' %}
<form method="post" action="{% url 'vacancy_set_status' v.pk %}" style="display:inline;">
{% csrf_token %}
<input type="hidden" name="status" value="closed">
<button type="submit" class="btn btn-ghost" style="font-size:0.75rem;">{% trans "Закрыть" %}</button>
</form>
<form method="post" action="{% url 'vacancy_set_status' v.pk %}" style="display:inline;">
{% csrf_token %}
<input type="hidden" name="status" value="filled">
<button type="submit" class="btn btn-ghost" style="font-size:0.75rem;">{% trans "Закрыта наймом" %}</button>
</form>
{% else %}
<form method="post" action="{% url 'vacancy_set_status' v.pk %}" style="display:inline;">
{% csrf_token %}
<input type="hidden" name="status" value="open">
<button type="submit" class="btn btn-ghost" style="font-size:0.75rem;">{% trans "Открыть снова" %}</button>
</form>
{% endif %}
</td>
{% endif %}
</tr>
{% empty %}
<tr>
<td colspan="7" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">{% trans "Открытых вакансий пока нет" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>