mirror of
https://github.com/getnamingo/registry.git
synced 2025-07-20 17:46:03 +02:00
More data on the dashboard
This commit is contained in:
parent
5f720233ef
commit
78594c693f
5 changed files with 318 additions and 3 deletions
|
@ -57,6 +57,95 @@ class HomeController extends Controller
|
||||||
'tickets' => $tickets,
|
'tickets' => $tickets,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
|
$endDate = new \DateTime();
|
||||||
|
$startDate = (new \DateTime())->modify('-4 days');
|
||||||
|
|
||||||
|
// Format dates for comparison
|
||||||
|
$startDateFormatted = $startDate->format('Y-m-d');
|
||||||
|
$endDateFormatted = $endDate->format('Y-m-d');
|
||||||
|
|
||||||
|
$query = "SELECT DATE(crdate) as date, COUNT(id) as count
|
||||||
|
FROM domain
|
||||||
|
WHERE crdate >= :startDate AND crdate <= :endDate
|
||||||
|
GROUP BY DATE(crdate)
|
||||||
|
ORDER BY DATE(crdate) ASC";
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
':startDate' => $startDateFormatted,
|
||||||
|
':endDate' => $endDateFormatted,
|
||||||
|
];
|
||||||
|
|
||||||
|
$domainsCount = $db->select($query, $params);
|
||||||
|
|
||||||
|
$dates = [];
|
||||||
|
$counts = [];
|
||||||
|
|
||||||
|
foreach ($domainsCount as $row) {
|
||||||
|
// Extract just the date part from the datetime string
|
||||||
|
$date = (new \DateTime($row['date']))->format('Y-m-d');
|
||||||
|
$count = (int)$row['count']; // Ensure count is an integer
|
||||||
|
|
||||||
|
$dates[] = $date;
|
||||||
|
$counts[] = $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "
|
||||||
|
SELECT
|
||||||
|
r.id,
|
||||||
|
r.name,
|
||||||
|
COUNT(d.id) AS domain_count
|
||||||
|
FROM
|
||||||
|
registrar r
|
||||||
|
JOIN
|
||||||
|
domain d ON r.id = d.clid
|
||||||
|
GROUP BY
|
||||||
|
r.id
|
||||||
|
ORDER BY
|
||||||
|
domain_count DESC
|
||||||
|
LIMIT 10;
|
||||||
|
";
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
$results = $db->select($query);
|
||||||
|
|
||||||
|
// Prepare data for the chart
|
||||||
|
$labels = [];
|
||||||
|
$series = [];
|
||||||
|
|
||||||
|
foreach ($results as $row) {
|
||||||
|
$labels[] = $row['name']; // Registrar names for chart labels
|
||||||
|
$series[] = (int)$row['domain_count']; // Domain counts for chart data
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "
|
||||||
|
SELECT
|
||||||
|
DATE(date_created) as ticket_date,
|
||||||
|
SUM(CASE WHEN status IN ('Open', 'In Progress') THEN 1 ELSE 0 END) AS unanswered,
|
||||||
|
SUM(CASE WHEN status IN ('Resolved', 'Closed') THEN 1 ELSE 0 END) AS answered
|
||||||
|
FROM
|
||||||
|
support_tickets
|
||||||
|
WHERE
|
||||||
|
date_created >= CURRENT_DATE - INTERVAL 7 DAY
|
||||||
|
GROUP BY
|
||||||
|
DATE(date_created)
|
||||||
|
ORDER BY
|
||||||
|
DATE(date_created) ASC;
|
||||||
|
";
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
$results = $db->select($query);
|
||||||
|
|
||||||
|
// Prepare data for ApexCharts
|
||||||
|
$labels3 = [];
|
||||||
|
$answeredData = [];
|
||||||
|
$unansweredData = [];
|
||||||
|
|
||||||
|
foreach ($results as $row) {
|
||||||
|
$labels3[] = $row['ticket_date'];
|
||||||
|
$answeredData[] = (int) $row['answered']; // Cast to int for ApexCharts
|
||||||
|
$unansweredData[] = (int) $row['unanswered']; // Cast to int for ApexCharts
|
||||||
|
}
|
||||||
|
|
||||||
$domains = $db->selectValue('SELECT count(id) as domains FROM domain');
|
$domains = $db->selectValue('SELECT count(id) as domains FROM domain');
|
||||||
$latest_domains = $db->select('SELECT name, crdate FROM domain ORDER BY crdate DESC LIMIT 10');
|
$latest_domains = $db->select('SELECT name, crdate FROM domain ORDER BY crdate DESC LIMIT 10');
|
||||||
$tickets = $db->select('SELECT id, subject, status, priority FROM support_tickets ORDER BY date_created DESC LIMIT 10');
|
$tickets = $db->select('SELECT id, subject, status, priority FROM support_tickets ORDER BY date_created DESC LIMIT 10');
|
||||||
|
@ -71,6 +160,13 @@ class HomeController extends Controller
|
||||||
'registrars' => $registrars,
|
'registrars' => $registrars,
|
||||||
'latest_domains' => $latest_domains,
|
'latest_domains' => $latest_domains,
|
||||||
'tickets' => $tickets,
|
'tickets' => $tickets,
|
||||||
|
'dates' => json_encode($dates),
|
||||||
|
'counts' => json_encode($counts),
|
||||||
|
'labels' => json_encode($labels),
|
||||||
|
'series' => json_encode($series),
|
||||||
|
'labels3' => json_encode($labels3),
|
||||||
|
'answeredData' => json_encode($answeredData),
|
||||||
|
'unansweredData' => json_encode($unansweredData),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,30 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<div class="col-lg-6 col-xl-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="card-title">{{ __('Last 5 Days: Domain Registrations') }}</h3>
|
||||||
|
<div id="last-5-days"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6 col-xl-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="card-title">{{ __('Top Registrars by Domains') }}</h3>
|
||||||
|
<div id="top-registrars"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6 col-xl-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="card-title">{{ __('Support Tickets: Last Week') }}</h3>
|
||||||
|
<div id="support-tickets"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col-12 col-md-6 mt-5">
|
<div class="col-12 col-md-6 mt-5">
|
||||||
<h3 class="card-title">{{ __('Recent Domains') }}</h3>
|
<h3 class="card-title">{{ __('Recent Domains') }}</h3>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -229,4 +253,198 @@
|
||||||
</div>
|
</div>
|
||||||
{% include 'partials/footer.twig' %}
|
{% include 'partials/footer.twig' %}
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
var dates = JSON.parse('{{ dates|raw }}');
|
||||||
|
var counts = JSON.parse('{{ counts|raw }}');
|
||||||
|
|
||||||
|
var labels = JSON.parse('{{ labels|raw }}');
|
||||||
|
var series = JSON.parse('{{ series|raw }}');
|
||||||
|
|
||||||
|
var labels3 = JSON.parse('{{ labels3|raw }}');
|
||||||
|
var answeredData = JSON.parse('{{ answeredData|raw }}');
|
||||||
|
var unansweredData = JSON.parse('{{ unansweredData|raw }}');
|
||||||
|
|
||||||
|
window.ApexCharts && (new ApexCharts(document.getElementById('last-5-days'), {
|
||||||
|
chart: {
|
||||||
|
type: "bar",
|
||||||
|
fontFamily: 'inherit',
|
||||||
|
height: 240,
|
||||||
|
parentHeightOffset: 0,
|
||||||
|
toolbar: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
animations: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
bar: {
|
||||||
|
columnWidth: '50%',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: "Domain Registrations",
|
||||||
|
data: counts
|
||||||
|
}],
|
||||||
|
tooltip: {
|
||||||
|
theme: 'dark'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
padding: {
|
||||||
|
top: -20,
|
||||||
|
right: 0,
|
||||||
|
left: -4,
|
||||||
|
bottom: -4
|
||||||
|
},
|
||||||
|
strokeDashArray: 4,
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
labels: {
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
axisBorder: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: 'category',
|
||||||
|
categories: dates,
|
||||||
|
labels: {
|
||||||
|
formatter: function (value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
labels: {
|
||||||
|
padding: 4
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labels: dates,
|
||||||
|
colors: [tabler.getColor("primary")],
|
||||||
|
legend: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
|
||||||
|
window.ApexCharts && (new ApexCharts(document.getElementById('top-registrars'), {
|
||||||
|
chart: {
|
||||||
|
type: "donut",
|
||||||
|
fontFamily: 'inherit',
|
||||||
|
height: 278,
|
||||||
|
sparkline: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
animations: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
series: series,
|
||||||
|
labels: labels,
|
||||||
|
tooltip: {
|
||||||
|
theme: 'dark'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
strokeDashArray: 4,
|
||||||
|
},
|
||||||
|
colors: [tabler.getColor("primary"), tabler.getColor("primary", 0.8), tabler.getColor("primary", 0.6), tabler.getColor("gray-300")],
|
||||||
|
legend: {
|
||||||
|
show: true,
|
||||||
|
position: 'bottom',
|
||||||
|
offsetY: 12,
|
||||||
|
markers: {
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
radius: 100,
|
||||||
|
},
|
||||||
|
itemMargin: {
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 8
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
fillSeriesColor: false
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
|
||||||
|
window.ApexCharts && (new ApexCharts(document.getElementById('support-tickets'), {
|
||||||
|
chart: {
|
||||||
|
type: "bar",
|
||||||
|
fontFamily: 'inherit',
|
||||||
|
height: 240,
|
||||||
|
parentHeightOffset: 0,
|
||||||
|
toolbar: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
animations: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
stacked: true,
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
bar: {
|
||||||
|
columnWidth: '50%',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: "Answered",
|
||||||
|
data: answeredData
|
||||||
|
},{
|
||||||
|
name: "Pending",
|
||||||
|
data: unansweredData
|
||||||
|
}],
|
||||||
|
tooltip: {
|
||||||
|
theme: 'dark'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
padding: {
|
||||||
|
top: -20,
|
||||||
|
right: 0,
|
||||||
|
left: -4,
|
||||||
|
bottom: -4
|
||||||
|
},
|
||||||
|
strokeDashArray: 4,
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
labels: {
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
axisBorder: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: 'category',
|
||||||
|
categories: labels3,
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
labels: {
|
||||||
|
padding: 4
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colors: [tabler.getColor("primary"), tabler.getColor("red")],
|
||||||
|
legend: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -260,7 +260,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- Libs JS -->
|
<!-- Libs JS -->
|
||||||
{% if route_is('dashboard') %}
|
{% if route_is('dashboard') %}
|
||||||
{% include 'partials/js-dash.twig' %}
|
{% include 'partials/js-home.twig' %}
|
||||||
{% elseif route_is('domains') %}
|
{% elseif route_is('domains') %}
|
||||||
{% include 'partials/js-domains.twig' %}
|
{% include 'partials/js-domains.twig' %}
|
||||||
{% elseif route_is('applications') %}
|
{% elseif route_is('applications') %}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<script src="/assets/js/tabler.min.js" defer></script>
|
|
2
cp/resources/views/partials/js-home.twig
Normal file
2
cp/resources/views/partials/js-home.twig
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<script src="/assets/libs/apexcharts/dist/apexcharts.min.js" defer></script>
|
||||||
|
<script src="/assets/js/tabler.min.js" defer></script>
|
Loading…
Add table
Add a link
Reference in a new issue