97 lines
4.0 KiB
JavaScript
97 lines
4.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function () {
|
|
const offerForm = document.getElementById('offer-explorer-form');
|
|
const resultsTableBody = document.getElementById('offer-results-body');
|
|
|
|
const mockOffers = [
|
|
{ provider: 'AWS', gpu: 'H100', region: 'us-east-1', price: 2.10, spot: true },
|
|
{ provider: 'GCP', gpu: 'H100', region: 'us-central1', price: 2.25, spot: true },
|
|
{ provider: 'Azure', gpu: 'H100', region: 'eastus', price: 2.30, spot: false },
|
|
{ provider: 'CoreWeave', gpu: 'H100', region: 'us-east', price: 1.89, spot: false },
|
|
{ provider: 'RunPod', gpu: 'H100', region: 'us-east', price: 1.79, spot: true },
|
|
{ provider: 'AWS', gpu: 'A100', region: 'us-west-2', price: 1.10, spot: true },
|
|
{ provider: 'GCP', gpu: 'A100', region: 'us-east4', price: 1.20, spot: true },
|
|
{ provider: 'Vast.ai', gpu: 'A100', region: 'us-west', price: 0.95, spot: true },
|
|
{ provider: 'AWS', gpu: 'RTX 4090', region: 'eu-west-1', price: 0.70, spot: true },
|
|
{ provider: 'RunPod', gpu: 'RTX 4090', region: 'eu-central-1', price: 0.65, spot: true },
|
|
];
|
|
|
|
if (offerForm) {
|
|
offerForm.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
|
|
const gpuType = document.getElementById('gpuType').value;
|
|
const spotOk = document.getElementById('spotOk').checked;
|
|
|
|
const filteredOffers = mockOffers.filter(offer => {
|
|
const gpuMatch = gpuType === 'any' || offer.gpu === gpuType;
|
|
const spotMatch = !spotOk || offer.spot === true;
|
|
return gpuMatch && spotMatch;
|
|
});
|
|
|
|
renderResults(filteredOffers);
|
|
});
|
|
}
|
|
|
|
function renderResults(offers) {
|
|
if (!resultsTableBody) return;
|
|
|
|
resultsTableBody.innerHTML = '';
|
|
|
|
if (offers.length === 0) {
|
|
resultsTableBody.innerHTML = '<tr><td colspan="5" class="text-center">No matching offers found.</td></tr>';
|
|
return;
|
|
}
|
|
|
|
offers.forEach(offer => {
|
|
const row = `
|
|
<tr>
|
|
<td>${offer.provider}</td>
|
|
<td>${offer.gpu}</td>
|
|
<td>${offer.region}</td>
|
|
<td>$${offer.price.toFixed(2)}</td>
|
|
<td>${offer.spot ? '<span class="badge bg-success">Yes</span>' : '<span class="badge bg-warning text-dark">No</span>'}</td>
|
|
</tr>
|
|
`;
|
|
resultsTableBody.innerHTML += row;
|
|
});
|
|
}
|
|
|
|
// Initial render with all offers
|
|
renderResults(mockOffers);
|
|
|
|
// Contact Form Handler
|
|
const contactForm = document.getElementById('contact-form');
|
|
if (contactForm) {
|
|
contactForm.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
const statusDiv = document.getElementById('contact-form-status');
|
|
const submitButton = contactForm.querySelector('button[type="submit"]');
|
|
|
|
statusDiv.innerHTML = '<p class="text-info">Sending...</p>';
|
|
submitButton.disabled = true;
|
|
|
|
const formData = new FormData(this);
|
|
|
|
fetch('contact.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json().then(data => ({ ok: response.ok, data })))
|
|
.then(({ ok, data }) => {
|
|
if (ok) {
|
|
statusDiv.innerHTML = `<p class="text-success">${data.success}</p>`;
|
|
contactForm.reset();
|
|
} else {
|
|
statusDiv.innerHTML = `<p class="text-danger">${data.error || 'An unknown error occurred.'}</p>`;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
statusDiv.innerHTML = '<p class="text-danger">A network error occurred. Please try again.</p>';
|
|
})
|
|
.finally(() => {
|
|
submitButton.disabled = false;
|
|
});
|
|
});
|
|
}
|
|
}); |