Spaces:
Running
Running
File size: 6,305 Bytes
da4e478 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
// Main JavaScript for NotteClone Pro
// Theme Toggle functionality
class ThemeManager {
constructor() {
this.theme = localStorage.getItem('theme') || 'dark';
this.init();
}
init() {
// Set initial theme
this.setTheme(this.theme);
// Listen for system theme changes
if (window.matchMedia) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
if (!localStorage.getItem('theme')) {
this.setTheme(e.matches ? 'dark' : 'light');
}
});
}
}
setTheme(theme) {
this.theme = theme;
document.documentElement.className = theme;
localStorage.setItem('theme', theme);
}
toggleTheme() {
this.setTheme(this.theme === 'dark' ? 'light' : 'dark');
}
}
// Initialize theme manager
const themeManager = new ThemeManager();
// API Integration for testimonials (using a placeholder API)
async function fetchTestimonials() {
try {
// Using JSONPlaceholder for demo data
const response = await fetch('https://jsonplaceholder.typicode.com/comments?_limit=3');
const comments = await response.json();
// Transform API data to testimonial format
const testimonials = comments.map(comment => ({
name: comment.name.split(' ')[0] + ' ' + comment.name.split(' ')[1],
role: 'NotteClone User',
content: comment.body.length > 120 ? comment.body.substring(0, 120) + '...' : comment.body,
rating: Math.floor(Math.random() * 3) + 3 // 3-5 stars
}));
return testimonials;
} catch (error) {
console.error('Error fetching testimonials:', error);
return getFallbackTestimonials();
}
}
function getFallbackTestimonials() {
return [
{
name: "Alex Johnson",
role: "Product Designer",
content: "NotteClone Pro has completely transformed how I organize my design notes. The dark mode is perfect for late-night brainstorming sessions.",
rating: 5
},
{
name: "Sam Rivera",
role: "Software Engineer",
content: "As a developer who spends hours in dark-themed IDEs, having a note-taking app that matches my workflow is a game-changer.",
rating: 5
},
{
name: "Taylor Morgan",
role: "Content Creator",
content: "The organization features are incredible. I can finally keep all my ideas sorted without switching between multiple apps.",
rating: 4
}
];
}
// Initialize testimonials when DOM is loaded
document.addEventListener('DOMContentLoaded', async function() {
// Load testimonials if section exists
const testimonialsSection = document.getElementById('testimonials');
if (testimonialsSection) {
const testimonials = await fetchTestimonials();
renderTestimonials(testimonials);
}
// Add scroll animations
setupScrollAnimations();
// Initialize tooltips if needed
initTooltips();
});
function renderTestimonials(testimonials) {
const container = document.querySelector('#testimonials .testimonials-container');
if (!container) return;
container.innerHTML = testimonials.map((testimonial, index) => `
<div class="testimonial-card bg-gray-800/50 border border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:border-primary-500 hover:shadow-lg" style="animation-delay: ${index * 100}ms">
<div class="flex items-center mb-4">
${'<i data-feather="star" class="w-4 h-4 text-amber-500 fill-amber-500"></i>'.repeat(testimonial.rating)}
${'<i data-feather="star" class="w-4 h-4 text-gray-600"></i>'.repeat(5 - testimonial.rating)}
</div>
<p class="text-gray-300 mb-6 italic">"${testimonial.content}"</p>
<div class="flex items-center">
<div class="w-12 h-12 rounded-full bg-gradient-to-r from-primary-500 to-secondary-500 flex items-center justify-center mr-4">
<span class="font-bold text-white">${testimonial.name.charAt(0)}</span>
</div>
<div>
<h4 class="font-bold">${testimonial.name}</h4>
<p class="text-gray-400 text-sm">${testimonial.role}</p>
</div>
</div>
</div>
`).join('');
feather.replace();
}
function setupScrollAnimations() {
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-slide-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Observe all elements with the data-animate attribute
document.querySelectorAll('[data-animate]').forEach(el => {
observer.observe(el);
});
}
function initTooltips() {
// Initialize tooltips for feature icons
const tooltipElements = document.querySelectorAll('[data-tooltip]');
tooltipElements.forEach(el => {
el.addEventListener('mouseenter', function(e) {
const tooltipText = this.getAttribute('data-tooltip');
const tooltip = document.createElement('div');
tooltip.className = 'tooltip absolute z-50 px-3 py-2 bg-gray-800 text-white text-sm rounded-lg shadow-xl border border-gray-700';
tooltip.textContent = tooltipText;
tooltip.style.top = (e.clientY - 40) + 'px';
tooltip.style.left = (e.clientX - 60) + 'px';
document.body.appendChild(tooltip);
this._tooltip = tooltip;
});
el.addEventListener('mouseleave', function() {
if (this._tooltip) {
this._tooltip.remove();
}
});
});
}
// Export for module usage if needed
if (typeof module !== 'undefined' && module.exports) {
module.exports = { ThemeManager, fetchTestimonials };
} |