Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,471 @@
|
||||
@extends('admin.layouts.app')
|
||||
@section('title', 'İçerik İstatistikleri')
|
||||
@section('page-title', 'İçerik İstatistikleri')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.st-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px 22px; }
|
||||
.st-card .val { font-size: 2rem; font-weight: 800; line-height: 1.1; color: var(--text); letter-spacing:-0.5px; }
|
||||
.st-card .lbl { font-size: 0.78rem; color: var(--text2); margin-top: 4px; font-weight:600; }
|
||||
.st-card .sub { font-size: 0.72rem; color: var(--text3); margin-top: 3px; }
|
||||
.st-card .ico { font-size: 1.8rem; opacity: 0.5; }
|
||||
|
||||
.chart-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; }
|
||||
.chart-title { font-size: 0.88rem; font-weight: 700; color: var(--text); margin-bottom: 14px; }
|
||||
.section-head { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .8px; color: var(--text2); font-weight: 700; margin-bottom: 14px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
|
||||
|
||||
.tbl-sm th { font-size: 0.73rem; color: var(--text2); text-transform: uppercase; letter-spacing: .5px; padding: 8px 10px; }
|
||||
.tbl-sm td { font-size: 0.84rem; padding: 8px 10px; vertical-align: middle; border-top: 1px solid var(--border); color: var(--text); }
|
||||
.tbl-sm tr:first-child td { border-top: none; }
|
||||
|
||||
.pbar-wrap { height: 6px; background: var(--surface); border-radius: 3px; flex: 1; }
|
||||
.pbar-fill { height: 100%; background: linear-gradient(90deg,var(--accent),var(--accent-lt)); border-radius: 3px; }
|
||||
|
||||
/* GitHub-style heatmap */
|
||||
.heatmap-wrap { overflow-x: auto; padding-bottom: 4px; }
|
||||
.heatmap { display: flex; gap: 3px; }
|
||||
.heatmap-col { display: flex; flex-direction: column; gap: 3px; }
|
||||
.heat-cell {
|
||||
width: 13px; height: 13px; border-radius: 2px;
|
||||
background: var(--surface);
|
||||
cursor: default;
|
||||
transition: opacity .15s;
|
||||
position: relative;
|
||||
}
|
||||
.heat-cell:hover::after {
|
||||
content: attr(data-tip);
|
||||
position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
|
||||
background: var(--bg2); border: 1px solid var(--border2); color: var(--text);
|
||||
font-size: 11px; padding: 3px 8px; border-radius: 5px; white-space: nowrap;
|
||||
pointer-events: none; z-index: 100;
|
||||
}
|
||||
.heat-0 { background: var(--surface); }
|
||||
.heat-1 { background: rgba(124,58,237,0.25); }
|
||||
.heat-2 { background: rgba(124,58,237,0.45); }
|
||||
.heat-3 { background: rgba(124,58,237,0.7); }
|
||||
.heat-4 { background: var(--accent); }
|
||||
|
||||
.heatmap-legend { display: flex; align-items: center; gap: 4px; margin-top: 8px; font-size: .72rem; color: var(--text2); justify-content: flex-end; }
|
||||
.heatmap-legend span { width: 13px; height: 13px; border-radius: 2px; display: inline-block; }
|
||||
|
||||
.month-labels { display: flex; gap: 3px; margin-bottom: 4px; font-size: .72rem; color: var(--text3); padding-left: 22px; }
|
||||
.day-labels { display: flex; flex-direction: column; gap: 3px; margin-right: 4px; }
|
||||
.day-labels span { height: 13px; font-size: .68rem; color: var(--text3); line-height: 13px; }
|
||||
|
||||
.ep-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); }
|
||||
.ep-row:last-child { border-bottom: none; }
|
||||
.ep-badge { font-size: .7rem; padding: 2px 7px; border-radius: 10px; background: var(--surface); color: var(--text2); font-weight: 600; white-space: nowrap; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- Özet kartlar --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6 col-sm-4 col-lg">
|
||||
<div class="st-card h-100">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<div class="val">{{ number_format($totalAnimes) }}</div>
|
||||
<div class="lbl">Toplam Anime</div>
|
||||
<div class="sub">{{ number_format($publishedAnimes) }} yayında</div>
|
||||
</div>
|
||||
<i class="bi bi-play-circle ico text-info"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4 col-lg">
|
||||
<div class="st-card h-100">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<div class="val">{{ number_format($totalEpisodes) }}</div>
|
||||
<div class="lbl">Toplam Bölüm</div>
|
||||
<div class="sub">{{ number_format($publishedEps) }} yayında</div>
|
||||
</div>
|
||||
<i class="bi bi-collection-play ico" style="color:#a371f7"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4 col-lg">
|
||||
<div class="st-card h-100">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<div class="val">{{ number_format($totalSeasons) }}</div>
|
||||
<div class="lbl">Toplam Sezon</div>
|
||||
</div>
|
||||
<i class="bi bi-layers ico" style="color:#f0883e"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4 col-lg">
|
||||
<div class="st-card h-100">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
@php $avgEpPerAnime = $totalAnimes > 0 ? round($totalEpisodes / $totalAnimes, 1) : 0; @endphp
|
||||
<div class="val">{{ $avgEpPerAnime }}</div>
|
||||
<div class="lbl">Ort. Bölüm/Anime</div>
|
||||
</div>
|
||||
<i class="bi bi-bar-chart ico" style="color:var(--success)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4 col-lg">
|
||||
<div class="st-card h-100">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
@php $unpublished = $totalEpisodes - $publishedEps; @endphp
|
||||
<div class="val">{{ number_format($unpublished) }}</div>
|
||||
<div class="lbl">Taslak Bölüm</div>
|
||||
<div class="sub">Yayında değil</div>
|
||||
</div>
|
||||
<i class="bi bi-eye-slash ico" style="color:var(--text2)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Yükleme Isı Haritası --}}
|
||||
<div class="chart-card mb-4">
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<div class="chart-title mb-0">Bölüm Yükleme Yoğunluk Haritası <span style="color:#6e7681;font-size:.78rem">(son 52 hafta)</span></div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
// Ay etiketleri için hesaplama
|
||||
$heatMonths = [];
|
||||
foreach ($heatData as $wi => $week) {
|
||||
$firstDay = $week[0]['date'];
|
||||
$month = \Carbon\Carbon::parse($firstDay)->format('M');
|
||||
$dayOfMonth = \Carbon\Carbon::parse($firstDay)->day;
|
||||
if ($dayOfMonth <= 7 && !isset($lastMonth) || (isset($lastMonth) && $lastMonth !== $month)) {
|
||||
$heatMonths[$wi] = $month;
|
||||
$lastMonth = $month;
|
||||
} else {
|
||||
$heatMonths[$wi] = '';
|
||||
}
|
||||
}
|
||||
$heatMax = collect($heatData)->flatten(1)->max('cnt') ?: 1;
|
||||
@endphp
|
||||
|
||||
<div class="d-flex">
|
||||
{{-- Gün etiketleri --}}
|
||||
<div class="day-labels mt-4">
|
||||
<span> </span>
|
||||
<span>Pzt</span>
|
||||
<span> </span>
|
||||
<span>Çar</span>
|
||||
<span> </span>
|
||||
<span>Cum</span>
|
||||
<span> </span>
|
||||
</div>
|
||||
<div style="flex:1;min-width:0">
|
||||
{{-- Ay etiketleri --}}
|
||||
<div class="month-labels">
|
||||
@foreach($heatMonths as $wi => $mon)
|
||||
<span style="width:16px;text-align:left;flex-shrink:0">{{ $mon }}</span>
|
||||
@endforeach
|
||||
</div>
|
||||
{{-- Hücreler --}}
|
||||
<div class="heatmap-wrap">
|
||||
<div class="heatmap">
|
||||
@foreach($heatData as $week)
|
||||
<div class="heatmap-col">
|
||||
@foreach($week as $cell)
|
||||
@php
|
||||
$cnt = $cell['cnt'];
|
||||
if ($cnt === 0) $level = 0;
|
||||
elseif ($cnt <= 2) $level = 1;
|
||||
elseif ($cnt <= 5) $level = 2;
|
||||
elseif ($cnt <= 10) $level = 3;
|
||||
else $level = 4;
|
||||
$tip = $cell['date'] . ': ' . $cnt . ' bölüm';
|
||||
@endphp
|
||||
<div class="heat-cell heat-{{ $level }}" data-tip="{{ $tip }}" title="{{ $tip }}"></div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="heatmap-legend">
|
||||
<span>Az</span>
|
||||
<span class="heat-0"></span>
|
||||
<span class="heat-1"></span>
|
||||
<span class="heat-2"></span>
|
||||
<span class="heat-3"></span>
|
||||
<span class="heat-4"></span>
|
||||
<span>Çok</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 90 gün trend + Aylık dağılım --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="chart-card h-100">
|
||||
<div class="chart-title">Son 90 Gün — Günlük Yükleme Trendi</div>
|
||||
<div style="position:relative;height:200px">
|
||||
<canvas id="trendChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="chart-card h-100">
|
||||
<div class="chart-title">Aylık Bölüm Dağılımı (24 Ay)</div>
|
||||
<div style="position:relative;height:200px">
|
||||
<canvas id="monthChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Saatlik + Haftalık dağılım --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="chart-card h-100">
|
||||
<div class="chart-title">Saatlik Yükleme Dağılımı <span style="color:#6e7681;font-size:.78rem">(tüm zamanlar)</span></div>
|
||||
<div style="position:relative;height:160px">
|
||||
<canvas id="hourlyChart"></canvas>
|
||||
</div>
|
||||
@php
|
||||
$peakHour = array_search(max($hourlyEpsData), $hourlyEpsData);
|
||||
$peakCount = max($hourlyEpsData);
|
||||
@endphp
|
||||
@if($peakCount > 0)
|
||||
<div class="mt-2 text-center" style="font-size:.78rem;color:var(--text2)">
|
||||
En yoğun saat: <strong style="color:var(--accent)">{{ str_pad($peakHour,2,'0',STR_PAD_LEFT) }}:00</strong>
|
||||
({{ number_format($peakCount) }} bölüm)
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="chart-card h-100">
|
||||
<div class="chart-title">Haftanın Günlerine Göre <span style="color:#6e7681;font-size:.78rem">(tüm zamanlar)</span></div>
|
||||
<div style="position:relative;height:160px">
|
||||
<canvas id="weekdayChart"></canvas>
|
||||
</div>
|
||||
@php
|
||||
$peakDow = array_search(max($weekdayData), $weekdayData);
|
||||
$peakDowCount = max($weekdayData);
|
||||
@endphp
|
||||
@if($peakDowCount > 0)
|
||||
<div class="mt-2 text-center" style="font-size:.78rem;color:var(--text2)">
|
||||
En yoğun gün: <strong style="color:#a371f7">{{ $weekdayLabels[$peakDow] }}</strong>
|
||||
({{ number_format($peakDowCount) }} bölüm)
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Top animeler + Tür dağılımı --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-lg-6">
|
||||
<div class="chart-card h-100">
|
||||
<div class="section-head">En Fazla Bölüm İçeren 10 Anime</div>
|
||||
@php $maxEpCount = $topByEpisodes->max('episodes_count') ?: 1; @endphp
|
||||
@foreach($topByEpisodes as $i => $a)
|
||||
<div class="d-flex align-items-center gap-2 mb-2">
|
||||
<span style="font-size:.72rem;color:var(--text2);width:16px;text-align:right">{{ $i+1 }}</span>
|
||||
<span style="font-size:.82rem;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
|
||||
<a href="{{ route('admin.animes.show', $a) }}" style="color:var(--text);text-decoration:none" class="hover-accent">{{ $a->title }}</a>
|
||||
</span>
|
||||
@php
|
||||
$statusColor = match($a->status) { 'ongoing'=>'var(--success)','completed'=>'#79c0ff','upcoming'=>'#f0883e',default=>'var(--text2)' };
|
||||
@endphp
|
||||
<span style="font-size:.7rem;color:{{ $statusColor }}">
|
||||
{{ match($a->status){'ongoing'=>'Devam','completed'=>'Bitti','upcoming'=>'Yakında',default=>$a->status} }}
|
||||
</span>
|
||||
<div class="pbar-wrap" style="width:90px"><div class="pbar-fill" style="width:{{ round($a->episodes_count/$maxEpCount*100) }}%"></div></div>
|
||||
<span style="font-size:.78rem;color:var(--text2);width:35px;text-align:right">{{ $a->episodes_count }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="chart-card h-100">
|
||||
<div class="section-head">Türe Göre Bölüm Sayısı</div>
|
||||
@php $maxGenreEp = $genreEpStats->max('ep_count') ?: 1; @endphp
|
||||
@foreach($genreEpStats as $g)
|
||||
<div class="d-flex align-items-center gap-2 mb-2">
|
||||
<span style="font-size:.82rem;flex:1">{{ $g->name }}</span>
|
||||
<div class="pbar-wrap"><div class="pbar-fill" style="width:{{ round($g->ep_count/$maxGenreEp*100) }}%;background:#a371f7"></div></div>
|
||||
<span style="font-size:.78rem;color:var(--text2);width:38px;text-align:right">{{ number_format($g->ep_count) }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Son eklenen bölümler --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="chart-card h-100">
|
||||
<div class="section-head">Son Eklenen Bölümler</div>
|
||||
@foreach($recentEpisodes as $ep)
|
||||
<div class="ep-row">
|
||||
<div style="flex:1;min-width:0">
|
||||
<div style="font-size:.83rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
|
||||
{{ $ep->anime?->title ?? '—' }}
|
||||
</div>
|
||||
<div style="font-size:.72rem;color:var(--text2)">
|
||||
S{{ $ep->season?->season_number ?? '?' }}E{{ $ep->episode_number }}
|
||||
@if($ep->title) · {{ $ep->title }} @endif
|
||||
</div>
|
||||
</div>
|
||||
<span class="ep-badge {{ $ep->is_published ? '' : '' }}" style="{{ $ep->is_published ? 'background:#0e4429;color:var(--success)' : 'background:#3d1a1a;color:var(--danger)' }}">
|
||||
{{ $ep->is_published ? 'Yayında' : 'Taslak' }}
|
||||
</span>
|
||||
<span style="font-size:.72rem;color:#6e7681;white-space:nowrap">{{ $ep->created_at->diffForHumans() }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="chart-card h-100">
|
||||
<div class="section-head">Son Eklenen Animeler</div>
|
||||
@foreach($recentAnimes as $a)
|
||||
<div class="ep-row">
|
||||
<div style="flex:1;min-width:0">
|
||||
<div style="font-size:.83rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
|
||||
<a href="{{ route('admin.animes.show', $a) }}" style="color:var(--text);text-decoration:none">{{ $a->title }}</a>
|
||||
</div>
|
||||
<div style="font-size:.72rem;color:var(--text2)">
|
||||
{{ strtoupper($a->type) }}
|
||||
</div>
|
||||
</div>
|
||||
<span style="font-size:.7rem;padding:2px 7px;border-radius:10px;{{ $a->is_published ? 'background:#0e4429;color:var(--success)' : 'background:var(--surface);color:var(--text2)' }}">
|
||||
{{ $a->is_published ? 'Yayında' : 'Taslak' }}
|
||||
</span>
|
||||
<span style="font-size:.72rem;color:#6e7681;white-space:nowrap">{{ $a->created_at->diffForHumans() }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.2/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
Chart.defaults.color = 'var(--text2)';
|
||||
Chart.defaults.borderColor = 'var(--border)';
|
||||
|
||||
// ── 90 gün trend ─────────────────────────────────────────────────────────────
|
||||
new Chart(document.getElementById('trendChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: @json($trendLabels),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Bölüm',
|
||||
data: @json($epTrendData),
|
||||
borderColor: 'var(--accent)',
|
||||
backgroundColor: 'rgba(232,67,147,.1)',
|
||||
fill: true, tension: 0.4, pointRadius: 2,
|
||||
yAxisID: 'y',
|
||||
},
|
||||
{
|
||||
label: 'Anime',
|
||||
data: @json($animeTrendData),
|
||||
borderColor: 'var(--success)',
|
||||
backgroundColor: 'rgba(63,185,80,.08)',
|
||||
fill: true, tension: 0.4, pointRadius: 2,
|
||||
yAxisID: 'y',
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
interaction: { mode: 'index', intersect: false },
|
||||
plugins: {
|
||||
legend: { display: true, labels: { font: { size: 11 }, boxWidth: 10, padding: 12 } }
|
||||
},
|
||||
scales: {
|
||||
x: { grid: { color: 'var(--border)' }, ticks: { maxTicksLimit: 10, font: { size: 10 } } },
|
||||
y: { grid: { color: 'var(--border)' }, ticks: { font: { size: 10 } }, beginAtZero: true },
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ── Aylık bölüm ───────────────────────────────────────────────────────────────
|
||||
new Chart(document.getElementById('monthChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: @json($monthLabels),
|
||||
datasets: [{
|
||||
label: 'Bölüm',
|
||||
data: @json($monthData),
|
||||
backgroundColor: 'rgba(163,113,247,.6)',
|
||||
borderColor: '#a371f7',
|
||||
borderWidth: 1,
|
||||
borderRadius: 3,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: {
|
||||
x: { grid: { display: false }, ticks: { font: { size: 9 }, maxTicksLimit: 8 } },
|
||||
y: { grid: { color: 'var(--border)' }, ticks: { font: { size: 10 } }, beginAtZero: true },
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ── Saatlik dağılım ───────────────────────────────────────────────────────────
|
||||
new Chart(document.getElementById('hourlyChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: Array.from({length:24}, (_,i) => `${String(i).padStart(2,'0')}:00`),
|
||||
datasets: [{
|
||||
label: 'Bölüm',
|
||||
data: @json($hourlyEpsData),
|
||||
backgroundColor: ctx => {
|
||||
const max = Math.max(...@json($hourlyEpsData));
|
||||
return ctx.parsed.y === max ? 'var(--accent)' : 'rgba(232,67,147,.35)';
|
||||
},
|
||||
borderColor: 'var(--accent)',
|
||||
borderWidth: 1,
|
||||
borderRadius: 3,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: {
|
||||
x: { grid: { display: false }, ticks: { font: { size: 9 } } },
|
||||
y: { grid: { color: 'var(--border)' }, ticks: { font: { size: 10 } }, beginAtZero: true },
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ── Haftanın günleri ──────────────────────────────────────────────────────────
|
||||
new Chart(document.getElementById('weekdayChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: @json($weekdayLabels),
|
||||
datasets: [{
|
||||
label: 'Bölüm',
|
||||
data: @json($weekdayData),
|
||||
backgroundColor: ctx => {
|
||||
const max = Math.max(...@json($weekdayData));
|
||||
return ctx.parsed.y === max ? '#a371f7' : 'rgba(163,113,247,.35)';
|
||||
},
|
||||
borderColor: '#a371f7',
|
||||
borderWidth: 1,
|
||||
borderRadius: 4,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: {
|
||||
x: { grid: { display: false }, ticks: { font: { size: 11 } } },
|
||||
y: { grid: { color: 'var(--border)' }, ticks: { font: { size: 10 } }, beginAtZero: true },
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
Reference in New Issue
Block a user