657 lines
29 KiB
HTML
657 lines
29 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load i18n %}
|
|
{% load static %}
|
|
|
|
{% block title %}Feedback Detail - PX360{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.detail-card {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.detail-card-header {
|
|
background: #f8f9fa;
|
|
border-bottom: 1px solid #dee2e6;
|
|
padding: 15px 20px;
|
|
font-weight: 600;
|
|
}
|
|
.detail-card-body {
|
|
padding: 20px;
|
|
}
|
|
.info-row {
|
|
display: flex;
|
|
padding: 10px 0;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
.info-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.info-label {
|
|
font-weight: 600;
|
|
color: #666;
|
|
min-width: 150px;
|
|
}
|
|
.info-value {
|
|
flex: 1;
|
|
color: #333;
|
|
}
|
|
.status-badge {
|
|
padding: 6px 16px;
|
|
border-radius: 12px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
}
|
|
.status-submitted { background: #e3f2fd; color: #1976d2; }
|
|
.status-reviewed { background: #fff3e0; color: #f57c00; }
|
|
.status-acknowledged { background: #e8f5e9; color: #388e3c; }
|
|
.status-closed { background: #f5f5f5; color: #616161; }
|
|
|
|
.type-badge {
|
|
padding: 6px 16px;
|
|
border-radius: 12px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
}
|
|
.type-compliment { background: #e8f5e9; color: #2e7d32; }
|
|
.type-suggestion { background: #e3f2fd; color: #1565c0; }
|
|
.type-general { background: #f5f5f5; color: #616161; }
|
|
.type-inquiry { background: #fff3e0; color: #ef6c00; }
|
|
|
|
.sentiment-badge {
|
|
padding: 6px 16px;
|
|
border-radius: 12px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
}
|
|
.sentiment-positive { background: #e8f5e9; color: #2e7d32; }
|
|
.sentiment-neutral { background: #f5f5f5; color: #616161; }
|
|
.sentiment-negative { background: #ffebee; color: #c62828; }
|
|
|
|
.rating-stars {
|
|
color: #ffc107;
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.timeline {
|
|
position: relative;
|
|
padding-left: 30px;
|
|
}
|
|
.timeline::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 8px;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 2px;
|
|
background: #dee2e6;
|
|
}
|
|
.timeline-item {
|
|
position: relative;
|
|
padding-bottom: 30px;
|
|
}
|
|
.timeline-item::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: -26px;
|
|
top: 5px;
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
background: #fff;
|
|
border: 2px solid #0d6efd;
|
|
}
|
|
.timeline-content {
|
|
background: #f8f9fa;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 8px;
|
|
padding: 15px;
|
|
}
|
|
.timeline-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
.timeline-user {
|
|
font-weight: 600;
|
|
color: #0d6efd;
|
|
}
|
|
.timeline-date {
|
|
font-size: 0.85rem;
|
|
color: #666;
|
|
}
|
|
.timeline-message {
|
|
color: #333;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.featured-badge {
|
|
background: #ffd700;
|
|
color: #000;
|
|
padding: 4px 12px;
|
|
border-radius: 12px;
|
|
font-size: 0.85rem;
|
|
font-weight: 600;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-2">
|
|
<li class="breadcrumb-item"><a href="{% url 'feedback:feedback_list' %}">{% trans "Feedback" %}</a></li>
|
|
<li class="breadcrumb-item active">Detail</li>
|
|
</ol>
|
|
</nav>
|
|
<h2 class="mb-0">
|
|
<i class="bi bi-chat-heart-fill text-primary me-2"></i>
|
|
Feedback Detail
|
|
</h2>
|
|
</div>
|
|
<div class="action-buttons">
|
|
{% if can_edit %}
|
|
<a href="{% url 'feedback:feedback_update' feedback.id %}" class="btn btn-outline-primary">
|
|
<i class="bi bi-pencil me-1"></i> Edit
|
|
</a>
|
|
<a href="{% url 'feedback:feedback_delete' feedback.id %}" class="btn btn-outline-danger">
|
|
<i class="bi bi-trash me-1"></i> Delete
|
|
</a>
|
|
{% endif %}
|
|
<a href="{% url 'feedback:feedback_list' %}" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-1"></i> Back to List
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Main Content -->
|
|
<div class="col-lg-8">
|
|
<!-- Feedback Details -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<span>Feedback Information</span>
|
|
<div class="d-flex gap-2">
|
|
<span class="type-badge type-{{ feedback.feedback_type }}">
|
|
{{ feedback.get_feedback_type_display }}
|
|
</span>
|
|
<span class="status-badge status-{{ feedback.status }}">
|
|
{{ feedback.get_status_display }}
|
|
</span>
|
|
{% if feedback.is_featured %}
|
|
<span class="featured-badge">★ FEATURED</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="detail-card-body">
|
|
<div class="info-row">
|
|
<div class="info-label">ID:</div>
|
|
<div class="info-value">
|
|
<code>{{ feedback.id }}</code>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Title:</div>
|
|
<div class="info-value">
|
|
<strong>{{ feedback.title }}</strong>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Message:</div>
|
|
<div class="info-value">
|
|
<p class="mb-0" style="white-space: pre-wrap;">{{ feedback.message }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Category:</div>
|
|
<div class="info-value">
|
|
<span class="badge bg-secondary">{{ feedback.get_category_display }}</span>
|
|
{% if feedback.subcategory %}
|
|
<span class="text-muted ms-2">/ {{ feedback.subcategory }}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% if feedback.rating %}
|
|
<div class="info-row">
|
|
<div class="info-label">Rating:</div>
|
|
<div class="info-value">
|
|
<span class="rating-stars">
|
|
{% for i in "12345" %}
|
|
{% if forloop.counter <= feedback.rating %}
|
|
<i class="bi bi-star-fill"></i>
|
|
{% else %}
|
|
<i class="bi bi-star"></i>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</span>
|
|
<span class="ms-2">({{ feedback.rating }}/5)</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
<div class="info-row">
|
|
<div class="info-label">Sentiment:</div>
|
|
<div class="info-value">
|
|
<span class="sentiment-badge sentiment-{{ feedback.sentiment }}">
|
|
{{ feedback.get_sentiment_display }}
|
|
</span>
|
|
{% if feedback.sentiment_score %}
|
|
<span class="text-muted ms-2">(Score: {{ feedback.sentiment_score|floatformat:2 }})</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Priority:</div>
|
|
<div class="info-value">
|
|
<span class="badge bg-info">{{ feedback.get_priority_display }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Created:</div>
|
|
<div class="info-value">
|
|
{{ feedback.created_at|date:"F d, Y H:i" }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Patient/Contact Information -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Patient/Contact Information</div>
|
|
<div class="detail-card-body">
|
|
{% if feedback.patient %}
|
|
<div class="info-row">
|
|
<div class="info-label">Patient:</div>
|
|
<div class="info-value">
|
|
<strong>{{ feedback.patient.get_full_name }}</strong>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">MRN:</div>
|
|
<div class="info-value">{{ feedback.patient.mrn }}</div>
|
|
</div>
|
|
{% if feedback.patient.phone %}
|
|
<div class="info-row">
|
|
<div class="info-label">Phone:</div>
|
|
<div class="info-value">{{ feedback.patient.phone }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.patient.email %}
|
|
<div class="info-row">
|
|
<div class="info-label">Email:</div>
|
|
<div class="info-value">{{ feedback.patient.email }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<div class="info-row">
|
|
<div class="info-label">Type:</div>
|
|
<div class="info-value">
|
|
<span class="badge bg-secondary">Anonymous Feedback</span>
|
|
</div>
|
|
</div>
|
|
{% if feedback.contact_name %}
|
|
<div class="info-row">
|
|
<div class="info-label">Contact Name:</div>
|
|
<div class="info-value">{{ feedback.contact_name }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.contact_email %}
|
|
<div class="info-row">
|
|
<div class="info-label">Email:</div>
|
|
<div class="info-value">{{ feedback.contact_email }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.contact_phone %}
|
|
<div class="info-row">
|
|
<div class="info-label">Phone:</div>
|
|
<div class="info-value">{{ feedback.contact_phone }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Organization Information -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Organization Information</div>
|
|
<div class="detail-card-body">
|
|
<div class="info-row">
|
|
<div class="info-label">Hospital:</div>
|
|
<div class="info-value">{{ feedback.hospital.name }}</div>
|
|
</div>
|
|
{% if feedback.department %}
|
|
<div class="info-row">
|
|
<div class="info-label">Department:</div>
|
|
<div class="info-value">{{ feedback.department.name }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.physician %}
|
|
<div class="info-row">
|
|
<div class="info-label">Physician:</div>
|
|
<div class="info-value">{{ feedback.physician.get_full_name }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.encounter_id %}
|
|
<div class="info-row">
|
|
<div class="info-label">Encounter ID:</div>
|
|
<div class="info-value"><code>{{ feedback.encounter_id }}</code></div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Related Survey (if satisfaction check) -->
|
|
{% if feedback.related_survey %}
|
|
<div class="detail-card border-info">
|
|
<div class="detail-card-header bg-info text-white">
|
|
<i class="bi bi-link-45deg me-2"></i>Related Survey
|
|
</div>
|
|
<div class="detail-card-body">
|
|
<div class="alert alert-info mb-3">
|
|
<i class="bi bi-info-circle me-2"></i>
|
|
This is a <strong>satisfaction check</strong> feedback following a negative survey response.
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Survey:</div>
|
|
<div class="info-value">
|
|
<strong>{{ feedback.related_survey.survey_template.name }}</strong>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Original Score:</div>
|
|
<div class="info-value">
|
|
<span class="badge bg-danger">{{ feedback.related_survey.total_score|floatformat:1 }}/5.0</span>
|
|
<span class="text-muted ms-2">(Negative)</span>
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Survey Date:</div>
|
|
<div class="info-value">
|
|
{{ feedback.related_survey.completed_at|date:"M d, Y H:i" }}
|
|
</div>
|
|
</div>
|
|
{% if feedback.related_survey.patient_contacted %}
|
|
<div class="info-row">
|
|
<div class="info-label">Patient Contacted:</div>
|
|
<div class="info-value">
|
|
<i class="bi bi-check-circle-fill text-success"></i>
|
|
{{ feedback.related_survey.patient_contacted_at|date:"M d, Y H:i" }}
|
|
<br>
|
|
<small class="text-muted">By {{ feedback.related_survey.patient_contacted_by.get_full_name }}</small>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
<div class="mt-3">
|
|
<a href="{% url 'surveys:instance_detail' feedback.related_survey.id %}"
|
|
class="btn btn-info btn-sm w-100">
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>View Original Survey
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Timeline -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Timeline & Responses</div>
|
|
<div class="detail-card-body">
|
|
{% if timeline %}
|
|
<div class="timeline">
|
|
{% for response in timeline %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-content">
|
|
<div class="timeline-header">
|
|
<div>
|
|
<span class="timeline-user">
|
|
{% if response.created_by %}
|
|
{{ response.created_by.get_full_name }}
|
|
{% else %}
|
|
System
|
|
{% endif %}
|
|
</span>
|
|
<span class="badge bg-secondary ms-2">{{ response.get_response_type_display }}</span>
|
|
{% if response.is_internal %}
|
|
<span class="badge bg-warning ms-1">Internal</span>
|
|
{% endif %}
|
|
</div>
|
|
<span class="timeline-date">
|
|
{{ response.created_at|date:"M d, Y H:i" }}
|
|
</span>
|
|
</div>
|
|
<div class="timeline-message">{{ response.message }}</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<p class="text-muted text-center py-3">No responses yet</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Actions -->
|
|
{% if can_edit %}
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Actions</div>
|
|
<div class="detail-card-body">
|
|
<!-- Change Status -->
|
|
<form method="post" action="{% url 'feedback:feedback_change_status' feedback.id %}" class="mb-3">
|
|
{% csrf_token %}
|
|
<label class="form-label fw-bold">{% trans "Change Status" %}</label>
|
|
<select name="status" class="form-select mb-2">
|
|
{% for value, label in status_choices %}
|
|
<option value="{{ value }}" {% if feedback.status == value %}selected{% endif %}>
|
|
{{ label }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<textarea name="note" class="form-control mb-2" rows="2"
|
|
placeholder="{% trans 'Add a note (optional)...' %}"></textarea>
|
|
<button type="submit" class="btn btn-primary btn-sm w-100">
|
|
<i class="bi bi-arrow-repeat me-1"></i> Update Status
|
|
</button>
|
|
</form>
|
|
|
|
<hr>
|
|
|
|
<!-- Assign -->
|
|
<form method="post" action="{% url 'feedback:feedback_assign' feedback.id %}" class="mb-3">
|
|
{% csrf_token %}
|
|
<label class="form-label fw-bold">{% trans "Assign To" %}</label>
|
|
<select name="user_id" class="form-select mb-2">
|
|
<option value="">Select user...</option>
|
|
{% for user in assignable_users %}
|
|
<option value="{{ user.id }}" {% if feedback.assigned_to.id == user.id %}selected{% endif %}>
|
|
{{ user.get_full_name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<button type="submit" class="btn btn-primary btn-sm w-100">
|
|
<i class="bi bi-person-check me-1"></i> Assign
|
|
</button>
|
|
</form>
|
|
|
|
<hr>
|
|
|
|
<!-- Add Response -->
|
|
<form method="post" action="{% url 'feedback:feedback_add_response' feedback.id %}">
|
|
{% csrf_token %}
|
|
<label class="form-label fw-bold">{% trans "Add Response" %}</label>
|
|
<select name="response_type" class="form-select mb-2">
|
|
<option value="response">Response to Patient</option>
|
|
<option value="note">Internal Note</option>
|
|
<option value="acknowledgment">Acknowledgment</option>
|
|
</select>
|
|
<textarea name="message" class="form-control mb-2" rows="3"
|
|
placeholder="{% trans 'Enter your response...' %}" required></textarea>
|
|
<div class="form-check mb-2">
|
|
<input type="checkbox" class="form-check-input" name="is_internal" id="is_internal">
|
|
<label class="form-check-label" for="is_internal">
|
|
Internal only (not visible to patient)
|
|
</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-success btn-sm w-100">
|
|
<i class="bi bi-chat-left-text me-1"></i> Add Response
|
|
</button>
|
|
</form>
|
|
|
|
<hr>
|
|
|
|
<!-- Toggle Actions -->
|
|
<div class="d-grid gap-2">
|
|
<form method="post" action="{% url 'feedback:feedback_toggle_featured' feedback.id %}" class="d-inline">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-outline-warning btn-sm w-100">
|
|
<i class="bi bi-star me-1"></i>
|
|
{% if feedback.is_featured %}Unfeature{% else %}Feature{% endif %}
|
|
</button>
|
|
</form>
|
|
<form method="post" action="{% url 'feedback:feedback_toggle_follow_up' feedback.id %}" class="d-inline">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-outline-info btn-sm w-100">
|
|
<i class="bi bi-flag me-1"></i>
|
|
{% if feedback.requires_follow_up %}Remove Follow-up{% else %}Mark for Follow-up{% endif %}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Assignment Info -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Assignment & Tracking</div>
|
|
<div class="detail-card-body">
|
|
<div class="info-row">
|
|
<div class="info-label">Assigned To:</div>
|
|
<div class="info-value">
|
|
{% if feedback.assigned_to %}
|
|
{{ feedback.assigned_to.get_full_name }}
|
|
<br><small class="text-muted">{{ feedback.assigned_at|date:"M d, Y H:i" }}</small>
|
|
{% else %}
|
|
<span class="text-muted">Unassigned</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% if feedback.reviewed_by %}
|
|
<div class="info-row">
|
|
<div class="info-label">Reviewed By:</div>
|
|
<div class="info-value">
|
|
{{ feedback.reviewed_by.get_full_name }}
|
|
<br><small class="text-muted">{{ feedback.reviewed_at|date:"M d, Y H:i" }}</small>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.acknowledged_by %}
|
|
<div class="info-row">
|
|
<div class="info-label">Acknowledged By:</div>
|
|
<div class="info-value">
|
|
{{ feedback.acknowledged_by.get_full_name }}
|
|
<br><small class="text-muted">{{ feedback.acknowledged_at|date:"M d, Y H:i" }}</small>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if feedback.closed_by %}
|
|
<div class="info-row">
|
|
<div class="info-label">Closed By:</div>
|
|
<div class="info-value">
|
|
{{ feedback.closed_by.get_full_name }}
|
|
<br><small class="text-muted">{{ feedback.closed_at|date:"M d, Y H:i" }}</small>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Flags -->
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Flags & Settings</div>
|
|
<div class="detail-card-body">
|
|
<div class="info-row">
|
|
<div class="info-label">Featured:</div>
|
|
<div class="info-value">
|
|
{% if feedback.is_featured %}
|
|
<i class="bi bi-check-circle-fill text-success"></i> Yes
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-muted"></i> No
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Public:</div>
|
|
<div class="info-value">
|
|
{% if feedback.is_public %}
|
|
<i class="bi bi-check-circle-fill text-success"></i> Yes
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-muted"></i> No
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Follow-up Required:</div>
|
|
<div class="info-value">
|
|
{% if feedback.requires_follow_up %}
|
|
<i class="bi bi-check-circle-fill text-warning"></i> Yes
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-muted"></i> No
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label">Source:</div>
|
|
<div class="info-value">
|
|
<span class="badge bg-info">{{ feedback.source }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attachments -->
|
|
{% if attachments %}
|
|
<div class="detail-card">
|
|
<div class="detail-card-header">Attachments ({{ attachments.count }})</div>
|
|
<div class="detail-card-body">
|
|
<div class="list-group list-group-flush">
|
|
{% for attachment in attachments %}
|
|
<div class="list-group-item px-0">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<i class="bi bi-paperclip me-2"></i>
|
|
<strong>{{ attachment.filename }}</strong>
|
|
<br>
|
|
<small class="text-muted">
|
|
{{ attachment.file_size|filesizeformat }} •
|
|
{{ attachment.created_at|date:"M d, Y" }}
|
|
</small>
|
|
</div>
|
|
<a href="{{ attachment.file.url }}" class="btn btn-sm btn-outline-primary"
|
|
target="_blank" download>
|
|
<i class="bi bi-download"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|