mirror of
https://github.com/the-programmers-hangout/Hermes.git
synced 2026-09-09 07:56:20 +02:00
bottom chart and responsive changes
This commit is contained in:
@@ -35,6 +35,29 @@
|
||||
'values' => data_get($stats, 'usage_over_time.values', []),
|
||||
],
|
||||
];
|
||||
|
||||
$customUsageTables = [
|
||||
[
|
||||
'title' => 'Top 10 Static Emotes',
|
||||
'list' => $stats['top_static'] ?? collect(),
|
||||
'empty' => 'No static emote usage found.',
|
||||
],
|
||||
[
|
||||
'title' => 'Top 10 Animated Emotes',
|
||||
'list' => $stats['top_animated'] ?? collect(),
|
||||
'empty' => 'No animated emote usage found.',
|
||||
],
|
||||
[
|
||||
'title' => 'Bottom 10 Static Emotes',
|
||||
'list' => $stats['bottom_static'] ?? collect(),
|
||||
'empty' => 'No static emote usage found.',
|
||||
],
|
||||
[
|
||||
'title' => 'Bottom 10 Animated Emotes',
|
||||
'list' => $stats['bottom_animated'] ?? collect(),
|
||||
'empty' => 'No animated emote usage found.',
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<x-layouts.app>
|
||||
@@ -69,36 +92,36 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mb-8 overflow-x-auto lg:overflow-visible">
|
||||
<div class="flex gap-3 pb-1 min-w-max lg:min-w-0 lg:w-full lg:justify-between">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="mb-8">
|
||||
<div class="grid gap-3 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-6">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Total Emoji Usage</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['total_usage'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['total_usage'] ?? 0 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Unique Emotes</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['unique_emotes'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['unique_emotes'] ?? 0 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Users Included</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['unique_users'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['unique_users'] ?? 0 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Static Usage</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['usage_by_type']['STATIC'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['usage_by_type']['STATIC'] ?? 0 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Animated Usage</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['usage_by_type']['ANIMATED'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['usage_by_type']['ANIMATED'] ?? 0 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-[180px] lg:min-w-0 lg:flex-1">
|
||||
<div class="p-4 border rounded-lg bg-[#2b2d31] border-[#3f4147] min-w-0">
|
||||
<p class="text-xs font-medium uppercase tracking-wide text-[#b5bac1]">Unicode Usage</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white">{{ $stats['usage_by_type']['UNICODE'] ?? 0 }}</p>
|
||||
<p class="mt-2 text-2xl font-semibold text-white break-words">{{ $stats['usage_by_type']['UNICODE'] ?? 0 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -107,91 +130,84 @@
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Emote Usage Over Time (Last 30 Days)</h3>
|
||||
|
||||
<div class="p-6 border rounded-lg bg-[#2b2d31] border-[#3f4147] md:p-7">
|
||||
<canvas id="emoji-usage-over-time-chart"></canvas>
|
||||
<div class="p-4 overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147] md:p-5">
|
||||
<div class="h-44 min-w-0 sm:h-56 md:h-64 lg:h-72">
|
||||
<canvas id="emoji-usage-over-time-chart" class="w-full h-full"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-8 lg:grid-cols-2">
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top Movers (Last 7 Days vs Previous 7 Days)</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_movers'] ?? collect()) as $emote)
|
||||
<div class="flex flex-col items-start gap-2 px-4 py-3.5 border-b border-[#3f4147] sm:flex-row sm:items-center sm:justify-between sm:gap-3 last:border-b-0">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
@if (($emote->type ?? null) === 'UNICODE')
|
||||
<span class="font-medium truncate text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
@else
|
||||
<img src="{{ $emoteImageSrc($emote->image) }}" alt="{{ $emote->emote_name }}" class="object-cover w-9 h-9 border rounded border-[#3f4147]" />
|
||||
<span class="font-medium truncate text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="text-left sm:text-right sm:shrink-0">
|
||||
<p class="text-sm text-[#b5bac1]">{{ $emote->previous_count }} → {{ $emote->current_count }}</p>
|
||||
<p class="text-sm font-medium {{ $emote->delta >= 0 ? 'text-[#57f287]' : 'text-[#ed4245]' }}">
|
||||
{{ $emote->delta >= 0 ? '+' : '' }}{{ $emote->delta }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No mover data available yet.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top 10 Unicode Emotes</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_unicode'] ?? collect()) as $emote)
|
||||
<div class="flex flex-col items-start gap-2 px-4 py-3.5 border-b border-[#3f4147] sm:flex-row sm:items-center sm:justify-between sm:gap-3 last:border-b-0">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<span class="w-8 text-sm font-semibold text-[#b5bac1]">#{{ $loop->iteration }}</span>
|
||||
<span class="font-medium truncate text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-[#b5bac1] sm:shrink-0">{{ $emote->total_usage }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No unicode emote usage found.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top Movers (Last 7 Days vs Previous 7 Days)</h3>
|
||||
<h3 class="text-xl font-semibold text-white">Custom Emote Usage (Top & Bottom)</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_movers'] ?? collect()) as $emote)
|
||||
<div class="flex items-center justify-between px-4 py-3.5 border-b border-[#3f4147] last:border-b-0">
|
||||
<div class="flex items-center gap-3">
|
||||
@if (($emote->type ?? null) === 'UNICODE')
|
||||
<span class="font-medium text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
@else
|
||||
<img src="{{ $emoteImageSrc($emote->image) }}" alt="{{ $emote->emote_name }}" class="object-cover w-9 h-9 border rounded border-[#3f4147]" />
|
||||
<span class="font-medium text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-sm text-[#b5bac1]">{{ $emote->previous_count }} → {{ $emote->current_count }}</p>
|
||||
<p class="text-sm font-medium {{ $emote->delta >= 0 ? 'text-[#57f287]' : 'text-[#ed4245]' }}">
|
||||
{{ $emote->delta >= 0 ? '+' : '' }}{{ $emote->delta }}
|
||||
</p>
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
@foreach ($customUsageTables as $table)
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
<div class="px-4 py-3 border-b border-[#3f4147]">
|
||||
<h4 class="text-sm font-semibold text-white">{{ $table['title'] }}</h4>
|
||||
</div>
|
||||
|
||||
@forelse ($table['list'] as $emote)
|
||||
<div class="flex flex-col items-start gap-2 px-4 py-3.5 border-b border-[#3f4147] sm:flex-row sm:items-center sm:justify-between sm:gap-3 last:border-b-0">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<span class="w-8 text-sm font-semibold text-[#b5bac1]">#{{ $loop->iteration }}</span>
|
||||
<img src="{{ $emoteImageSrc($emote->image) }}" alt="{{ $emote->emote_name }}" class="object-cover w-9 h-9 border rounded border-[#3f4147]" />
|
||||
<span class="font-medium truncate text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-[#b5bac1] sm:shrink-0">{{ $emote->total_usage }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">{{ $table['empty'] }}</p>
|
||||
@endforelse
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No mover data available yet.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top 10 Static Emotes</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_static'] ?? collect()) as $emote)
|
||||
<div class="flex items-center justify-between px-4 py-3.5 border-b border-[#3f4147] last:border-b-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="w-8 text-sm font-semibold text-[#b5bac1]">#{{ $loop->iteration }}</span>
|
||||
<img src="{{ $emoteImageSrc($emote->image) }}" alt="{{ $emote->emote_name }}" class="object-cover w-9 h-9 border rounded border-[#3f4147]" />
|
||||
<span class="font-medium text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-[#b5bac1]">{{ $emote->total_usage }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No static emote usage found.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top 10 Animated Emotes</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_animated'] ?? collect()) as $emote)
|
||||
<div class="flex items-center justify-between px-4 py-3.5 border-b border-[#3f4147] last:border-b-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="w-8 text-sm font-semibold text-[#b5bac1]">#{{ $loop->iteration }}</span>
|
||||
<img src="{{ $emoteImageSrc($emote->image) }}" alt="{{ $emote->emote_name }}" class="object-cover w-9 h-9 border rounded border-[#3f4147]" />
|
||||
<span class="font-medium text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-[#b5bac1]">{{ $emote->total_usage }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No animated emote usage found.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<h3 class="text-xl font-semibold text-white">Top 10 Unicode Emotes</h3>
|
||||
|
||||
<div class="overflow-hidden border rounded-lg bg-[#2b2d31] border-[#3f4147]">
|
||||
@forelse (($stats['top_unicode'] ?? collect()) as $emote)
|
||||
<div class="flex items-center justify-between px-4 py-3.5 border-b border-[#3f4147] last:border-b-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="w-8 text-sm font-semibold text-[#b5bac1]">#{{ $loop->iteration }}</span>
|
||||
<span class="font-medium text-[#dbdee1]">{{ $emote->emote_name }}</span>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-[#b5bac1]">{{ $emote->total_usage }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-4 py-3 text-sm text-[#b5bac1]">No unicode emote usage found.</p>
|
||||
@endforelse
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -237,6 +253,7 @@
|
||||
|
||||
const usageOverTimeCanvas = document.getElementById('emoji-usage-over-time-chart');
|
||||
const usageOverTime = payload.usage_over_time || { labels: [], values: [] };
|
||||
const isMobileViewport = window.matchMedia('(max-width: 639px)').matches;
|
||||
|
||||
if (usageOverTimeCanvas) {
|
||||
hermesDestroyChart('usageOverTime');
|
||||
@@ -250,15 +267,23 @@
|
||||
tension: 0.3,
|
||||
fill: false,
|
||||
borderColor: '#5865f2',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: '#5865f2',
|
||||
pointBorderColor: '#5865f2'
|
||||
pointBorderColor: '#5865f2',
|
||||
pointRadius: isMobileViewport ? 0 : 2,
|
||||
pointHoverRadius: isMobileViewport ? 2 : 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
maintainAspectRatio: false,
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: !isMobileViewport,
|
||||
labels: {
|
||||
color: '#dbdee1'
|
||||
}
|
||||
@@ -267,17 +292,23 @@
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
color: '#b5bac1'
|
||||
color: '#b5bac1',
|
||||
autoSkip: true,
|
||||
maxTicksLimit: isMobileViewport ? 4 : 8,
|
||||
maxRotation: 0,
|
||||
minRotation: 0
|
||||
},
|
||||
grid: {
|
||||
color: '#3f4147'
|
||||
color: '#3f4147',
|
||||
display: !isMobileViewport
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
precision: 0,
|
||||
color: '#b5bac1'
|
||||
color: '#b5bac1',
|
||||
maxTicksLimit: isMobileViewport ? 5 : 8
|
||||
},
|
||||
grid: {
|
||||
color: '#3f4147'
|
||||
@@ -291,6 +322,10 @@
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
hermesRenderOverTimeChart();
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
hermesRenderOverTimeChart();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endonce
|
||||
|
||||
Reference in New Issue
Block a user