| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /tmp/ |
Upload File : |
// Sitzungs-Verlauf: Zeile aufklappen → analytische Detailansicht (Journey)
(function(){
var table = document.querySelector('[data-session-url]');
if(!table) return;
var base = table.getAttribute('data-session-url');
var CONV_TAGS = {};
var MICRO_DEF = ['vxcam_live','vxcam_offline','omocha_shop','external','vxcam_gallery','omocha_gallery'];
function classifyConv(type){
type=type||'';
if(CONV_TAGS[type]) return {label:CONV_TAGS[type].label||type, micro:CONV_TAGS[type].category==='micro'};
var lbl=type.replace(/[_-]+/g,' ').replace(/\b\w/g,function(c){return c.toUpperCase();});
return {label:lbl, micro:MICRO_DEF.indexOf(type)>-1};
}
var WDAY=['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'];
var MON=['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
var CN={DE:'Deutschland',AT:'Österreich',CH:'Schweiz',US:'USA',GB:'Großbritannien',FR:'Frankreich',NL:'Niederlande',IT:'Italien',ES:'Spanien',PL:'Polen',BE:'Belgien',TR:'Türkei',AT_:'',SE:'Schweden',DK:'Dänemark',NO:'Norwegen',CZ:'Tschechien',CA:'Kanada',AU:'Australien'};
var DEV={desktop:['Desktop','fa-desktop'],mobile:['Smartphone','fa-mobile-screen'],tablet:['Tablet','fa-tablet-screen-button']};
function esc(s){ var d=document.createElement('div'); d.textContent=(s==null?'':String(s)); return d.innerHTML; }
function jsd(s){ if(!s) return null; var d=new Date(String(s).replace(' ','T')); return isNaN(d)?null:d; }
function clock(s){ var d=jsd(s); if(!d) return esc(s); return ('0'+d.getHours()).slice(-2)+':'+('0'+d.getMinutes()).slice(-2)+':'+('0'+d.getSeconds()).slice(-2); }
function dur(sec){ sec=parseInt(sec||0,10); if(sec<=0) return '0 s'; if(sec<60) return sec+' s'; var m=Math.floor(sec/60),s=sec%60; return m+':'+('0'+s).slice(-2)+' min'; }
function flag(cc){ cc=(cc||'').toUpperCase(); if(!/^[A-Z]{2}$/.test(cc)) return ''; return String.fromCodePoint(0x1F1E6+cc.charCodeAt(0)-65)+String.fromCodePoint(0x1F1E6+cc.charCodeAt(1)-65); }
function host(u){ try{ return new URL(u).host.replace(/^www\./,''); }catch(e){ return u; } }
function pathOf(u){ try{ var x=new URL(u); return (x.pathname||'/')+(x.search||''); }catch(e){ return u; } }
function channel(d){
var med=(d.utm&&d.utm.medium||'').toLowerCase(), src=(d.utm&&d.utm.source||'').toLowerCase(), ref=(d.referrer||'').toLowerCase();
if(med==='email'||src.indexOf('newsletter')>-1||med.indexOf('mail')>-1) return ['E-Mail','fa-envelope','#7c3aed'];
if(['cpc','ppc','paid','paidsearch','display'].indexOf(med)>-1) return ['Paid','fa-rectangle-ad','#db2777'];
if(/(facebook|instagram|t\.co|twitter|x\.com|linkedin|pinterest|tiktok|youtube|reddit|whatsapp)/.test(ref)||med.indexOf('social')>-1) return ['Social','fa-share-nodes','#0891b2'];
if(/(google|bing|duckduckgo|yahoo|ecosia|yandex|baidu|startpage|qwant)/.test(ref)||med==='organic') return ['Organische Suche','fa-magnifying-glass','#16a34a'];
if(src||med) return ['Kampagne','fa-bullhorn','#f59e0b'];
if(!ref||ref==='direkt'||ref==='direct') return ['Direkt','fa-circle-dot','#64748b'];
return ['Verweis','fa-arrow-right-to-bracket','#2563eb'];
}
function ua(s){ s=s||''; var b='Unbekannt',o='Unbekannt';
if(/Edg\//.test(s))b='Edge'; else if(/OPR\/|Opera/.test(s))b='Opera'; else if(/SamsungBrowser/.test(s))b='Samsung Internet'; else if(/Chrome\//.test(s))b='Chrome'; else if(/Firefox\//.test(s))b='Firefox'; else if(/Safari\//.test(s))b='Safari';
if(/Windows NT 10/.test(s))o='Windows 10/11'; else if(/Windows/.test(s))o='Windows'; else if(/Android/.test(s))o='Android'; else if(/iPhone|iPad|iOS/.test(s))o='iOS'; else if(/Mac OS X|Macintosh/.test(s))o='macOS'; else if(/Linux/.test(s))o='Linux';
return b+' · '+o;
}
var EVMETA={
outbound_click:['fa-arrow-up-right-from-square','Externer Klick','#0891b2'],
scroll_depth:['fa-arrows-down-to-line','Scrolltiefe','#64748b'],
page_leave:['fa-door-open','Seite verlassen','#94a3b8'],
form_abandon:['fa-rectangle-xmark','Formular abgebrochen','#dc2626'],
click:['fa-hand-pointer','Klick','#64748b']
};
function evLabel(e){
var m=EVMETA[e.type]||['fa-circle-dot',e.type||'Event','#94a3b8'], val='';
if(e.type==='scroll_depth' && e.value) val=parseInt(e.value,10)+' %';
else if(e.type==='outbound_click' && e.value) val='→ '+esc(host(e.value));
else if(e.value) val=esc(String(e.value));
return {icon:m[0],label:m[1],color:m[2],val:val};
}
function render(d){
var cc=(d.country||'').toUpperCase(), cname=CN[cc]||cc;
var dev=(d.device||'').toLowerCase(), dm=DEV[dev]||['',(d.device||'')];
var ch=channel(d), st=jsd(d.started_at);
var when = st ? (WDAY[st.getDay()]+', '+st.getDate()+'. '+MON[st.getMonth()]+' '+st.getFullYear()+' · '+('0'+st.getHours()).slice(-2)+':'+('0'+st.getMinutes()).slice(-2)+' Uhr') : esc(d.started_at||'');
var hardConv=0, microConv=0, convVal=0;
(d.conversions||[]).forEach(function(c){ var cl=classifyConv(c.conversion_type); if(cl.micro) microConv++; else { hardConv++; convVal+=parseFloat(c.value||0)||0; } });
var converted=hardConv>0;
var maxScroll=0; (d.events||[]).forEach(function(e){ if(e.type==='scroll_depth'){ var v=parseInt(e.value,10)||0; if(v>maxScroll)maxScroll=v; } });
// ---- Header ----
var h='<div class="sx"><div class="sx-fixed">';
h+='<div class="sx-head">'
+'<div class="sx-id">'
+'<span class="sx-flag">'+(flag(cc)||'<i class=\"fa-solid fa-user\"></i>')+'</span>'
+'<div><div class="sx-title">'+(cname?('Besucher aus '+esc(cname)):'Besucher')+'</div>'
+'<div class="sx-sub">'+when+'</div></div></div>'
+'<div class="sx-badges">'
+'<span class="ch-chip" style="--c:'+ch[2]+'"><i class="fa-solid '+ch[1]+'"></i>'+esc(ch[0])+'</span>'
+(dm[1]?'<span class="sx-tag"><i class="fa-solid '+(dm[1]||'fa-question')+'"></i>'+esc(dm[0])+'</span>':'')
+(converted?'<span class="sx-tag sx-conv"><i class="fa-solid fa-bullseye"></i>Conversion</span>':'')
+(microConv?'<span class="sx-tag sx-eng"><i class="fa-solid fa-arrow-pointer"></i>'+microConv+' Engagement</span>':'')
+'</div></div>';
// ---- Engagement-Kacheln ----
h+='<div class="sx-chips">';
h+='<div class="sx-chip"><span class="sx-cv">'+dur(d.duration)+'</span><span class="sx-cl">Aufenthalt</span></div>';
h+='<div class="sx-chip"><span class="sx-cv">'+(d.pageviews||(d.pages||[]).length||0)+'</span><span class="sx-cl">Seiten</span></div>';
h+='<div class="sx-chip"><span class="sx-cv">'+(maxScroll?maxScroll+' %':'—')+'</span><span class="sx-cl">max. Scrolltiefe</span></div>';
h+='<div class="sx-chip"><span class="sx-cv">'+(d.is_bounce?'Ja':'Nein')+'</span><span class="sx-cl">Absprung</span></div>';
if(converted) h+='<div class="sx-chip sx-chip-ok"><span class="sx-cv">'+(convVal>0?convVal.toLocaleString("de-DE",{minimumFractionDigits:2})+" €":(hardConv+"×"))+'</span><span class="sx-cl">Conversion-Wert</span></div>';
h+='</div>';
// ---- Akquise ----
var acq=d.referrer?('von <strong>'+esc(host(d.referrer))+'</strong>'):'<strong>Direktaufruf</strong>';
if(d.utm){ var u=[]; ['source','medium','campaign'].forEach(function(x){ if(d.utm[x]) u.push(esc(x)+': '+esc(d.utm[x])); }); if(u.length) acq+=' <span class="text-muted">· '+u.join(' · ')+'</span>'; }
h+='<div class="sx-acq"><i class="fa-solid '+ch[1]+'" style="color:'+ch[2]+'"></i> Kam '+acq+'</div>';
// ---- Journey: Events den Seiten zuordnen ----
var pages=(d.pages||[]).slice().sort(function(a,b){ return (a.ts||'')<(b.ts||'')?-1:1; });
var inter=[];
(d.events||[]).forEach(function(e){ if(e.type!=='page_leave') inter.push({ts:e.ts,kind:'event',data:e}); });
(d.conversions||[]).forEach(function(c){ inter.push({ts:c.ts||c.created_at,kind:'conv',data:c}); });
function bucket(ts){ var idx=0; for(var i=0;i<pages.length;i++){ if((pages[i].ts||'')<=(ts||'')) idx=i; } return idx; }
var buckets={}; inter.forEach(function(it){ var i=pages.length?bucket(it.ts):-1; (buckets[i]=buckets[i]||[]).push(it); });
Object.keys(buckets).forEach(function(k){ buckets[k].sort(function(a,b){ return (a.ts||'')<(b.ts||'')?-1:1; }); });
function actHtml(it){
if(it.kind==='conv'){ var c=it.data, cl=classifyConv(c.conversion_type);
return '<div class="sx-act sx-act-conv'+(cl.micro?' sx-act-micro':'')+'"><i class="fa-solid '+(cl.micro?'fa-arrow-pointer':'fa-bullseye')+'"></i><span><strong>'+esc(cl.label)+'</strong>'
+'<span class="sx-ctag '+(cl.micro?'is-micro':'is-hard')+'">'+(cl.micro?'Micro':'Hard')+'</span>'
+(c.reference_id?' · '+esc(c.reference_id):'')+(c.value?' · '+esc(c.value)+(c.currency?' '+esc(c.currency):''):'')+'</span><span class="sx-at">'+clock(it.ts)+'</span></div>';
}
var m=evLabel(it.data);
return '<div class="sx-act"><i class="fa-solid '+m.icon+'" style="color:'+m.color+'"></i><span>'+esc(m.label)+(m.val?' <span class="text-muted">'+m.val+'</span>':'')+'</span><span class="sx-at">'+clock(it.ts)+'</span></div>';
}
var jr='';
if(pages.length){
pages.forEach(function(p,i){
var acts=(buckets[i]||[]).map(actHtml).join('');
var tags='';
if(i===0) tags+='<span class="sx-pin sx-in">Einstieg</span>';
if(i===pages.length-1) tags+='<span class="sx-pin sx-out">Ausstieg</span>';
jr+='<div class="sx-step">'
+'<div class="sx-rail"><span class="sx-dot">'+(i+1)+'</span></div>'
+'<div class="sx-pcard">'
+'<div class="sx-phead"><a href="'+esc(p.url)+'" target="_blank" rel="noopener" class="sx-ptitle">'+esc(p.title||pathOf(p.url))+'</a>'
+(p.dwell?'<span class="sx-pdwell"><i class="fa-regular fa-clock"></i> '+dur(p.dwell)+'</span>':'')+tags+'</div>'
+'<div class="sx-ppath">'+esc(pathOf(p.url))+'</div>'
+(acts?'<div class="sx-acts">'+acts+'</div>':'')
+'</div></div>';
});
// Conversions/Events vor der ersten Seite (Bucket -1)
if(buckets[-1]) jr = '<div class="sx-step"><div class="sx-rail"><span class="sx-dot sx-dot-pre"><i class="fa-solid fa-flag"></i></span></div><div class="sx-pcard"><div class="sx-acts">'+buckets[-1].map(actHtml).join('')+'</div></div></div>'+jr;
} else {
// Keine Seitendaten → flacher Verlauf
var flat=inter.slice().sort(function(a,b){ return (a.ts||'')<(b.ts||'')?-1:1; }).map(actHtml).join('');
jr = flat ? '<div class="sx-pcard"><div class="sx-acts">'+flat+'</div></div>' : '<div class="text-muted small py-2">Kein detaillierter Seitenverlauf übermittelt.</div>';
}
h+='</div><div class="sx-scroll">';
h+='<div class="sx-journey-h"><i class="fa-solid fa-route me-2 text-muted"></i>Verlauf der Sitzung</div>';
h+='<div class="sx-journey">'+jr+'</div>';
h+='</div>';
// ---- Technik ----
h+='<div class="sx-tech">'
+(d.user_agent?'<span><i class="fa-solid fa-microchip"></i> '+esc(ua(d.user_agent))+'</span>':'')
+'<span class="sx-ua-raw" title="'+esc(d.user_agent||'')+'">'+esc(d.user_agent||'')+'</span>'
+(d.session_hash?'<span><i class="fa-solid fa-fingerprint"></i> '+esc(d.session_hash)+'</span>':'')
+'</div>';
h+='</div>';
return h;
}
// ---- Modal mit Vor/Zurück-Navigation ----
var ids = Array.prototype.map.call(table.querySelectorAll('.vses-row'), function(r){ return r.getAttribute('data-session'); });
var modal = document.getElementById('vsesModal');
if(!modal) return;
var mBody = modal.querySelector('[data-vmod-body]');
var mIdx = modal.querySelector('[data-vmod-idx]');
var mTot = modal.querySelector('[data-vmod-total]');
var bPrev = modal.querySelector('[data-vmod-prev]');
var bNext = modal.querySelector('[data-vmod-next]');
var cache = {};
var cur = -1;
mTot.textContent = ids.length;
function load(id){
if(cache[id]){ mBody.innerHTML = render(cache[id]); return; }
mBody.innerHTML = '<div class="text-muted small py-4 text-center"><i class="fa-solid fa-circle-notch fa-spin me-1"></i>Lade …</div>';
fetch(base+'&session='+encodeURIComponent(id),{headers:{'X-Requested-With':'XMLHttpRequest'}})
.then(function(r){return r.json();})
.then(function(d){ if(d&&d.ok){ cache[id]=d; mBody.innerHTML=render(d); } else { mBody.innerHTML='<span class="text-danger small">Konnte Sitzung nicht laden.</span>'; } })
.catch(function(){ mBody.innerHTML='<span class="text-danger small">Ladefehler.</span>'; });
}
function openAt(i){
if(i<0||i>=ids.length) return;
cur=i;
mIdx.textContent=(i+1);
bPrev.disabled=(i<=0); bNext.disabled=(i>=ids.length-1);
modal.hidden=false; document.body.classList.add('vmod-open');
mBody.scrollTop=0;
load(ids[i]);
}
function close(){ modal.hidden=true; document.body.classList.remove('vmod-open'); }
Array.prototype.forEach.call(table.querySelectorAll('.vses-row'), function(row,i){
row.addEventListener('click', function(){ openAt(i); });
});
bPrev.addEventListener('click', function(){ openAt(cur-1); });
bNext.addEventListener('click', function(){ openAt(cur+1); });
Array.prototype.forEach.call(modal.querySelectorAll('[data-vmod-close]'), function(el){ el.addEventListener('click', close); });
document.addEventListener('keydown', function(e){
if(modal.hidden) return;
if(e.key==='Escape') close();
else if(e.key==='ArrowLeft') openAt(cur-1);
else if(e.key==='ArrowRight') openAt(cur+1);
});
})();