173 lines
8.7 KiB
PHP
173 lines
8.7 KiB
PHP
<div>
|
|
{{-- Page header --}}
|
|
<div class="flex items-center justify-between mb-7 nim-reveal nim-reveal-1">
|
|
<div>
|
|
<h1 class="text-t1">Overview</h1>
|
|
<p class="text-xs text-t3 mt-0.5">{{ now()->format('l, F j') }}</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<a href="{{ route('w.analytics.index', $workspaceUlid) }}"
|
|
wire:navigate
|
|
class="px-3 py-2 text-xs text-t2 hover:text-t1 transition-colors flex items-center gap-1.5">
|
|
<x-heroicon-o-arrow-trending-up class="w-3.5 h-3.5" />
|
|
Analytics
|
|
</a>
|
|
<a href="{{ route('w.qr.index', $workspaceUlid) }}"
|
|
wire:navigate
|
|
class="px-3 py-2 bg-s2 border border-white/[.06] text-t1 rounded-lg text-xs font-medium hover:bg-s3 transition-colors">
|
|
+ QR Code
|
|
</a>
|
|
<a href="{{ route('w.links.index', $workspaceUlid) }}"
|
|
wire:navigate
|
|
class="px-3 py-2 bg-accent-gradient text-white rounded-lg text-xs font-semibold hover:opacity-90 transition-opacity">
|
|
+ New Link
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Metric cards --}}
|
|
<div class="grid grid-cols-2 lg:grid-cols-4 gap-3 mb-5">
|
|
<div class="bg-s1 border border-white/[.06] rounded-xl p-4 card-shadow card-accent-top nim-reveal nim-reveal-1">
|
|
<div class="text-xs font-medium text-t3 uppercase tracking-widest mb-3">Today</div>
|
|
<div class="metric-num text-3xl text-t1">{{ number_format($today) }}</div>
|
|
<div class="text-xs text-t3 mt-1.5">clicks since midnight</div>
|
|
</div>
|
|
|
|
<div class="bg-s1 border border-white/[.06] rounded-xl p-4 card-shadow nim-reveal nim-reveal-2">
|
|
<div class="text-xs font-medium text-t3 uppercase tracking-widest mb-3">7 Days</div>
|
|
<div class="metric-num text-3xl text-t1">{{ number_format($last7) }}</div>
|
|
<div class="text-xs text-t3 mt-1.5">rolling window</div>
|
|
</div>
|
|
|
|
<div class="bg-s1 border border-white/[.06] rounded-xl p-4 card-shadow nim-reveal nim-reveal-3">
|
|
<div class="text-xs font-medium text-t3 uppercase tracking-widest mb-3">30 Days</div>
|
|
<div class="metric-num text-3xl text-t1">{{ number_format($last30) }}</div>
|
|
<div class="text-xs text-t3 mt-1.5">rolling window</div>
|
|
</div>
|
|
|
|
<div class="bg-s1 border border-white/[.06] rounded-xl p-4 card-shadow nim-reveal nim-reveal-4">
|
|
<div class="text-xs font-medium text-t3 uppercase tracking-widest mb-3">Links</div>
|
|
<div class="metric-num text-3xl text-t1">{{ number_format($totalLinks) }}</div>
|
|
<div class="text-xs text-t3 mt-1.5">active links</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Chart --}}
|
|
<div
|
|
class="bg-s1 border border-white/[.06] rounded-xl p-5 mb-4 card-shadow nim-reveal nim-reveal-5"
|
|
x-data
|
|
x-init="
|
|
const ctx = document.getElementById('clicksChart');
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: {{ Js::from($labels) }},
|
|
datasets: [{
|
|
data: {{ Js::from($data) }},
|
|
borderColor: '#7c3aed',
|
|
backgroundColor: (ctx) => {
|
|
const g = ctx.chart.ctx.createLinearGradient(0, 0, 0, 160);
|
|
g.addColorStop(0, 'rgba(124,58,237,0.18)');
|
|
g.addColorStop(1, 'rgba(124,58,237,0.00)');
|
|
return g;
|
|
},
|
|
fill: true,
|
|
tension: 0.4,
|
|
pointRadius: 0,
|
|
pointHoverRadius: 4,
|
|
pointHoverBackgroundColor: '#7c3aed',
|
|
borderWidth: 1.5,
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: { mode: 'index', intersect: false },
|
|
plugins: {
|
|
legend: { display: false },
|
|
tooltip: {
|
|
backgroundColor: '#111117',
|
|
borderColor: 'rgba(255,255,255,0.08)',
|
|
borderWidth: 1,
|
|
titleColor: '#8888a0',
|
|
bodyColor: '#f0f0f5',
|
|
titleFont: { family: 'JetBrains Mono', size: 10 },
|
|
bodyFont: { family: 'JetBrains Mono', size: 13, weight: '700' },
|
|
padding: 10,
|
|
displayColors: false,
|
|
callbacks: { label: ctx => ctx.parsed.y.toLocaleString() + ' clicks' }
|
|
}
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: { color: 'rgba(255,255,255,0.03)', drawTicks: false },
|
|
border: { display: false },
|
|
ticks: { color: '#44445a', font: { family: 'JetBrains Mono', size: 10 }, maxTicksLimit: 8, maxRotation: 0 }
|
|
},
|
|
y: {
|
|
position: 'right',
|
|
grid: { color: 'rgba(255,255,255,0.03)', drawTicks: false },
|
|
border: { display: false },
|
|
ticks: { color: '#44445a', font: { family: 'JetBrains Mono', size: 10 }, maxTicksLimit: 4 },
|
|
beginAtZero: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
"
|
|
>
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="text-xs font-semibold text-t1 tracking-wide">CLICKS — LAST 30 DAYS</div>
|
|
<div class="w-2 h-2 rounded-full bg-accent-gradient"></div>
|
|
</div>
|
|
<div class="h-44">
|
|
<canvas id="clicksChart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Top Links --}}
|
|
<div class="bg-s1 border border-white/[.06] rounded-xl overflow-hidden card-shadow nim-reveal nim-reveal-5">
|
|
<div class="px-5 py-3.5 border-b border-white/[.06] flex items-center justify-between">
|
|
<div class="text-xs font-semibold text-t1 tracking-wide uppercase">Top Links</div>
|
|
<a href="{{ route('w.links.index', $workspaceUlid) }}" wire:navigate
|
|
class="text-xs text-t3 hover:text-t1 transition-colors">View all →</a>
|
|
</div>
|
|
<table class="w-full">
|
|
<thead>
|
|
<tr class="text-t3 text-xs uppercase tracking-widest border-b border-white/[.04]">
|
|
<th class="px-5 py-2.5 text-left font-medium w-8">#</th>
|
|
<th class="px-5 py-2.5 text-left font-medium">Slug</th>
|
|
<th class="px-5 py-2.5 text-left font-medium hidden md:table-cell">Title</th>
|
|
<th class="px-5 py-2.5 text-right font-medium">Clicks</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($topLinks as $index => $link)
|
|
<tr class="border-b border-white/[.03] last:border-0 table-row-hover hover:bg-white/[.015]">
|
|
<td class="px-5 py-3 text-t3 font-mono text-xs tabular-nums">{{ str_pad($index + 1, 2, '0', STR_PAD_LEFT) }}</td>
|
|
<td class="px-5 py-3">
|
|
<div class="flex items-baseline gap-1">
|
|
<span class="text-t3 text-xs">nimu.li/</span><span class="font-mono text-blue text-sm font-medium">{{ $link->slug }}</span>
|
|
</div>
|
|
</td>
|
|
<td class="px-5 py-3 text-t3 text-xs truncate max-w-xs hidden md:table-cell">{{ $link->title ?: '—' }}</td>
|
|
<td class="px-5 py-3 text-right font-mono text-t1 font-bold text-sm tabular-nums">{{ number_format($link->total_clicks) }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="4" class="px-5 py-12 text-center">
|
|
<div class="flex flex-col items-center gap-3">
|
|
<svg class="w-8 h-8 text-t3" fill="none" viewBox="0 0 32 32" stroke="currentColor" stroke-width="1">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19 11l-8 8M11 11h8v8"/>
|
|
<circle cx="16" cy="16" r="13" stroke-dasharray="4 3"/>
|
|
</svg>
|
|
<p class="text-xs text-t3">No links yet — create your first one</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|