nimuli/resources/views/livewire/pages/dashboard/overview.blade.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>