feat(dashboard): Redesign and implement analytics dashboard

This commit introduces a complete overhaul of the analytics dashboard, replacing the previous simple layout with a modern, data-rich interface.

The new dashboard is built using Tailwind CSS for styling and Chart.js for interactive data visualizations. It provides a more comprehensive and user-friendly view of bot analytics with key metrics, charts for user growth and satisfaction, and a detailed feedback table.

Additionally, this commit fixes a mobile viewport height (`vh`) rendering issue on the chat page to prevent layout shifts on mobile browsers.
This commit is contained in:
2025-07-17 09:18:04 +07:00
parent 4ce725d333
commit 158b6d0886
6 changed files with 960 additions and 508 deletions

View File

@@ -1,81 +1,16 @@
console.log("Dashboard script loaded");
// Toggle dropdown menu visibility
const menuButton = document.querySelector('.mobile-header-menu-button');
const dropdownMenu = document.querySelector('.dropdown-menu');
// Inisialisasi fungsi dasar
document.addEventListener('DOMContentLoaded', () => {
const sidebar = document.querySelector('.sidebar');
const menuBtn = document.querySelector('.main-header .hamburger-btn');
const closeBtn = document.querySelector('.sidebar .hamburger-btn');
// Toggle sidebar visibility
function toggleSidebar() {
sidebar.classList.toggle('active');
document.body.classList.toggle('sidebar-active');
}
// Event listeners for hamburger buttons
if (menuBtn) {
menuBtn.addEventListener('click', toggleSidebar);
}
if (closeBtn) {
closeBtn.addEventListener('click', toggleSidebar);
}
// Close sidebar when clicking outside
document.addEventListener('click', (e) => {
if (window.innerWidth > 768) return;
if (sidebar.classList.contains('active') &&
!sidebar.contains(e.target) &&
!menuBtn.contains(e.target)) {
toggleSidebar();
}
if (menuButton && dropdownMenu) {
menuButton.addEventListener('click', function() {
dropdownMenu.classList.toggle('visible');
});
// Handle sidebar on mobile
if (window.innerWidth <= 768) {
sidebar.classList.add('collapsed');
}
// Event listener untuk tombol logout
const logoutBtn = document.querySelector('.logout-btn');
if (logoutBtn) {
logoutBtn.addEventListener('click', function(e) {
e.preventDefault();
// Simulasi logout
alert('Anda telah logout');
// Redirect ke halaman login
window.location.href = this.getAttribute('href');
});
}
// Update date and time in real-time
function updateDateTime() {
const now = new Date();
// Format date
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const dateString = now.toLocaleDateString('id-ID', options);
// Format time
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const timeString = `${hours}:${minutes}:${seconds}`;
// Update DOM
document.getElementById('date').textContent = dateString;
document.getElementById('time').textContent = timeString;
}
// Initial call
updateDateTime();
// Update every second
setInterval(updateDateTime, 1000);
});
// Fungsi untuk toggle sidebar
function toggleSidebar() {
const sidebar = document.querySelector('.sidebar');
sidebar.classList.toggle('collapsed');
}
// Close dropdown when clicking outside
document.addEventListener('click', function(event) {
if (!event.target.closest('.mobile-header-right') && dropdownMenu) {
dropdownMenu.classList.remove('visible');
}
});