summaryrefslogtreecommitdiff
path: root/static/api-docs-script.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/api-docs-script.js')
-rw-r--r--static/api-docs-script.js315
1 files changed, 315 insertions, 0 deletions
diff --git a/static/api-docs-script.js b/static/api-docs-script.js
new file mode 100644
index 0000000..2f179b9
--- /dev/null
+++ b/static/api-docs-script.js
@@ -0,0 +1,315 @@
+// Smooth scrolling for navigation links
+document.querySelectorAll('.nav-item').forEach(link => {
+ link.addEventListener('click', (e) => {
+ e.preventDefault();
+ const targetId = link.getAttribute('href').substring(1);
+ const targetElement = document.getElementById(targetId);
+
+ if (targetElement) {
+ targetElement.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ });
+
+ // Update active nav item
+ document.querySelectorAll('.nav-item').forEach(item => {
+ item.classList.remove('active');
+ });
+ link.classList.add('active');
+ }
+ });
+});
+
+// Copy to clipboard functionality
+document.querySelectorAll('.copy-btn').forEach(button => {
+ button.addEventListener('click', async () => {
+ const textToCopy = button.getAttribute('data-copy');
+
+ try {
+ await navigator.clipboard.writeText(textToCopy);
+
+ // Update button state
+ const originalText = button.textContent;
+ button.textContent = 'Copied!';
+ button.classList.add('copied');
+
+ setTimeout(() => {
+ button.textContent = originalText;
+ button.classList.remove('copied');
+ }, 2000);
+
+ showToast('Copied to clipboard!', 'success');
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
+ showToast('Failed to copy to clipboard', 'error');
+ }
+ });
+});
+
+// Toast notification
+const showToast = (message, type = 'success') => {
+ const toast = document.getElementById('toast');
+ const toastMessage = toast.querySelector('.toast-message');
+ const toastIcon = toast.querySelector('.toast-icon');
+
+ toastMessage.textContent = message;
+
+ if (type === 'success') {
+ toast.style.background = 'var(--success)';
+ toastIcon.textContent = '✓';
+ } else {
+ toast.style.background = 'var(--error)';
+ toastIcon.textContent = '✕';
+ }
+
+ toast.classList.add('show');
+
+ setTimeout(() => {
+ toast.classList.remove('show');
+ }, 3000);
+};
+
+// Intersection Observer for active navigation
+const observerOptions = {
+ threshold: 0.1,
+ rootMargin: '-100px 0px -50% 0px'
+};
+
+const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ const id = entry.target.id;
+ const navLink = document.querySelector(`.nav-item[href="#${id}"]`);
+
+ if (navLink) {
+ document.querySelectorAll('.nav-item').forEach(item => {
+ item.classList.remove('active');
+ });
+ navLink.classList.add('active');
+ }
+ }
+ });
+}, observerOptions);
+
+// Observe all sections
+document.querySelectorAll('.doc-section[id]').forEach(section => {
+ observer.observe(section);
+});
+
+// Navbar background on scroll
+window.addEventListener('scroll', () => {
+ const navbar = document.querySelector('.navbar');
+ if (window.scrollY > 50) {
+ navbar.style.background = 'rgba(255, 255, 255, 0.98)';
+ } else {
+ navbar.style.background = 'rgba(255, 255, 255, 0.95)';
+ }
+});
+
+// Button click handlers
+document.querySelectorAll('.btn').forEach(btn => {
+ btn.addEventListener('click', (e) => {
+ const buttonText = btn.textContent.toLowerCase();
+
+ if (buttonText.includes('trial') || buttonText.includes('start')) {
+ if (!btn.closest('form')) {
+ e.preventDefault();
+ showToast('Starting your free trial! Redirecting...', 'success');
+ setTimeout(() => {
+ window.location.href = 'signup.html';
+ }, 2000);
+ }
+ } else if (buttonText.includes('documentation') || buttonText.includes('github') || buttonText.includes('pypi')) {
+ e.preventDefault();
+ showToast('Opening external documentation...', 'success');
+ } else if (buttonText.includes('import collection')) {
+ e.preventDefault();
+ showToast('Postman collection downloaded!', 'success');
+ }
+ });
+});
+
+// Syntax highlighting for code blocks (basic)
+const highlightCode = () => {
+ document.querySelectorAll('pre code').forEach(block => {
+ let html = block.innerHTML;
+
+ // Highlight JSON keys
+ html = html.replace(/"([^"]+)":/g, '<span style="color: #10b981;">"$1"</span>:');
+
+ // Highlight strings
+ html = html.replace(/: "([^"]+)"/g, ': <span style="color: #f59e0b;">"$1"</span>');
+
+ // Highlight numbers
+ html = html.replace(/: (\d+\.?\d*)/g, ': <span style="color: #3b82f6;">$1</span>');
+
+ // Highlight booleans
+ html = html.replace(/: (true|false)/g, ': <span style="color: #8b5cf6;">$1</span>');
+
+ // Highlight null
+ html = html.replace(/: (null)/g, ': <span style="color: #64748b;">$1</span>');
+
+ block.innerHTML = html;
+ });
+};
+
+// Apply syntax highlighting on load
+document.addEventListener('DOMContentLoaded', highlightCode);
+
+// Search functionality (basic)
+const addSearchFunctionality = () => {
+ // Create search input
+ const searchContainer = document.createElement('div');
+ searchContainer.style.cssText = `
+ position: sticky;
+ top: 0;
+ background: var(--surface);
+ padding: 1rem 1.5rem;
+ border-bottom: 1px solid var(--border);
+ margin-bottom: 1rem;
+ `;
+
+ const searchInput = document.createElement('input');
+ searchInput.type = 'text';
+ searchInput.placeholder = 'Search documentation...';
+ searchInput.style.cssText = `
+ width: 100%;
+ padding: 0.75rem 1rem;
+ border: 1px solid var(--border);
+ border-radius: 0.5rem;
+ font-size: 0.875rem;
+ background: white;
+ `;
+
+ searchContainer.appendChild(searchInput);
+
+ // Insert search at the top of sidebar
+ const sidebarContent = document.querySelector('.sidebar-content');
+ sidebarContent.insertBefore(searchContainer, sidebarContent.firstChild);
+
+ // Search functionality
+ searchInput.addEventListener('input', (e) => {
+ const query = e.target.value.toLowerCase();
+ const navItems = document.querySelectorAll('.nav-item');
+
+ navItems.forEach(item => {
+ const text = item.textContent.toLowerCase();
+ const section = item.closest('.nav-section');
+
+ if (text.includes(query)) {
+ item.style.display = 'block';
+ section.style.display = 'block';
+ } else {
+ item.style.display = 'none';
+ }
+ });
+
+ // Hide sections with no visible items
+ document.querySelectorAll('.nav-section').forEach(section => {
+ const visibleItems = section.querySelectorAll('.nav-item[style*="block"]');
+ if (visibleItems.length === 0 && query !== '') {
+ section.style.display = 'none';
+ } else {
+ section.style.display = 'block';
+ }
+ });
+ });
+};
+
+// Add search functionality on load
+document.addEventListener('DOMContentLoaded', addSearchFunctionality);
+
+// Keyboard shortcuts
+document.addEventListener('keydown', (e) => {
+ // Ctrl/Cmd + K to focus search
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
+ e.preventDefault();
+ const searchInput = document.querySelector('input[placeholder*="Search"]');
+ if (searchInput) {
+ searchInput.focus();
+ }
+ }
+
+ // Escape to clear search
+ if (e.key === 'Escape') {
+ const searchInput = document.querySelector('input[placeholder*="Search"]');
+ if (searchInput && document.activeElement === searchInput) {
+ searchInput.value = '';
+ searchInput.dispatchEvent(new Event('input'));
+ searchInput.blur();
+ }
+ }
+});
+
+// Print styles
+const addPrintStyles = () => {
+ const printStyles = document.createElement('style');
+ printStyles.textContent = `
+ @media print {
+ .navbar,
+ .sidebar,
+ .copy-btn,
+ .toast {
+ display: none !important;
+ }
+
+ .docs-layout {
+ flex-direction: column;
+ }
+
+ .main-content {
+ width: 100% !important;
+ }
+
+ .content-container {
+ max-width: none !important;
+ padding: 0 !important;
+ }
+
+ .code-block {
+ background: #f8f9fa !important;
+ color: #333 !important;
+ border: 1px solid #ddd !important;
+ }
+
+ .endpoint {
+ break-inside: avoid;
+ }
+ }
+ `;
+ document.head.appendChild(printStyles);
+};
+
+addPrintStyles();
+
+// Initialize everything when DOM is ready
+document.addEventListener('DOMContentLoaded', () => {
+ // Set initial active nav item
+ const hash = window.location.hash;
+ if (hash) {
+ const navLink = document.querySelector(`.nav-item[href="${hash}"]`);
+ if (navLink) {
+ navLink.classList.add('active');
+ }
+ } else {
+ // Default to first nav item
+ const firstNavItem = document.querySelector('.nav-item');
+ if (firstNavItem) {
+ firstNavItem.classList.add('active');
+ }
+ }
+});
+
+// Handle hash changes
+window.addEventListener('hashchange', () => {
+ const hash = window.location.hash;
+ if (hash) {
+ const navLink = document.querySelector(`.nav-item[href="${hash}"]`);
+ if (navLink) {
+ document.querySelectorAll('.nav-item').forEach(item => {
+ item.classList.remove('active');
+ });
+ navLink.classList.add('active');
+ }
+ }
+});