loko/streetup/notifications/templates/notifications/discussion_list.html

194 lines
9 KiB
HTML

{% extends "base.html" %}
{% load i18n %}
{% load static %}
{% load mention_tags %}
{% block head %}
<style>
.discussion-item {
transition: all 0.15s ease-in-out;
border-left: 4px solid transparent;
}
.discussion-item.has-unread {
background-color: #f4f7ff;
border-left-color: var(--brand-color, #2f3e8b);
}
.discussion-item:hover {
background-color: #edf2fc;
text-decoration: none;
}
.avatar-discussion {
width: 44px;
height: 44px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.avatar-group {
display: inline-flex;
align-items: center;
}
.avatar-group .avatar-circle {
width: 26px;
height: 26px;
border-radius: 50%;
font-size: 0.7rem;
font-weight: 600;
display: inline-flex;
align-items: center;
justify-content: center;
border: 2px solid #ffffff;
margin-left: -6px;
transition: transform 0.15s ease, z-index 0.15s ease;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: default;
}
.avatar-group .avatar-circle:first-child {
margin-left: 0;
}
.avatar-group .avatar-circle:hover {
transform: translateY(-2px) scale(1.15);
z-index: 5;
}
.avatar-group .avatar-more {
background-color: #f1f5f9;
color: #475569;
font-size: 0.68rem;
font-weight: 700;
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0">
<i class="bi bi-chat-dots me-2 text-primary"></i>{% translate "Discussions" %}
</h1>
<div class="d-flex gap-2">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#newDiscussionModal">
<i class="bi bi-chat-plus-fill me-1.5"></i>{% translate "Nouvelle discussion" %}
</button>
<a href="{% url 'notifications:inbox' %}" class="btn btn-outline-secondary">
<i class="bi bi-bell me-1"></i>{% translate "Notifications" %}
</a>
<a href="{% url 'notifications:settings' %}" class="btn btn-outline-secondary" title="{% translate 'Paramètres' %}">
<i class="bi bi-gear me-1"></i>{% translate "Paramètres" %}
</a>
</div>
</div>
{% if not items %}
<div class="card border-0 shadow-sm rounded-3">
<div class="card-body text-center py-5 text-muted">
<i class="bi bi-chat-square fs-1 d-block mb-3 text-primary opacity-50"></i>
<p class="mb-0">{% translate "Vous n'avez encore aucune discussion." %}</p>
</div>
</div>
{% else %}
<div class="card border-0 shadow-sm rounded-3 overflow-hidden">
<div class="list-group list-group-flush">
{% for item in items %}
<a href="{% url 'notifications:discussion_detail' item.discussion.pk %}"
class="list-group-item list-group-item-action discussion-item px-3 px-md-4 py-3 {% if item.unread_count %}has-unread{% endif %}">
<div class="d-flex align-items-start gap-3">
<!-- Icône typée -->
{% with type_info=item.discussion.type_info %}
<div class="avatar-discussion {{ type_info.bg_class }} {{ type_info.text_class }} border {{ type_info.border_class }}" title="{{ type_info.label }}">
<i class="bi {{ type_info.icon }} fs-5"></i>
</div>
{% endwith %}
<!-- Contenu -->
<div class="flex-grow-1 min-width-0">
<div class="d-flex justify-content-between align-items-start gap-2 mb-1">
<div class="d-flex align-items-center gap-2 flex-wrap min-width-0">
<span class="fw-semibold text-dark text-truncate" style="font-size: 0.975rem;">
{{ item.discussion.title|default:item.discussion }}
</span>
{% if item.discussion.object_label and item.discussion.object_label != item.discussion.title %}
<span class="badge bg-light text-secondary border small rounded-pill px-2 py-0.5">
<i class="bi bi-link-45deg me-0.5"></i>{{ item.discussion.object_label }}
</span>
{% endif %}
{% if item.discussion.is_closed %}
<span class="badge bg-secondary-subtle text-secondary small rounded-pill px-2 py-0.5">
<i class="bi bi-lock-fill me-0.5"></i>{% translate "Clôturée" %}
</span>
{% endif %}
</div>
<span class="text-muted small ms-2 text-nowrap d-flex align-items-center gap-1">
<i class="bi bi-clock opacity-75"></i>
{{ item.discussion.updated_at|date:"d/m/Y H:i" }}
</span>
</div>
<!-- Aperçu du message nettoyé des tags @[Nom](u:id) -->
{% if item.last_message %}
<p class="mb-2 small text-muted text-truncate mt-0.5" style="max-width: 780px;">
<strong class="text-secondary">{{ item.last_message.author.get_full_name|default:item.last_message.author.username }}</strong> :
<span class="text-dark opacity-75">{{ item.last_message.content|clean_mentions_preview|truncatechars:140 }}</span>
</p>
{% else %}
<p class="mb-2 small text-muted mt-0.5 fst-italic">{% translate "Aucun message encore." %}</p>
{% endif %}
<!-- Pied de ligne : Participants en avatars empilés & compteur non lu -->
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 pt-1">
<div class="d-flex align-items-center gap-2">
<span class="text-muted small d-none d-sm-inline" style="font-size: 0.78rem;">
<i class="bi bi-people me-1 opacity-75"></i>{% translate "Participants" %} :
</span>
<div class="avatar-group">
{% for p in item.discussion.participants.all|slice:":6" %}
<div class="avatar-circle"
style="background-color: {{ p|avatar_bg_color }}; color: {{ p|avatar_text_color }};"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ p.get_full_name|default:p.username }}">
{{ p|user_initials }}
</div>
{% endfor %}
{% if item.discussion.participants.count > 6 %}
<div class="avatar-circle avatar-more"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ item.discussion.participants.count }} {% translate 'participants au total' %}">
+{{ item.discussion.participants.count|add:"-6" }}
</div>
{% endif %}
</div>
</div>
<!-- Badge non-lus -->
{% if item.unread_count %}
<span class="badge rounded-pill bg-primary px-2.5 py-1 small fw-semibold shadow-sm" style="background-color: var(--brand-color, #2f3e8b) !important;">
{{ item.unread_count }} {% translate "non lu(s)" %}
</span>
{% endif %}
</div>
</div>
</div>
</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% include "notifications/_new_discussion_modal.html" %}
{% endblock content %}
{% block script %}
<script>
document.addEventListener('DOMContentLoaded', () => {
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
[...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
});
</script>
{% endblock script %}