|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| |
| document.documentElement.classList.add('dark'); |
|
|
| |
| const monthlyBtn = document.querySelector('.pricing-toggle button:first-child'); |
| const annualBtn = document.querySelector('.pricing-toggle button:last-child'); |
| |
| if (monthlyBtn && annualBtn) { |
| monthlyBtn.addEventListener('click', () => { |
| monthlyBtn.classList.add('bg-primary', 'text-background-dark'); |
| monthlyBtn.classList.remove('text-text-light/70'); |
| annualBtn.classList.remove('bg-primary', 'text-background-dark'); |
| annualBtn.classList.add('text-text-light/70'); |
| |
| }); |
|
|
| annualBtn.addEventListener('click', () => { |
| annualBtn.classList.add('bg-primary', 'text-background-dark'); |
| annualBtn.classList.remove('text-text-light/70'); |
| monthlyBtn.classList.remove('bg-primary', 'text-background-dark'); |
| monthlyBtn.classList.add('text-text-light/70'); |
| |
| }); |
| } |
|
|
| |
| const navLinks = document.querySelectorAll('header a'); |
| navLinks.forEach(link => { |
| link.addEventListener('click', () => { |
| navLinks.forEach(l => l.classList.remove('text-text-light')); |
| link.classList.add('text-text-light'); |
| }); |
| }); |
| |
| document.getElementById('supabaseConnect').addEventListener('click', async () => { |
| const url = document.getElementById('supabaseUrl').value; |
| const key = document.getElementById('supabaseKey').value; |
| |
| if (!url || !key) { |
| alert('Please enter both Supabase URL and API Key'); |
| return; |
| } |
|
|
| try { |
| supabase = createClient(url, key); |
| |
| |
| const { data, error } = await supabase.from('profiles').select('*').limit(1); |
| |
| if (error) throw error; |
| |
| |
| document.getElementById('supabaseConnect').classList.add('hidden'); |
| document.getElementById('supabaseStatus').classList.remove('hidden'); |
| |
| |
| if (localStorage.getItem('githubToken')) { |
| document.getElementById('configPanel').classList.remove('hidden'); |
| loadRepositories(); |
| } |
| } catch (error) { |
| alert('Supabase connection failed: ' + error.message); |
| } |
| }); |
| |
| document.getElementById('repoSelect').addEventListener('change', (e) => { |
| if (e.target.value) { |
| simulateLoadBranches(e.target.value); |
| } |
| }); |
| |
| const dropZone = document.getElementById('dropZone'); |
| const fileInput = document.getElementById('fileInput'); |
| const fileList = document.getElementById('fileList'); |
| const fileItems = document.getElementById('fileItems'); |
| let uploadedFiles = []; |
|
|
| |
| dropZone.addEventListener('click', () => fileInput.click()); |
| |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| dropZone.addEventListener(eventName, preventDefaults, false); |
| }); |
|
|
| function preventDefaults(e) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
|
|
| ['dragenter', 'dragover'].forEach(eventName => { |
| dropZone.addEventListener(eventName, highlight, false); |
| }); |
|
|
| ['dragleave', 'drop'].forEach(eventName => { |
| dropZone.addEventListener(eventName, unhighlight, false); |
| }); |
|
|
| function highlight() { |
| dropZone.classList.add('border-indigo-500', 'bg-indigo-50'); |
| } |
|
|
| function unhighlight() { |
| dropZone.classList.remove('border-indigo-500', 'bg-indigo-50'); |
| } |
|
|
| dropZone.addEventListener('drop', handleDrop, false); |
| fileInput.addEventListener('change', handleFiles, false); |
|
|
| function handleDrop(e) { |
| const dt = e.dataTransfer; |
| const files = dt.files; |
| handleFiles({ target: { files } }); |
| } |
|
|
| function handleFiles(e) { |
| const files = e.target.files; |
| const allowedTypes = ['.js', '.ts', '.jsx', '.tsx', '.sql', '.json']; |
| |
| Array.from(files).forEach(file => { |
| const ext = '.' + file.name.split('.').pop().toLowerCase(); |
| if (!allowedTypes.includes(ext)) { |
| alert(`File type ${ext} is not allowed`); |
| return; |
| } |
| |
| uploadedFiles.push(file); |
| updateFileList(); |
| }); |
| } |
|
|
| function updateFileList() { |
| if (uploadedFiles.length === 0) { |
| fileList.classList.add('hidden'); |
| return; |
| } |
| |
| fileItems.innerHTML = ''; |
| uploadedFiles.forEach((file, index) => { |
| const li = document.createElement('li'); |
| li.className = 'flex items-center justify-between py-1'; |
| li.innerHTML = ` |
| <span>${file.name} (${(file.size / 1024).toFixed(2)} KB)</span> |
| <button data-index="${index}" class="text-red-500 hover:text-red-700"> |
| <i data-feather="trash-2" class="w-4 h-4"></i> |
| </button> |
| `; |
| fileItems.appendChild(li); |
| }); |
| |
| fileList.classList.remove('hidden'); |
| feather.replace(); |
| |
| |
| document.querySelectorAll('#fileItems button').forEach(btn => { |
| btn.addEventListener('click', (e) => { |
| const index = e.target.closest('button').dataset.index; |
| uploadedFiles.splice(index, 1); |
| updateFileList(); |
| }); |
| }); |
| } |
|
|
| |
| document.getElementById('saveConfig').addEventListener('click', () => { |
| const repo = document.getElementById('repoSelect').value; |
| const branch = document.getElementById('branchSelect').value; |
| const hookUrl = document.getElementById('hookUrl').value; |
| |
| if (repo && branch && hookUrl) { |
| if (uploadedFiles.length > 0) { |
| |
| const formData = new FormData(); |
| uploadedFiles.forEach(file => { |
| formData.append('files', file); |
| }); |
| formData.append('repo', repo); |
| formData.append('branch', branch); |
| formData.append('hookUrl', hookUrl); |
| |
| |
| alert('Configuration and files saved successfully!'); |
| } else { |
| alert('Configuration saved successfully!'); |
| } |
| } else { |
| alert('Please complete all configuration fields'); |
| } |
| }); |
| }); |
| async function loadRepositories() { |
| try { |
| const response = await fetch('https://api.github.com/user/repos', { |
| headers: { |
| 'Authorization': `token ${localStorage.getItem('githubToken')}` |
| } |
| }); |
| |
| if (!response.ok) throw new Error('Failed to fetch repositories'); |
| |
| const repos = await response.json(); |
| const select = document.getElementById('repoSelect'); |
| |
| select.innerHTML = '<option value="">Select a repository</option>'; |
| repos.forEach(repo => { |
| const option = document.createElement('option'); |
| option.value = repo.full_name; |
| option.textContent = repo.name; |
| select.appendChild(option); |
| }); |
| |
| select.disabled = false; |
| } catch (error) { |
| alert('Error loading repositories: ' + error.message); |
| } |
| } |
| |
| if (window.location.pathname === '/auth/github/callback') { |
| const code = new URLSearchParams(window.location.search).get('code'); |
| |
| if (code) { |
| |
| |
| const clientId = 'YOUR_GITHUB_CLIENT_ID'; |
| const clientSecret = 'YOUR_GITHUB_CLIENT_SECRET'; |
| |
| fetch('https://github.com/login/oauth/access_token', { |
| method: 'POST', |
| headers: { |
| 'Accept': 'application/json', |
| 'Content-Type': 'application/json' |
| }, |
| body: JSON.stringify({ |
| client_id: clientId, |
| client_secret: clientSecret, |
| code: code |
| }) |
| }) |
| .then(response => response.json()) |
| .then(data => { |
| if (data.access_token) { |
| localStorage.setItem('githubToken', data.access_token); |
| window.location.href = '/'; |
| } else { |
| throw new Error(data.error_description || 'Failed to get access token'); |
| } |
| }) |
| .catch(error => { |
| console.error('GitHub auth failed:', error); |
| alert('GitHub authentication failed: ' + error.message); |
| }); |
| } |
| } |
| |
| async function simulateLoadBranches(repo) { |
| try { |
| const response = await fetch(`https://api.github.com/repos/${repo}/branches`, { |
| headers: { |
| 'Authorization': `token ${localStorage.getItem('githubToken')}` |
| } |
| }); |
| |
| if (!response.ok) throw new Error('Failed to fetch branches'); |
| |
| const branches = await response.json(); |
| const select = document.getElementById('branchSelect'); |
| |
| select.innerHTML = '<option value="">Select a branch</option>'; |
| branches.forEach(branch => { |
| const option = document.createElement('option'); |
| option.value = branch.name; |
| option.textContent = branch.name; |
| select.appendChild(option); |
| }); |
| |
| select.disabled = false; |
| } catch (error) { |
| alert('Error loading branches: ' + error.message); |
| } |
| } |
|
|
| function checkConnectionStatus() { |
| const githubConnected = !document.getElementById('github |
| |