Deploy Ladill Link / deploy (push) Successful in 37s
Add Bitly-style branded domain support via Ladill Domains SSL API, account analytics dashboard, settings page with default domain picker, and fix SSO/dashboard issues from QR Plus template leftovers. Co-authored-by: Cursor <cursoragent@cursor.com>
94 lines
5.2 KiB
PHP
94 lines
5.2 KiB
PHP
<x-user-layout>
|
|
<x-slot name="title">Analytics</x-slot>
|
|
<div class="mx-auto max-w-6xl space-y-6">
|
|
<div>
|
|
<h1 class="text-2xl font-semibold text-slate-900">Analytics</h1>
|
|
<p class="mt-1 text-sm text-slate-500">Click activity across all your short links.</p>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4 sm:grid-cols-5">
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<p class="text-2xl font-bold text-slate-900">{{ number_format($summary['total_clicks']) }}</p>
|
|
<p class="mt-0.5 text-xs text-slate-500">Total clicks</p>
|
|
</div>
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<p class="text-2xl font-bold text-slate-900">{{ number_format($summary['unique_clicks']) }}</p>
|
|
<p class="mt-0.5 text-xs text-slate-500">Unique clicks</p>
|
|
</div>
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<p class="text-2xl font-bold text-slate-900">{{ number_format($summary['clicks_7d']) }}</p>
|
|
<p class="mt-0.5 text-xs text-slate-500">Last 7 days</p>
|
|
</div>
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<p class="text-2xl font-bold text-slate-900">{{ number_format($summary['clicks_30d']) }}</p>
|
|
<p class="mt-0.5 text-xs text-slate-500">Last 30 days</p>
|
|
</div>
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<p class="text-2xl font-bold text-emerald-700">{{ number_format($summary['links_total']) }}</p>
|
|
<p class="mt-0.5 text-xs text-slate-500">Links created</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-xl border border-slate-200 bg-white p-6">
|
|
<h2 class="text-sm font-semibold text-slate-900">Clicks — last 30 days</h2>
|
|
@php $maxDaily = max(1, $dailyClicks->max('total')); @endphp
|
|
<div class="mt-5 flex h-28 items-end gap-px">
|
|
@foreach($dailyClicks as $day)
|
|
<div class="group relative flex flex-1 flex-col items-center justify-end" title="{{ $day->date }}: {{ $day->total }}">
|
|
<div class="w-full rounded-t-sm bg-emerald-400/70 transition-colors group-hover:bg-emerald-600"
|
|
style="height: {{ max(2, ($day->total / $maxDaily) * 100) }}%"></div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid gap-4 lg:grid-cols-2">
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<h2 class="text-sm font-semibold text-slate-900">Top links</h2>
|
|
<ul class="mt-4 space-y-2.5">
|
|
@forelse($topLinks as $row)
|
|
<li class="flex items-center justify-between gap-3 text-sm">
|
|
<a href="{{ $row['url'] }}" class="truncate text-slate-600 hover:text-emerald-700">{{ $row['label'] }}</a>
|
|
<span class="shrink-0 font-semibold text-slate-900">{{ number_format($row['total']) }}</span>
|
|
</li>
|
|
@empty
|
|
<li class="text-sm text-slate-400">No clicks yet</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
<div class="rounded-xl border border-slate-200 bg-white p-5">
|
|
<h2 class="text-sm font-semibold text-slate-900">Top referrers</h2>
|
|
<ul class="mt-4 space-y-2.5">
|
|
@forelse($referrers as $row)
|
|
<li class="flex items-center justify-between gap-3 text-sm">
|
|
<span class="truncate text-slate-600">{{ $row['label'] }}</span>
|
|
<span class="shrink-0 font-semibold text-slate-900">{{ number_format($row['total']) }}</span>
|
|
</li>
|
|
@empty
|
|
<li class="text-sm text-slate-400">No referrer data yet</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-xl border border-slate-200 bg-white">
|
|
<div class="border-b border-slate-100 px-5 py-4">
|
|
<h2 class="font-semibold text-slate-900">Recent clicks</h2>
|
|
</div>
|
|
<ul class="divide-y divide-slate-100">
|
|
@forelse($recentClicks as $click)
|
|
<li class="flex items-center justify-between gap-4 px-5 py-3 text-sm">
|
|
<div class="min-w-0">
|
|
<p class="font-medium text-slate-900">{{ $click->shortLink?->label ?: $click->shortLink?->slug }}</p>
|
|
<p class="truncate text-xs text-slate-500">{{ $click->referer ?: 'Direct / unknown' }}</p>
|
|
</div>
|
|
<time class="shrink-0 text-xs text-slate-400">{{ $click->clicked_at->diffForHumans() }}</time>
|
|
</li>
|
|
@empty
|
|
<li class="px-5 py-8 text-center text-sm text-slate-400">No clicks recorded yet.</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</x-user-layout>
|