Spaces:
Running
Running
Update index.html
Browse files- index.html +109 -95
index.html
CHANGED
@@ -401,113 +401,127 @@
|
|
401 |
</form>
|
402 |
</div>
|
403 |
</div>
|
404 |
-
|
405 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
|
|
|
|
417 |
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
|
|
|
|
429 |
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
}
|
442 |
-
};
|
443 |
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
454 |
});
|
455 |
-
|
456 |
-
|
457 |
-
const result = await response.json();
|
458 |
-
localStorage.setItem('accessToken', result.accessToken);
|
459 |
-
localStorage.setItem('partnerName', result.partnerName);
|
460 |
-
sessionToken = result.accessToken;
|
461 |
-
checkLoginState(); // Re-check the state to show the button
|
462 |
|
463 |
-
|
464 |
-
|
465 |
-
|
|
|
|
|
|
|
|
|
|
|
466 |
}
|
467 |
-
|
|
|
|
|
468 |
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${sessionToken}`},
|
477 |
-
body: JSON.stringify(entryData),
|
478 |
});
|
479 |
-
if (!response.ok) throw new Error('Authorization failed. Please log in again.');
|
480 |
-
|
481 |
-
const result = await response.json();
|
482 |
-
alert(`${result.message}\nNew Balance: ${result.newBalance.toFixed(2)}`);
|
483 |
-
entryModal.style.display = 'none';
|
484 |
-
ledgerForm.reset();
|
485 |
-
} catch (error) {
|
486 |
-
alert(error.message);
|
487 |
}
|
488 |
-
});
|
489 |
-
|
490 |
-
// Event listeners for logout and modal buttons
|
491 |
-
logoutBtn.addEventListener('click', () => {
|
492 |
-
localStorage.removeItem('accessToken');
|
493 |
-
localStorage.removeItem('partnerName');
|
494 |
-
sessionToken = null;
|
495 |
-
checkLoginState(); // Re-check state to show the login form again
|
496 |
-
});
|
497 |
-
|
498 |
-
addEntryBtn.addEventListener('click', () => entryModal.style.display = 'flex');
|
499 |
-
cancelBtn.addEventListener('click', () => { entryModal.style.display = 'none'; ledgerForm.reset(); });
|
500 |
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
localStorage.removeItem('accessToken');
|
506 |
-
localStorage.removeItem('partnerName');
|
507 |
-
alert('Session data has been cleared. The page will now reload.');
|
508 |
-
window.location.reload();
|
509 |
-
});
|
510 |
-
</script>
|
511 |
<div class="modal-overlay" id="loginModal">
|
512 |
<div class="modal-content">
|
513 |
<h3>Partner Access</h3>
|
|
|
401 |
</form>
|
402 |
</div>
|
403 |
</div>
|
404 |
+
<script>
|
405 |
+
// The entire script is wrapped in a DOMContentLoaded listener.
|
406 |
+
// This ensures the script only runs AFTER the entire HTML page is loaded,
|
407 |
+
// which guarantees that all buttons and forms can be found.
|
408 |
+
document.addEventListener('DOMContentLoaded', () => {
|
409 |
+
|
410 |
+
// ▼▼▼▼▼ CRITICAL: CONFIGURE YOUR WORKER URL ▼▼▼▼▼
|
411 |
+
const WORKER_URL="https://partnership-ledger-api.aiagents.workers.dev/";
|
412 |
+
// ▲▲▲▲▲ CRITICAL: CONFIGURE YOUR WORKER URL ▲▲▲▲▲
|
413 |
+
|
414 |
+
// Add the Turnstile script to the page dynamically
|
415 |
+
const turnstileScript = document.createElement('script');
|
416 |
+
turnstileScript.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
|
417 |
+
turnstileScript.async = true;
|
418 |
+
turnstileScript.defer = true;
|
419 |
+
document.head.appendChild(turnstileScript);
|
420 |
|
421 |
+
// Get all the elements we need to control
|
422 |
+
const loginModal = document.getElementById('loginModal');
|
423 |
+
const entryModal = document.getElementById('entryModal');
|
424 |
+
const addEntryBtn = document.getElementById('addEntryBtn');
|
425 |
+
const cancelBtn = document.getElementById('cancelBtn');
|
426 |
+
const loginForm = document.getElementById('loginForm');
|
427 |
+
const ledgerForm = document.getElementById('ledgerForm');
|
428 |
+
const welcomeDiv = document.getElementById('welcome');
|
429 |
+
const partnerNameSpan = document.getElementById('partnerName');
|
430 |
+
const logoutBtn = document.getElementById('logoutBtn');
|
431 |
+
const forceLogoutBtn = document.getElementById('forceLogoutBtn'); // Get the new button
|
432 |
+
let sessionToken = localStorage.getItem('accessToken');
|
433 |
|
434 |
+
// This function checks if a user is already logged in on page load
|
435 |
+
const checkLoginState = () => {
|
436 |
+
if (sessionToken) {
|
437 |
+
if (loginModal) loginModal.style.display = 'none';
|
438 |
+
if (addEntryBtn) addEntryBtn.style.display = 'flex';
|
439 |
+
if (welcomeDiv) welcomeDiv.style.display = 'block';
|
440 |
+
if (partnerNameSpan) partnerNameSpan.textContent = localStorage.getItem('partnerName');
|
441 |
+
} else {
|
442 |
+
if (loginModal) loginModal.style.display = 'flex';
|
443 |
+
if (addEntryBtn) addEntryBtn.style.display = 'none';
|
444 |
+
if (welcomeDiv) welcomeDiv.style.display = 'none';
|
445 |
+
}
|
446 |
+
};
|
447 |
|
448 |
+
// Event listener for the LOGIN form
|
449 |
+
if (loginForm) {
|
450 |
+
loginForm.addEventListener('submit', async (e) => {
|
451 |
+
e.preventDefault();
|
452 |
+
const formData = new FormData(loginForm);
|
453 |
+
const data = Object.fromEntries(formData.entries());
|
454 |
+
try {
|
455 |
+
const response = await fetch(`${WORKER_URL}/api/login`, {
|
456 |
+
method: 'POST',
|
457 |
+
headers: { 'Content-Type': 'application/json' },
|
458 |
+
body: JSON.stringify(data)
|
459 |
+
});
|
460 |
+
if (!response.ok) throw new Error('Login failed. Check your ID and try again.');
|
461 |
+
|
462 |
+
const result = await response.json();
|
463 |
+
localStorage.setItem('accessToken', result.accessToken);
|
464 |
+
localStorage.setItem('partnerName', result.partnerName);
|
465 |
+
sessionToken = result.accessToken;
|
466 |
+
checkLoginState();
|
467 |
+
|
468 |
+
} catch (error) {
|
469 |
+
alert(error.message);
|
470 |
+
try { turnstile.reset(); } catch (e) {}
|
471 |
+
}
|
472 |
+
});
|
473 |
}
|
|
|
474 |
|
475 |
+
// Event listener for the LEDGER form
|
476 |
+
if(ledgerForm) {
|
477 |
+
ledgerForm.addEventListener('submit', async (e) => {
|
478 |
+
e.preventDefault();
|
479 |
+
const entryData = { date: document.getElementById('date').value, description: document.getElementById('description').value, ref: document.getElementById('ref').value, debit: document.getElementById('debit').value || 0, credit: document.getElementById('credit').value || 0 };
|
480 |
+
try {
|
481 |
+
const response = await fetch(`${WORKER_URL}/api/ledger`, {
|
482 |
+
method: 'POST',
|
483 |
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${sessionToken}`},
|
484 |
+
body: JSON.stringify(entryData),
|
485 |
+
});
|
486 |
+
if (!response.ok) throw new Error('Authorization failed. Please log in again.');
|
487 |
+
|
488 |
+
const result = await response.json();
|
489 |
+
alert(`${result.message}\nNew Balance: ${result.newBalance.toFixed(2)}`);
|
490 |
+
entryModal.style.display = 'none';
|
491 |
+
ledgerForm.reset();
|
492 |
+
} catch (error) {
|
493 |
+
alert(error.message);
|
494 |
+
}
|
495 |
});
|
496 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
497 |
|
498 |
+
// Event listeners for logout and modal buttons
|
499 |
+
if (logoutBtn) {
|
500 |
+
logoutBtn.addEventListener('click', () => {
|
501 |
+
localStorage.removeItem('accessToken');
|
502 |
+
localStorage.removeItem('partnerName');
|
503 |
+
sessionToken = null;
|
504 |
+
checkLoginState();
|
505 |
+
});
|
506 |
}
|
507 |
+
|
508 |
+
if (addEntryBtn) addEntryBtn.addEventListener('click', () => entryModal.style.display = 'flex');
|
509 |
+
if (cancelBtn) cancelBtn.addEventListener('click', () => { entryModal.style.display = 'none'; ledgerForm.reset(); });
|
510 |
|
511 |
+
// Event listener for our temporary Force Logout button
|
512 |
+
if(forceLogoutBtn) {
|
513 |
+
forceLogoutBtn.addEventListener('click', () => {
|
514 |
+
localStorage.removeItem('accessToken');
|
515 |
+
localStorage.removeItem('partnerName');
|
516 |
+
alert('Session data has been cleared. The page will now reload.');
|
517 |
+
window.location.reload();
|
|
|
|
|
518 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
519 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
|
521 |
+
// Run the initial check to see if we should show the login modal or the app
|
522 |
+
checkLoginState();
|
523 |
+
});
|
524 |
+
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
525 |
<div class="modal-overlay" id="loginModal">
|
526 |
<div class="modal-content">
|
527 |
<h3>Partner Access</h3>
|