No services configured. Run the installer to set up services.
`;
return;
}
// Sort all services alphabetically by display name
const sortedKeys = Object.keys(services).sort((a, b) => {
const aName = (SERVICE_METADATA[a]?.name || a).toLowerCase();
const bName = (SERVICE_METADATA[b]?.name || b).toLowerCase();
return aName.localeCompare(bName);
});
// Use DocumentFragment for better performance
const fragment = document.createDocumentFragment();
sortedKeys.forEach(key => {
fragment.appendChild(renderServiceCard(key, services[key]));
});
servicesContainer.appendChild(fragment);
}
/**
* Render quick start steps
*/
function renderQuickStart(steps) {
if (!quickstartContainer) return;
quickstartContainer.innerHTML = '';
if (!steps || steps.length === 0) {
// Default steps if none provided
steps = [
{ step: 1, title: 'Log into n8n', description: 'Use the email you provided during installation' },
{ step: 2, title: 'Create your first workflow', description: 'Start with a Manual Trigger + HTTP Request nodes' },
{ step: 3, title: 'Monitor your system', description: 'Use Grafana to track performance' }
];
}
const fragment = document.createDocumentFragment();
steps.forEach(item => {
const stepEl = document.createElement('div');
stepEl.className = 'flex items-start gap-4 p-4 bg-surface-100 rounded-xl border border-surface-400 hover:border-brand/30 hover:bg-surface-200 transition-all';
stepEl.innerHTML = `
${Icons.warning('w-12 h-12 mx-auto text-red-500 mb-4')}
Unable to load service data
Make sure the installation completed successfully and data.json was generated.
`;
}
/**
* Load data and render page
*/
async function init() {
// Inject section icons
injectSectionIcons();
// Always render commands (static content)
renderCommands();
try {
const response = await fetch('data.json');
if (!response.ok) {
throw new Error(`Failed to load data (${response.status})`);
}
const data = await response.json();
// Update domain info
if (domainInfo) {
if (data.domain) {
domainInfo.textContent = `Domain: ${data.domain}`;
}
if (data.generated_at) {
const date = new Date(data.generated_at);
domainInfo.textContent += ` | Generated: ${date.toLocaleString()}`;
}
}
// Render services
renderServices(data.services);
// Render quick start
renderQuickStart(data.quick_start);
} catch (error) {
console.error('Error loading data:', error);
// Show error in UI
renderServicesError();
// Still render default quick start
renderQuickStart(null);
}
// Initialize confetti animation on first visit
CinematicAnimations.init();
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();