fix: приведен шаблон request_detail к стилям проекта

- Использованы компоненты card-list и message-field
- Убраны inline стили, используются классы проекта
- Улучшена структура и читаемость
- Добавлен правильный layout с container-fluid
- Комментарии теперь используют card-list-item класс
- Форма комментариев использует message-field компонент
This commit is contained in:
Игорь Надеин 2025-12-29 09:24:30 +03:00
parent 59f4db9fb6
commit 69788e8859

View File

@ -1,50 +1,41 @@
{% extends 'base.html' %}
{% load static django_bootstrap5 %}
{% extends "base.html" %}
{% load static %}
{% block title %}Заявление{% endblock %}
{% block title %}Заявление #{{ request_obj.id }}{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/components/card-list.css' %}">
<link rel="stylesheet" href="{% static 'css/components/message-field.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<div class="row gx-0">
<div class="col-12">
<div class="container-fluid py-3">
<div class="row justify-content-center">
<div class="col-12 col-lg-10 col-xl-8">
{% if error %}
{# — Ошибка при загрузке — #}
<div class="alert alert-danger mb-3" role="alert">
<i class="bi-exclamation-circle"></i>
{% if error_code == 404 %}
<strong>Заявление не найдено.</strong> Возможно, оно было удалено.
{% elif error_code == 403 %}
<strong>Доступ запрещен.</strong> Вы не можете просмотреть это заявление.
{% else %}
<strong>Ошибка при загрузке.</strong> {{ error }}
{% endif %}
<div class="card mb-3">
<div class="card-body text-center py-5">
<i class="bi bi-exclamation-triangle text-warning" style="font-size: 3rem;"></i>
<h5 class="mt-3">{{ error }}</h5>
<p class="text-muted">Код ошибки: {{ error_code }}</p>
<a href="{% url 'requests:request_list' %}" class="btn btn-primary mt-3">
<i class="bi-arrow-left me-2"></i>Вернуться к списку
</a>
</div>
</div>
<a href="{% url 'requests:request_list' %}" class="btn btn-secondary">
<i class="bi-arrow-left"></i> К списку заявлений
</a>
{% elif request_obj %}
<div class="section-header">
<i class="bi-file-earmark-text fs-2 text-primary"></i>
<h2 class="title mb-0">Детали заявления</h2>
<div class="ms-auto d-flex gap-2">
<a href="{% url 'requests:request_list' %}" class="btn btn-ghost">
<i class="bi-arrow-left"></i> К списку
</a>
</div>
</div>
{% else %}
{# — Карточка заявки — #}
{# ===== Основная информация о заявлении ===== #}
<article class="card mb-3">
<header class="card-header">
<div class="card-icon" style="width:48px;height:48px;">
{% if request_obj.employee.avatar %}
<img src="{{ request_obj.employee.avatar }}" alt="">
{% else %}<i class="bi-person"></i>{% endif %}
<header class="card-header d-flex align-items-start gap-3">
<div class="card-icon">
<i class="bi-clipboard-check"></i>
</div>
<div class="card-meta flex-grow-1">
<div class="d-flex align-items-center gap-2 flex-wrap">
<div class="d-flex align-items-center gap-2 flex-wrap mb-2">
<span class="card-title">
{{ request_obj.employee.full_name|default:request_obj.employee.display_name }}
</span>
@ -70,8 +61,8 @@
</span>
</div>
<div class="card-subtitle mt-1">
<time datetime="{{ request_obj.created_at|date:'c' }}">{{ request_obj.created_at|date:"d.m.Y H:i" }}</time>
<div class="card-subtitle">
<time datetime="{{ request_obj.created_at|date:'c' }}">{{ request_obj.created_at }}</time>
{% if request_obj.date_from or request_obj.date_to %}
· Период: {{ request_obj.date_from|date:'d.m.Y' }}{% if request_obj.date_to %} — {{ request_obj.date_to|date:'d.m.Y' }}{% endif %}
{% endif %}
@ -107,25 +98,30 @@
{% endif %}
</header>
<div class="card-body pt-0">
<div class="mb-2">
<span class="text-secondary small">Комментарий:</span>
<div>{{ request_obj.comment|default:"—" }}</div>
<div class="card-body">
{% if request_obj.title %}
<h6 class="mb-2">{{ request_obj.title }}</h6>
{% endif %}
<div class="mb-3">
<span class="text-secondary small d-block mb-1">Комментарий:</span>
<div>{{ request_obj.comment|default:"—"|linebreaksbr }}</div>
</div>
{% if request_obj.attachment_url %}
<a class="btn btn-ghost d-inline-flex align-items-center gap-1"
<a class="btn btn-ghost d-inline-flex align-items-center gap-2"
href="{{ request_obj.attachment_url }}" target="_blank" rel="noopener">
<i class="bi-paperclip"></i><span>Вложение</span>
<i class="bi-paperclip"></i>
<span>Вложение</span>
</a>
{% endif %}
</div>
</article>
<!--
{# — Комментарии — #}
{# ===== Комментарии ===== #}
<article class="card" id="comments">
<header class="card-header">
<div class="card-icon" style="width:44px;height:44px;">
<div class="card-icon">
<i class="bi-chat-dots"></i>
</div>
<div class="card-meta">
@ -134,19 +130,19 @@
</div>
</header>
<div class="card-body pt-0">
<div class="card-body">
{% if comments %}
<div class="d-flex flex-column gap-2 mb-3">
{% for c in comments %}
<div class="bg-body-tertiary border rounded p-2">
<div class="small d-flex justify-content-between align-items-start">
<div class="card-list-item">
<div class="d-flex justify-content-between align-items-start mb-1">
<div>
<span class="fw-semibold">{{ c.author.full_name|default:c.author.display_name }}</span>
<span class="text-secondary">·</span>
<time class="text-muted">{{ c.created_at }}</time>
<span class="text-secondary mx-1">·</span>
<time class="text-muted small">{{ c.created_at }}</time>
</div>
{# удалить — только автору комментария (права дополнительно проверяются во вьюхе) #}
{# удалить — только автору комментария #}
{% if c.author.id == request.user.id %}
<form method="post" action="{% url 'requests:request_comment_delete' request_obj.id c.id %}">
{% csrf_token %}
@ -156,16 +152,16 @@
</form>
{% endif %}
</div>
<div class="small mt-1">{{ c.text|linebreaksbr }}</div>
<div class="small">{{ c.text|linebreaksbr }}</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-secondary small mb-3">Комментариев пока нет.</div>
<div class="text-secondary small text-center py-3">Комментариев пока нет.</div>
{% endif %}
{# Добавить комментарий — #}
<form class="mt-2 request-comment-form" method="post" action="{% url 'requests:request_comment_add' request_obj.id %}">
<form class="mt-3 request-comment-form" method="post" action="{% url 'requests:request_comment_add' request_obj.id %}">
{% csrf_token %}
<div class="message-field message-field--compact">
<!-- Кнопка выбора эмодзи -->
@ -180,26 +176,37 @@
<emoji-picker data-emoji-picker class="chat-emoji-picker"></emoji-picker>
</div>
</div>
<textarea name="text" class="form-control message-input" rows="1" placeholder="Оставить комментарий…" maxlength="1000"></textarea>
<button class="btn btn-primary message-send" type="submit" title="Отправить"><i class="bi-send"></i></button>
<textarea
name="text"
class="message-input"
placeholder="Добавить комментарий..."
rows="2"
required
></textarea>
<button type="submit" class="btn btn-primary message-send-btn">
<i class="bi-send-fill"></i>
</button>
</div>
</form>
</div>
</article>
{% else %}
<div class="alert alert-info mb-3" role="alert">
Загрузка...
</div>
{% endif %}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
{{ block.super }}
<script src="{% static 'js/components/requestComments.js' %}"></script>
<!-- Emoji Picker Library -->
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>
<script type="module">
import { initRequestDetailModal } from '{% static "js/modules/requestDetail.js" %}';
// Если это модальное окно, не инициализируем
if (!window.location.pathname.includes('/requests/')) {
// Страница используется в модальном окне
}
</script>
{% endblock %}