feat: wire the coming-soon waitlist form to POST /api/waitlist
All checks were successful
sync-to-github / sync (push) Successful in 6s
All checks were successful
sync-to-github / sync (push) Successful in 6s
Backend endpoint already deployed (nxtgauge-backend-rust apps/users/src/handlers/waitlist.rs, routed through the gateway). - ingress.yaml: route /api on nxtgauge.com and www.nxtgauge.com to nxtgauge-rust-gateway:9100, same 'more specific paths first' pattern nxtgauge-frontend-solid's ingress already uses - the coming-soon page is a static nginx site with no backend of its own. - index.html: handleSubmit now actually awaits the fetch instead of unconditionally showing success after a commented-out example call. Disables the submit button while in flight, added a form-error state for a failed request (was previously just documented, not wired). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
7088201679
commit
e752326411
3 changed files with 68 additions and 22 deletions
|
|
@ -172,6 +172,11 @@ data:
|
||||||
font-size: 14px; font-weight: 600; color: #4ade80;
|
font-size: 14px; font-weight: 600; color: #4ade80;
|
||||||
animation: fadeIn 0.4s ease;
|
animation: fadeIn 0.4s ease;
|
||||||
}
|
}
|
||||||
|
.form-error {
|
||||||
|
display: none;
|
||||||
|
font-size: 13px; font-weight: 500; color: #f87171;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
@keyframes fadeIn { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
|
@keyframes fadeIn { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
|
||||||
|
|
||||||
/* ── Footer ──────────────────────────────────────────────────── */
|
/* ── Footer ──────────────────────────────────────────────────── */
|
||||||
|
|
@ -247,6 +252,7 @@ data:
|
||||||
</form>
|
</form>
|
||||||
<p class="form-note" id="formNote">No spam. We'll only email when we launch.</p>
|
<p class="form-note" id="formNote">No spam. We'll only email when we launch.</p>
|
||||||
<p class="form-success" id="successMsg">✓ You're on the list! We'll reach out when we go live.</p>
|
<p class="form-success" id="successMsg">✓ You're on the list! We'll reach out when we go live.</p>
|
||||||
|
<p class="form-error" id="errorMsg">Something went wrong. Please try again.</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
|
|
@ -259,23 +265,31 @@ data:
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function handleSubmit(e) {
|
async function handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const email = document.getElementById('emailInput').value.trim();
|
const email = document.getElementById('emailInput').value.trim();
|
||||||
if (!email) return;
|
if (!email) return;
|
||||||
|
|
||||||
document.getElementById('notifyForm').style.display = 'none';
|
const submitBtn = document.querySelector('#notifyForm button[type="submit"]');
|
||||||
document.getElementById('formNote').style.display = 'none';
|
const errorMsg = document.getElementById('errorMsg');
|
||||||
document.getElementById('successMsg').style.display = 'block';
|
errorMsg.style.display = 'none';
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
// Wire to your backend — example:
|
try {
|
||||||
// fetch('/api/waitlist', {
|
const res = await fetch('/api/waitlist', {
|
||||||
// method: 'POST',
|
method: 'POST',
|
||||||
// headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
// body: JSON.stringify({ email })
|
body: JSON.stringify({ email }),
|
||||||
// });
|
});
|
||||||
|
if (!res.ok) throw new Error('Request failed');
|
||||||
|
|
||||||
console.log('Waitlist signup:', email);
|
document.getElementById('notifyForm').style.display = 'none';
|
||||||
|
document.getElementById('formNote').style.display = 'none';
|
||||||
|
document.getElementById('successMsg').style.display = 'block';
|
||||||
|
} catch (err) {
|
||||||
|
errorMsg.style.display = 'block';
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,17 @@ spec:
|
||||||
- host: nxtgauge.com
|
- host: nxtgauge.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
|
# More specific paths must come first — Traefik matches the
|
||||||
|
# longest prefix. /api routes to the Rust gateway directly (the
|
||||||
|
# coming-soon page is a static nginx site with no backend of its
|
||||||
|
# own — see the "Notify Me" waitlist form's fetch('/api/waitlist')).
|
||||||
|
- path: /api
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: nxtgauge-rust-gateway
|
||||||
|
port:
|
||||||
|
number: 9100
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
|
|
@ -27,6 +38,13 @@ spec:
|
||||||
- host: www.nxtgauge.com
|
- host: www.nxtgauge.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
|
- path: /api
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: nxtgauge-rust-gateway
|
||||||
|
port:
|
||||||
|
number: 9100
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@
|
||||||
font-size: 14px; font-weight: 600; color: #4ade80;
|
font-size: 14px; font-weight: 600; color: #4ade80;
|
||||||
animation: fadeIn 0.4s ease;
|
animation: fadeIn 0.4s ease;
|
||||||
}
|
}
|
||||||
|
.form-error {
|
||||||
|
display: none;
|
||||||
|
font-size: 13px; font-weight: 500; color: #f87171;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
@keyframes fadeIn { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
|
@keyframes fadeIn { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
|
||||||
|
|
||||||
/* ── Footer ──────────────────────────────────────────────────── */
|
/* ── Footer ──────────────────────────────────────────────────── */
|
||||||
|
|
@ -244,6 +249,7 @@
|
||||||
</form>
|
</form>
|
||||||
<p class="form-note" id="formNote">No spam. We'll only email when we launch.</p>
|
<p class="form-note" id="formNote">No spam. We'll only email when we launch.</p>
|
||||||
<p class="form-success" id="successMsg">✓ You're on the list! We'll reach out when we go live.</p>
|
<p class="form-success" id="successMsg">✓ You're on the list! We'll reach out when we go live.</p>
|
||||||
|
<p class="form-error" id="errorMsg">Something went wrong. Please try again.</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
|
|
@ -256,23 +262,31 @@
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function handleSubmit(e) {
|
async function handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const email = document.getElementById('emailInput').value.trim();
|
const email = document.getElementById('emailInput').value.trim();
|
||||||
if (!email) return;
|
if (!email) return;
|
||||||
|
|
||||||
document.getElementById('notifyForm').style.display = 'none';
|
const submitBtn = document.querySelector('#notifyForm button[type="submit"]');
|
||||||
document.getElementById('formNote').style.display = 'none';
|
const errorMsg = document.getElementById('errorMsg');
|
||||||
document.getElementById('successMsg').style.display = 'block';
|
errorMsg.style.display = 'none';
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
// Wire to your backend — example:
|
try {
|
||||||
// fetch('/api/waitlist', {
|
const res = await fetch('/api/waitlist', {
|
||||||
// method: 'POST',
|
method: 'POST',
|
||||||
// headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
// body: JSON.stringify({ email })
|
body: JSON.stringify({ email }),
|
||||||
// });
|
});
|
||||||
|
if (!res.ok) throw new Error('Request failed');
|
||||||
|
|
||||||
console.log('Waitlist signup:', email);
|
document.getElementById('notifyForm').style.display = 'none';
|
||||||
|
document.getElementById('formNote').style.display = 'none';
|
||||||
|
document.getElementById('successMsg').style.display = 'block';
|
||||||
|
} catch (err) {
|
||||||
|
errorMsg.style.display = 'block';
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue