280 lines
9.7 KiB
JavaScript
280 lines
9.7 KiB
JavaScript
import { driver } from 'driver.js';
|
|
import 'driver.js/dist/driver.css';
|
|
import { adminTours } from './tours/admin-tours.js';
|
|
import { userTours } from './tours/user-tours.js';
|
|
|
|
// Detect current panel and page
|
|
function getCurrentPage() {
|
|
const path = window.location.pathname;
|
|
const isAdmin = path.includes('/jabali-admin');
|
|
const isUser = path.includes('/jabali/');
|
|
|
|
let page = 'dashboard';
|
|
|
|
if (path.includes('/users')) page = 'users';
|
|
else if (path.includes('/server-status')) page = 'serverStatus';
|
|
else if (path.includes('/ssl-manager')) page = 'sslManager';
|
|
else if (path.includes('/server-settings')) page = 'serverSettings';
|
|
else if (path.includes('/email-settings')) page = 'emailSettings';
|
|
else if (path.includes('/dns-zones')) page = 'dnsZones';
|
|
else if (path.includes('/security')) page = 'security';
|
|
else if (path.includes('/services')) page = 'services';
|
|
else if (path.includes('/backups')) page = 'backups';
|
|
else if (path.includes('/audit-logs')) page = 'auditLogs';
|
|
else if (path.includes('/domains')) page = 'domains';
|
|
else if (path.includes('/email')) page = 'email';
|
|
else if (path.includes('/databases')) page = 'databases';
|
|
else if (path.includes('/files')) page = 'files';
|
|
else if (path.includes('/ssl')) page = 'ssl';
|
|
else if (path.includes('/dns-records')) page = 'dnsRecords';
|
|
else if (path.includes('/cron')) page = 'cronJobs';
|
|
else if (path.includes('/php')) page = 'phpSettings';
|
|
else if (path.includes('/ssh')) page = 'sshKeys';
|
|
else if (path.includes('/wordpress')) page = 'wordpress';
|
|
|
|
return { isAdmin, isUser, page };
|
|
}
|
|
|
|
// Setup sidebar data-tour attributes
|
|
function setupSidebarTourAttributes() {
|
|
const sidebarItems = document.querySelectorAll('.fi-sidebar-item');
|
|
const tourMappings = {
|
|
'/users': 'users',
|
|
'/server-status': 'server-status',
|
|
'/ssl-manager': 'ssl-manager',
|
|
'/server-settings': 'server-settings',
|
|
'/email-settings': 'email-settings',
|
|
'/dns-zones': 'dns-zones',
|
|
'/security': 'security',
|
|
'/services': 'services',
|
|
'/backups': 'backups',
|
|
'/audit-logs': 'audit-logs',
|
|
'/domains': 'domains',
|
|
'/email': 'email',
|
|
'/databases': 'databases',
|
|
'/files': 'files',
|
|
'/ssl': 'ssl',
|
|
'/dns-records': 'dns-records',
|
|
'/cron': 'cron-jobs',
|
|
'/php': 'php-settings',
|
|
'/ssh': 'ssh-keys',
|
|
'/wordpress': 'wordpress'
|
|
};
|
|
|
|
sidebarItems.forEach(item => {
|
|
const link = item.querySelector('a');
|
|
if (link) {
|
|
const href = link.getAttribute('href') || '';
|
|
for (const [pattern, tourId] of Object.entries(tourMappings)) {
|
|
if (href.includes(pattern)) {
|
|
item.setAttribute('data-tour', tourId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Get tour configuration for current page
|
|
function getTourConfig(page, isAdmin) {
|
|
const tours = isAdmin ? adminTours : userTours;
|
|
return tours[page] || tours.dashboard;
|
|
}
|
|
|
|
// Filter steps to only include existing elements
|
|
function filterSteps(steps) {
|
|
return steps.filter(step => {
|
|
if (!step.element) return true; // Non-element steps always included
|
|
const el = document.querySelector(step.element);
|
|
return el !== null;
|
|
});
|
|
}
|
|
|
|
// Start tour for current page
|
|
function startPageTour(pageTour = null) {
|
|
const t = window.jabaliTourTranslations || {};
|
|
const { isAdmin, page } = getCurrentPage();
|
|
|
|
setupSidebarTourAttributes();
|
|
|
|
const tourConfig = pageTour ? { steps: () => pageTour } : getTourConfig(page, isAdmin);
|
|
|
|
if (!tourConfig) {
|
|
console.warn('No tour configuration found for page:', page);
|
|
return;
|
|
}
|
|
|
|
let steps = tourConfig.steps(t);
|
|
steps = filterSteps(steps);
|
|
|
|
if (steps.length === 0) {
|
|
console.warn('No valid steps for tour');
|
|
return;
|
|
}
|
|
|
|
const driverObj = driver({
|
|
showProgress: true,
|
|
animate: true,
|
|
smoothScroll: true,
|
|
allowClose: true,
|
|
overlayOpacity: 0.6,
|
|
stagePadding: 8,
|
|
nextBtnText: t.next || 'Next',
|
|
prevBtnText: t.prev || 'Previous',
|
|
doneBtnText: t.done || 'Done',
|
|
steps: steps,
|
|
onDestroyStarted: () => {
|
|
markTourCompleted();
|
|
driverObj.destroy();
|
|
}
|
|
});
|
|
|
|
driverObj.drive();
|
|
}
|
|
|
|
// Start main panel tour (dashboard overview)
|
|
function startAdminTour() {
|
|
const t = window.jabaliTourTranslations || {};
|
|
const { isAdmin } = getCurrentPage();
|
|
|
|
setupSidebarTourAttributes();
|
|
|
|
// Build comprehensive panel tour
|
|
const steps = [];
|
|
|
|
// Welcome
|
|
steps.push({
|
|
popover: {
|
|
title: t.welcome || 'Welcome to Jabali!',
|
|
description: t.welcomeDesc || "Let's take a quick tour of your control panel."
|
|
}
|
|
});
|
|
|
|
// Sidebar
|
|
const sidebar = document.querySelector('.fi-sidebar-nav');
|
|
if (sidebar) {
|
|
steps.push({
|
|
element: '.fi-sidebar-nav',
|
|
popover: {
|
|
title: t.navigation || 'Navigation Menu',
|
|
description: t.navigationDesc || 'Access all panel sections from the sidebar.',
|
|
side: 'right',
|
|
align: 'start'
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add sidebar items based on what's available
|
|
const sidebarSteps = isAdmin ? [
|
|
{ tour: 'users', title: t.users || 'Users Management', desc: t.usersDesc || 'Create and manage hosting accounts.' },
|
|
{ tour: 'server-status', title: t.serverStatus || 'Server Status', desc: t.serverStatusDesc || 'Monitor server health and services.' },
|
|
{ tour: 'ssl-manager', title: t.sslManager || 'SSL Manager', desc: t.sslManagerDesc || 'Manage SSL certificates.' },
|
|
{ tour: 'server-settings', title: t.serverSettings || 'Server Settings', desc: t.serverSettingsDesc || 'Configure panel and server options.' },
|
|
{ tour: 'email-settings', title: t.emailSettings || 'Email Settings', desc: t.emailSettingsDesc || 'Configure mail server.' },
|
|
{ tour: 'dns-zones', title: t.dnsZones || 'DNS Zones', desc: t.dnsZonesDesc || 'Manage DNS zones.' },
|
|
{ tour: 'services', title: t.services || 'Services', desc: t.servicesDesc || 'Manage server services.' },
|
|
{ tour: 'backups', title: t.backups || 'Backups', desc: t.backupsDesc || 'Configure backups.' },
|
|
{ tour: 'security', title: t.security || 'Security', desc: t.securityDesc || 'Firewall, Fail2ban, antivirus, and SSH settings.' },
|
|
{ tour: 'audit-logs', title: t.auditLogs || 'Audit Logs', desc: t.auditLogsDesc || 'Track panel activities.' }
|
|
] : [
|
|
{ tour: 'domains', title: t.domains || 'Domains', desc: t.domainsDesc || 'Manage your websites.' },
|
|
{ tour: 'email', title: t.email || 'Email', desc: t.emailDesc || 'Manage email accounts.' },
|
|
{ tour: 'databases', title: t.databases || 'Databases', desc: t.databasesDesc || 'Manage MySQL databases.' },
|
|
{ tour: 'files', title: t.files || 'File Manager', desc: t.filesDesc || 'Manage your files.' },
|
|
{ tour: 'ssl', title: t.ssl || 'SSL', desc: t.sslDesc || 'Manage SSL certificates.' },
|
|
{ tour: 'backups', title: t.backups || 'Backups', desc: t.backupsDesc || 'Manage backups.' }
|
|
];
|
|
|
|
sidebarSteps.forEach(item => {
|
|
const el = document.querySelector(`[data-tour="${item.tour}"]`);
|
|
if (el) {
|
|
steps.push({
|
|
element: `[data-tour="${item.tour}"]`,
|
|
popover: {
|
|
title: item.title,
|
|
description: item.desc,
|
|
side: 'right',
|
|
align: 'start'
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Top bar
|
|
const topbar = document.querySelector('.fi-topbar');
|
|
if (topbar) {
|
|
steps.push({
|
|
element: '.fi-topbar',
|
|
popover: {
|
|
title: t.topBar || 'Top Bar',
|
|
description: t.topBarDesc || 'Access profile, language, and theme settings.',
|
|
side: 'bottom',
|
|
align: 'end'
|
|
}
|
|
});
|
|
}
|
|
|
|
// Quick Actions widget
|
|
const quickActions = document.querySelector('.fi-wi');
|
|
if (quickActions) {
|
|
steps.push({
|
|
element: '.fi-wi',
|
|
popover: {
|
|
title: t.quickActions || 'Quick Actions',
|
|
description: t.quickActionsDesc || 'Quick shortcuts to common tasks.',
|
|
side: 'top',
|
|
align: 'start'
|
|
}
|
|
});
|
|
}
|
|
|
|
// Final
|
|
steps.push({
|
|
popover: {
|
|
title: t.ready || "You're Ready!",
|
|
description: t.readyDesc || 'You can retake this tour anytime from the Dashboard.'
|
|
}
|
|
});
|
|
|
|
const driverObj = driver({
|
|
showProgress: true,
|
|
animate: true,
|
|
smoothScroll: true,
|
|
allowClose: true,
|
|
overlayOpacity: 0.6,
|
|
stagePadding: 8,
|
|
nextBtnText: t.next || 'Next',
|
|
prevBtnText: t.prev || 'Previous',
|
|
doneBtnText: t.done || 'Done',
|
|
steps: steps,
|
|
onDestroyStarted: () => {
|
|
markTourCompleted();
|
|
driverObj.destroy();
|
|
}
|
|
});
|
|
|
|
driverObj.drive();
|
|
}
|
|
|
|
function markTourCompleted() {
|
|
if (window.Livewire) {
|
|
Livewire.dispatch('tour-completed');
|
|
}
|
|
localStorage.setItem('jabali_tour_completed', 'true');
|
|
}
|
|
|
|
// Listen for Livewire events
|
|
document.addEventListener('livewire:init', () => {
|
|
Livewire.on('start-admin-tour', () => {
|
|
setTimeout(() => startAdminTour(), 300);
|
|
});
|
|
|
|
Livewire.on('start-page-tour', (data) => {
|
|
setTimeout(() => startPageTour(data?.steps), 300);
|
|
});
|
|
});
|
|
|
|
// Export for manual triggering
|
|
window.startAdminTour = startAdminTour;
|
|
window.startPageTour = startPageTour;
|