2025-05-09 13:39:34 +00:00
|
|
|
{{ define "adminconversations.pages.tmpl" }}
|
2025-05-09 13:42:53 +00:00
|
|
|
{{ template "head" . }}
|
2025-05-09 16:12:29 +00:00
|
|
|
|
2025-05-09 14:59:48 +00:00
|
|
|
<div class="columns">
|
|
|
|
|
{{ template "sidebar" . }}
|
2025-05-09 16:12:29 +00:00
|
|
|
|
2025-05-09 15:05:31 +00:00
|
|
|
<div class="column is-10">
|
2025-05-09 16:12:29 +00:00
|
|
|
<section class="section">
|
2025-05-11 07:36:01 +00:00
|
|
|
{{ if eq .User.Role "ADMIN" }}
|
|
|
|
|
<div class="field mb-3">
|
|
|
|
|
<label class="label">👤 Voir les conversations de :</label>
|
|
|
|
|
<div class="control">
|
|
|
|
|
<div class="select is-small">
|
|
|
|
|
<select id="userSelect"
|
|
|
|
|
name="user"
|
|
|
|
|
onchange="location.href='/admin/user/' + this.value + '/conversations'">
|
|
|
|
|
<option value="">Tous les utilisateurs</option>
|
|
|
|
|
{{ range .Clients }}
|
|
|
|
|
<option value="{{ .ID }}" {{ if eq $.UserID (printf "%d" .ID) }}selected{{ end }}>
|
|
|
|
|
{{ .Email }}
|
|
|
|
|
</option>
|
|
|
|
|
{{ end }}
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{ end }}
|
|
|
|
|
|
2025-05-09 16:12:29 +00:00
|
|
|
<h1 class="title is-4">💬 Historique des messages — Utilisateur #{{ .UserID }}</h1>
|
|
|
|
|
|
2025-05-09 16:16:08 +00:00
|
|
|
<!-- Filtres -->
|
2025-05-09 16:12:29 +00:00
|
|
|
<div class="box mb-4">
|
|
|
|
|
<h2 class="subtitle is-6">🔍 Filtres personnalisés</h2>
|
|
|
|
|
<div class="columns is-multiline">
|
2025-05-11 09:14:11 +00:00
|
|
|
<div class="column is-4">
|
|
|
|
|
<label class="label is-small">📅 Filtrer entre deux dates :</label>
|
|
|
|
|
<div class="field has-addons">
|
|
|
|
|
<p class="control">
|
|
|
|
|
<input type="date" class="input is-small" id="startDate" onchange="filterByDateRange()">
|
|
|
|
|
</p>
|
|
|
|
|
<p class="control">
|
|
|
|
|
<input type="date" class="input is-small" id="endDate" onchange="filterByDateRange()">
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="column is-2">
|
2025-05-09 16:16:08 +00:00
|
|
|
<input type="text" class="input is-small" placeholder="➡️ Direction" onkeyup="filterTable(1, this.value)">
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="column is-2">
|
2025-05-09 16:16:08 +00:00
|
|
|
<input type="text" class="input is-small" placeholder="📨 Expéditeur" onkeyup="filterTable(2, this.value)">
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="column is-2">
|
2025-05-09 16:16:08 +00:00
|
|
|
<input type="text" class="input is-small" placeholder="📦 Type" onkeyup="filterTable(3, this.value)">
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="column is-2">
|
2025-05-09 16:16:08 +00:00
|
|
|
<input type="text" class="input is-small" placeholder="💬 Contenu" onkeyup="filterTable(4, this.value)">
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
<div class="column is-2">
|
2025-05-09 16:16:08 +00:00
|
|
|
<input type="text" class="input is-small" placeholder="✅ Statut" onkeyup="filterTable(5, this.value)">
|
2025-05-09 16:12:29 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-05-09 16:16:08 +00:00
|
|
|
<!-- Tableau -->
|
2025-05-09 16:12:29 +00:00
|
|
|
<table class="table is-fullwidth is-striped is-hoverable" id="conversationTable">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
2025-05-09 16:16:08 +00:00
|
|
|
<th onclick="sortTable(0)">📅 Date</th>
|
|
|
|
|
<th onclick="sortTable(1)">➡️ Direction</th>
|
|
|
|
|
<th onclick="sortTable(2)">📨 Expéditeur</th>
|
|
|
|
|
<th onclick="sortTable(3)">📦 Type</th>
|
|
|
|
|
<th onclick="sortTable(4)">💬 Contenu</th>
|
|
|
|
|
<th onclick="sortTable(5)">✅ Statut</th>
|
2025-05-11 09:14:11 +00:00
|
|
|
<th onclick="sortTable(6)">📖 Lu le</th>
|
2025-05-09 16:12:29 +00:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
2025-05-11 09:14:11 +00:00
|
|
|
|
2025-05-09 16:12:29 +00:00
|
|
|
<tbody id="conversationRows"
|
|
|
|
|
hx-get="/api/user/{{ .UserID }}/conversations"
|
|
|
|
|
hx-trigger="load"
|
|
|
|
|
hx-target="this"
|
|
|
|
|
hx-swap="innerHTML">
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
<h2 class="title is-5 mt-5">🧵 Conversation complète</h2>
|
|
|
|
|
<div id="threadViewer" class="box mt-3"></div>
|
|
|
|
|
</section>
|
2025-05-09 15:05:31 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-05-09 15:56:57 +00:00
|
|
|
|
|
|
|
|
<script>
|
2025-05-11 09:14:11 +00:00
|
|
|
function filterByDateRange() {
|
|
|
|
|
const table = document.getElementById("conversationTable");
|
|
|
|
|
const rows = table.tBodies[0].getElementsByTagName("tr");
|
|
|
|
|
const start = document.getElementById("startDate").value;
|
|
|
|
|
const end = document.getElementById("endDate").value;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < rows.length; i++) {
|
|
|
|
|
const dateText = rows[i].children[0].innerText.trim().split(" ")[0]; // yyyy-mm-dd
|
|
|
|
|
const rowDate = new Date(dateText);
|
|
|
|
|
|
|
|
|
|
const showRow =
|
|
|
|
|
(!start || rowDate >= new Date(start)) &&
|
|
|
|
|
(!end || rowDate <= new Date(end));
|
|
|
|
|
|
|
|
|
|
rows[i].style.display = showRow ? "" : "none";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-09 15:56:57 +00:00
|
|
|
function filterTable(colIndex, filterValue) {
|
|
|
|
|
const table = document.getElementById("conversationTable");
|
|
|
|
|
const rows = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
|
|
|
|
|
filterValue = filterValue.toLowerCase();
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < rows.length; i++) {
|
|
|
|
|
const td = rows[i].getElementsByTagName("td")[colIndex];
|
|
|
|
|
if (td) {
|
|
|
|
|
const text = td.textContent || td.innerText;
|
|
|
|
|
rows[i].style.display = text.toLowerCase().includes(filterValue) ? "" : "none";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-09 16:12:29 +00:00
|
|
|
|
2025-05-09 16:16:08 +00:00
|
|
|
function sortTable(colIndex) {
|
|
|
|
|
const table = document.getElementById("conversationTable");
|
|
|
|
|
const tbody = table.tBodies[0];
|
|
|
|
|
const rows = Array.from(tbody.querySelectorAll("tr"));
|
|
|
|
|
|
|
|
|
|
const isAscending = table.getAttribute("data-sort-dir") !== "asc";
|
|
|
|
|
table.setAttribute("data-sort-dir", isAscending ? "asc" : "desc");
|
|
|
|
|
|
|
|
|
|
rows.sort((a, b) => {
|
|
|
|
|
const cellA = a.children[colIndex].innerText.toLowerCase();
|
|
|
|
|
const cellB = b.children[colIndex].innerText.toLowerCase();
|
|
|
|
|
return isAscending
|
|
|
|
|
? cellA.localeCompare(cellB, 'fr', { numeric: true })
|
|
|
|
|
: cellB.localeCompare(cellA, 'fr', { numeric: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
rows.forEach(row => tbody.appendChild(row));
|
|
|
|
|
}
|
|
|
|
|
</script>
|
2025-05-09 15:56:57 +00:00
|
|
|
{{ end }}
|