Abmacode12's picture
<!doctype html>
460f6aa verified
// Main JavaScript for CodeCanvas
// Initialize tooltips for icons
function initTooltips() {
const tooltipElements = document.querySelectorAll('[data-tooltip]');
tooltipElements.forEach(element => {
element.addEventListener('mouseenter', (e) => {
const tooltipText = element.getAttribute('data-tooltip');
const tooltip = document.createElement('div');
tooltip.className = 'fixed z-50 px-3 py-2 text-sm bg-gray-900 text-white rounded-lg shadow-lg border border-gray-700 pointer-events-none';
tooltip.textContent = tooltipText;
document.body.appendChild(tooltip);
const rect = element.getBoundingClientRect();
tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`;
element._tooltip = tooltip;
});
element.addEventListener('mouseleave', (e) => {
if (element._tooltip) {
element._tooltip.remove();
delete element._tooltip;
}
});
});
}
// Dark/Light mode toggle
function initThemeToggle() {
const themeToggle = document.querySelector('[data-theme-toggle]');
if (!themeToggle) return;
themeToggle.addEventListener('click', () => {
const html = document.documentElement;
const isDark = html.classList.contains('dark');
if (isDark) {
html.classList.remove('dark');
localStorage.setItem('theme', 'light');
} else {
html.classList.add('dark');
localStorage.setItem('theme', 'dark');
}
// Update icon
const icon = themeToggle.querySelector('i[data-feather]');
if (icon) {
const newIcon = isDark ? 'sun' : 'moon';
icon.setAttribute('data-feather', newIcon);
feather.replace();
}
});
}
// Project statistics from GitHub API
async function loadGitHubStats() {
try {
const response = await fetch('https://api.github.com/repos/tailwindlabs/tailwindcss');
const data = await response.json();
const statsElement = document.querySelector('[data-github-stats]');
if (statsElement) {
statsElement.innerHTML = `
<div class="grid grid-cols-3 gap-4">
<div class="text-center">
<div class="text-2xl font-bold text-rose-400">${(data.stargazers_count / 1000).toFixed(1)}k</div>
<div class="text-gray-400 text-sm">Stars</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-rose-400">${data.forks_count}</div>
<div class="text-gray-400 text-sm">Forks</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-rose-400">${(data.watchers_count / 1000).toFixed(1)}k</div>
<div class="text-gray-400 text-sm">Watchers</div>
</div>
</div>
`;
}
} catch (error) {
console.log('GitHub stats loading failed, using fallback');
}
}
// Code execution simulation
function initCodeRunner() {
const runButtons = document.querySelectorAll('[data-run-code]');
runButtons.forEach(button => {
button.addEventListener('click', async () => {
const originalText = button.textContent;
button.disabled = true;
button.innerHTML = '<div class="spinner w-5 h-5 border-2 border-rose-400 border-t-transparent rounded-full animate-spin"></div>';
// Simulate code execution
await new Promise(resolve => setTimeout(resolve, 1500));
button.disabled = false;
button.textContent = originalText;
// Show success message
const notification = document.createElement('div');
notification.className = 'fixed bottom-4 right-4 bg-gradient-to-r from-rose-500 to-pink-500 text-white px-6 py-3 rounded-xl shadow-lg transform transition-all duration-300 translate-y-0 opacity-100';
notification.textContent = 'Code executed successfully!';
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.add('translate-y-8', 'opacity-0');
setTimeout(() => notification.remove(), 300);
}, 3000);
});
});
}
// Search functionality
function initSearch() {
const searchInput = document.querySelector('[data-search-input]');
const searchResults = document.querySelector('[data-search-results]');
if (!searchInput || !searchResults) return;
let searchTimeout;
searchInput.addEventListener('input', (e) => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const query = e.target.value.trim();
if (query.length < 2) {
searchResults.classList.add('hidden');
return;
}
// Simulate search results
const results = [
{ type: 'file', name: 'main.js', path: '/src/main.js' },
{ type: 'component', name: 'Navbar', path: '/components/Navbar.js' },
{ type: 'style', name: 'global.css', path: '/styles/global.css' },
{ type: 'page', name: 'Dashboard', path: '/pages/dashboard.js' }
];
searchResults.innerHTML = results.map(result => `
<div class="p-3 hover:bg-gray-800/50 rounded-lg cursor-pointer border-b border-gray-700/50 last:border-0">
<div class="flex items-center gap-3">
<i data-feather="${result.type === 'file' ? 'file' : result.type === 'component' ? 'box' : 'layout'}" class="w-4 h-4 text-rose-400"></i>
<div>
<div class="font-medium text-white">${result.name}</div>
<div class="text-gray-400 text-sm">${result.path}</div>
</div>
</div>
</div>
`).join('');
searchResults.classList.remove('hidden');
feather.replace();
}, 300);
});
// Close search when clicking outside
document.addEventListener('click', (e) => {
if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
searchResults.classList.add('hidden');
}
});
}
// Initialize everything when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
// Initialize all features
initTooltips();
initThemeToggle();
initCodeRunner();
initSearch();
// Load GitHub stats
loadGitHubStats();
// Update feather icons
feather.replace();
// Add keyboard shortcuts
document.addEventListener('keydown', (e) => {
// Ctrl/Cmd + K for search
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
const searchInput = document.querySelector('[data-search-input]');
if (searchInput) {
searchInput.focus();
}
}
// Ctrl/Cmd + / for help
if ((e.ctrlKey || e.metaKey) && e.key === '/') {
e.preventDefault();
alert('Available shortcuts:\n\nCtrl/Cmd + K: Search\nCtrl/Cmd + /: This help\nCtrl/Cmd + S: Save\nCtrl/Cmd + E: New file');
}
});
console.log('CodeCanvas initialized successfully! 🎨');
});
// Export functions for component usage
window.CodeCanvas = {
initTooltips,
initThemeToggle,
loadGitHubStats,
initCodeRunner,
initSearch
};