/** * Client-Side JavaScript for the International Umbrella Endowment * * Handles all user interactions: * - Opening the submission modal via a floating button. * - Submitting a new deal and auto-populating the lookup field. * - Looking up a deal's status and displaying it in a modal. * - Admin actions for approving/declining deals. * * Final Version: Monday, June 16, 2025 */ document.addEventListener('DOMContentLoaded', () => { // --- CONFIGURATION --- const workerUrl = 'https://form-handler-worker.aiagents.workers.dev/'; // Ensure this is your correct worker URL // --- ELEMENT SELECTIONS --- // Forms const submissionForm = document.getElementById('vessel-exchange-form'); const lookupForm = document.getElementById('deal-lookup-form'); const adminForm = document.getElementById('admin-action-form'); // Buttons const showSubmissionButton = document.getElementById('show-submission-button'); const submitButton = document.getElementById('submit-button'); const adminApproveButton = document.getElementById('admin-approve-button'); const adminDeclineButton = document.getElementById('admin-decline-button'); const submissionModalCloseButton = document.getElementById('submission-modal-close-button'); const dealModalCloseButton = document.getElementById('modal-close-button'); // Modals & Containers const submissionModal = document.getElementById('submission-modal'); const dealModal = document.getElementById('deal-modal'); const lookupContainer = document.getElementById('lookup-container'); const lookupInput = document.getElementById('lookup-deal-id'); // Status Message Areas const submissionStatus = document.getElementById('status-message'); const adminStatus = document.getElementById('admin-status-message'); // --- EVENT LISTENERS --- // Floating button to show the submission form modal if (showSubmissionButton) { showSubmissionButton.addEventListener('click', () => { submissionModal.classList.remove('hidden'); }); } // Close the submission form modal if (submissionModal) { submissionModalCloseButton.addEventListener('click', () => closeModal(submissionModal)); submissionModal.addEventListener('click', (event) => { if (event.target === submissionModal) closeModal(submissionModal); }); } // Close the deal info modal if (dealModal) { dealModalCloseButton.addEventListener('click', () => closeModal(dealModal)); dealModal.addEventListener('click', (event) => { if (event.target === dealModal) closeModal(dealModal); }); } // Handle New Deal Submissions if (submissionForm) { submissionForm.addEventListener('submit', handleFormSubmit); } // Handle Deal Status Lookups if (lookupForm) { lookupForm.addEventListener('submit', handleLookupSubmit); } // Handle Admin Actions if (adminForm) { adminApproveButton.addEventListener('click', () => handleAdminClick('approve')); adminDeclineButton.addEventListener('click', () => handleAdminClick('decline')); } // --- HANDLER FUNCTIONS --- /** * Handles the main form submission to create a new deal. */ async function handleFormSubmit(event) { event.preventDefault(); // Stop page reload showStatus(submissionStatus, 'Submitting...'); submitButton.disabled = true; try { const formData = new FormData(submissionForm); const response = await fetch(workerUrl, { method: 'POST', body: formData }); const resultText = await response.text(); if (!response.ok) { throw new Error(resultText); // Use the error text from the worker } const result = JSON.parse(resultText); const dealId = result.deal_id; // --- Auto-populate and Highlight Logic --- showSuccess(submissionStatus, `Success! Deal ID copied below.`); lookupInput.value = dealId; // Auto-populate the lookup field lookupContainer.classList.add('highlight'); setTimeout(() => { lookupContainer.classList.remove('highlight'); }, 2000); submissionForm.reset(); // Close the modal after a delay setTimeout(() => closeModal(submissionModal), 2500); } catch (error) { showError(submissionStatus, error.message); } finally { submitButton.disabled = false; } } /** * Handles the lookup form submission to check a deal's status. */ async function handleLookupSubmit(event) { event.preventDefault(); if (!lookupInput.value) return; try { const response = await fetch(`${workerUrl}?deal_id=${lookupInput.value}`, { method: 'GET' }); const result = await response.json(); if (!response.ok) throw new Error(result.error || 'Failed to fetch deal.'); openDealInfoModal(result); } catch (error) { alert(`Error: ${error.message}`); } } /** * Handles clicks on the admin approve/decline buttons. */ async function handleAdminClick(action) { const dealId = document.getElementById('admin-deal-id').value; if (!dealId) { showError(adminStatus, 'Please enter a Deal ID.'); return; } showStatus(adminStatus, 'Processing action...'); const formData = new FormData(); formData.append('action', action); formData.append('deal_id', dealId); try { const response = await fetch(workerUrl, { method: 'POST', body: formData }); const result = await response.json(); if (!response.ok) throw new Error(result.error || `Server responded with status ${response.status}`); showSuccess(adminStatus, result.message); } catch (error) { showError(adminStatus, error.message); } } // --- UI HELPER FUNCTIONS --- /** * Populates and opens the deal information modal. */ function openDealInfoModal(dealData) { document.getElementById('modal-deal-id').textContent = dealData.deal_id; document.getElementById('modal-owner-name').textContent = dealData.owner_name; document.getElementById('modal-contact-email').textContent = dealData.contact_email; document.getElementById('modal-contact-phone').textContent = dealData.contact_phone || 'N/A'; document.getElementById('modal-year-built').textContent = dealData.year_built || 'N/A'; document.getElementById('modal-gross-tonnage').textContent = dealData.gross_tonnage || 'N/A'; document.getElementById('modal-token-amount').textContent = dealData.token_amount; document.getElementById('modal-vessel-description').textContent = dealData.vessel_description || 'No description provided.'; const statusBadge = document.getElementById('modal-status-badge'); statusBadge.textContent = dealData.status; statusBadge.className = `badge ${dealData.status}`; dealModal.classList.remove('hidden'); } /** * Hides a modal element. */ function closeModal(modalElement) { modalElement.classList.add('hidden'); } /** * Displays a generic status message. */ function showStatus(element, message) { element.className = 'status'; element.innerHTML = message; element.style.display = 'block'; } /** * Displays a success message. */ function showSuccess(element, message) { element.className = 'status success'; element.innerHTML = `${message}`; element.style.display = 'block'; } /** * Displays an error message. */ function showError(element, message) { element.className = 'status error'; element.innerHTML = `Error: ${message}`; element.style.display = 'block'; } });