Compact live visitor panel

This commit is contained in:
rajchales-monito
2026-07-24 11:43:43 +02:00
parent c72e6f3ed1
commit 79826cd26d
3 changed files with 46 additions and 26 deletions
+27 -11
View File
@@ -381,16 +381,18 @@ label { display: grid; gap: 6px; color: var(--muted); font-size: 13px; }
overflow: auto;
}
.visitor-card {
padding: 12px 14px;
padding: 10px 12px;
border-bottom: 1px solid var(--line);
background: white;
}
.visitor-card.clickable { cursor: pointer; }
.visitor-card.clickable:hover { background: #f8fbf9; }
.visitor-card-head {
display: grid;
grid-template-columns: 34px minmax(0, 1fr) 10px;
gap: 9px;
align-items: center;
margin-bottom: 10px;
margin-bottom: 7px;
}
.visitor-card-head strong,
.visitor-card-head small {
@@ -418,21 +420,35 @@ label { display: grid; gap: 6px; color: var(--muted); font-size: 13px; }
background: #2f9e44;
box-shadow: 0 0 0 4px rgb(47 158 68 / 14%);
}
.visitor-card dl {
display: grid;
grid-template-columns: 68px minmax(0, 1fr);
gap: 5px 8px;
margin: 0;
.visitor-compact-meta {
display: flex;
align-items: center;
gap: 7px;
min-width: 0;
color: var(--muted);
font-size: 12px;
}
.visitor-card dt { color: var(--muted); }
.visitor-card dd {
min-width: 0;
margin: 0;
.visitor-compact-meta span {
flex: 0 0 auto;
max-width: 72px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.visitor-page,
.visitor-referrer {
display: block;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 12px;
}
.visitor-page { margin-top: 6px; }
.visitor-referrer {
margin-top: 3px;
color: var(--muted);
}
.visitor-card a { color: var(--ink); text-decoration: none; }
.visitor-card a:hover { color: var(--brand); text-decoration: underline; }
.message {
+17 -15
View File
@@ -199,6 +199,14 @@ $("#messages").addEventListener("click", (event) => {
openPhotoPreview(preview.dataset.photoUrl, preview.dataset.photoName);
});
$("#visitorList").addEventListener("click", async (event) => {
if (event.target.closest("a")) return;
const card = event.target.closest("[data-visitor-conversation]");
const conversationId = card?.dataset.visitorConversation;
if (!conversationId) return;
await openConversation(conversationId);
});
async function showApp() {
$("#loginView").classList.add("hidden");
$("#appView").classList.remove("hidden");
@@ -320,7 +328,7 @@ function renderConversations() {
function renderVisitors() {
$("#visitorCount").textContent = `${state.visitors.length} online`;
$("#visitorList").innerHTML = state.visitors.length ? state.visitors.map((visitor) => `
<article class="visitor-card">
<article class="visitor-card ${visitor.lastConversationId ? "clickable" : ""}" data-visitor-conversation="${escapeHtml(visitor.lastConversationId || "")}">
<div class="visitor-card-head">
<span class="visitor-avatar">${escapeHtml(visitor.initials || "??")}</span>
<div>
@@ -329,20 +337,14 @@ function renderVisitors() {
</div>
<span class="online-dot" title="Online"></span>
</div>
<dl>
<dt>Zeme</dt>
<dd>${visitor.countryFlag || ""} ${escapeHtml(visitor.countryCode || "?")}</dd>
<dt>Stranka</dt>
<dd><a href="${escapeHtml(visitor.currentUrl || "#")}" target="_blank" rel="noreferrer">${escapeHtml(pageTitle(visitor))}</a></dd>
<dt>Prisiel z</dt>
<dd>${visitor.referrer ? `<a href="${escapeHtml(visitor.referrer)}" target="_blank" rel="noreferrer">${escapeHtml(referrerLabel(visitor.referrer))}</a>` : "primy vstup"}</dd>
<dt>Cas</dt>
<dd>${formatDuration(visitor.sessionSeconds)}</dd>
<dt>Navstevy</dt>
<dd>${Number(visitor.visitCount || visitor.pageCount || 1)}</dd>
<dt>Chaty</dt>
<dd>${Number(visitor.conversationCount || 0)}</dd>
</dl>
<div class="visitor-compact-meta">
<span>${visitor.countryFlag || escapeHtml(visitor.countryCode || "?")}</span>
<span>${formatDuration(visitor.sessionSeconds)}</span>
<span>${Number(visitor.visitCount || visitor.pageCount || 1)} navst.</span>
<span>${Number(visitor.conversationCount || 0)} chaty</span>
</div>
<a class="visitor-page" href="${escapeHtml(visitor.currentUrl || "#")}" target="_blank" rel="noreferrer">${escapeHtml(pageTitle(visitor))}</a>
<div class="visitor-referrer">${visitor.referrer ? escapeHtml(referrerLabel(visitor.referrer)) : "primy vstup"}${visitor.lastConversationId ? "" : " · bez chatu"}</div>
</article>
`).join("") : `<p class="empty-list">Zatim nikdo online.</p>`;
}