ac0418083b
Модель вакансий, флоу рекрутинга и панели HR-портала (заявки/вакансии). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
197 lines
14 KiB
HTML
197 lines
14 KiB
HTML
{% 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>
|