fix(join): wire handleJoin and handleSplashJoin in public scripts and join fragments to fix 400 error on /join
This commit is contained in:
parent
77a82cbe84
commit
c221e32855
@ -1076,3 +1076,116 @@ document.addEventListener("keydown", (e) => {
|
|||||||
closeAttendeesDrawer();
|
closeAttendeesDrawer();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function handleJoin(e) {
|
||||||
|
if (e && e.preventDefault) e.preventDefault();
|
||||||
|
const input = document.getElementById("eventCode");
|
||||||
|
const code = input ? input.value.trim() : "";
|
||||||
|
if (!code) return;
|
||||||
|
|
||||||
|
const btn = document.getElementById("joinBtn");
|
||||||
|
const notice = document.getElementById("joinNotice");
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.textContent = "Claiming Seat...";
|
||||||
|
}
|
||||||
|
if (notice) notice.style.display = "none";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/join", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ code }),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (res.ok && data.success) {
|
||||||
|
showNotice("Seat claimed! Redirecting...", false);
|
||||||
|
globalThis.location.href = data.redirectUrl || "/dashboard";
|
||||||
|
} else {
|
||||||
|
if (notice) {
|
||||||
|
notice.textContent = data.error ||
|
||||||
|
"Invalid event code or workshop capacity reached";
|
||||||
|
notice.style.display = "block";
|
||||||
|
notice.style.background = "var(--danger-bg)";
|
||||||
|
notice.style.color = "var(--danger-text)";
|
||||||
|
notice.style.border = "1px solid var(--danger-border)";
|
||||||
|
}
|
||||||
|
showNotice(data.error || "Invalid event code", true);
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = "⚡ Enter Workshop";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_err) {
|
||||||
|
if (notice) {
|
||||||
|
notice.textContent = "Network error connecting to event";
|
||||||
|
notice.style.display = "block";
|
||||||
|
notice.style.background = "var(--danger-bg)";
|
||||||
|
notice.style.color = "var(--danger-text)";
|
||||||
|
notice.style.border = "1px solid var(--danger-border)";
|
||||||
|
}
|
||||||
|
showNotice("Network error connecting to event", true);
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = "⚡ Enter Workshop";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalThis.handleJoin = handleJoin;
|
||||||
|
|
||||||
|
async function handleSplashJoin(slug) {
|
||||||
|
const btn = document.getElementById("joinSplashBtn");
|
||||||
|
const notice = document.getElementById("splashNotice");
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.textContent = "Claiming Seat...";
|
||||||
|
}
|
||||||
|
if (notice) notice.style.display = "none";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/join", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ code: slug }),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (res.ok && data.success) {
|
||||||
|
showNotice("Seat claimed! Redirecting...", false);
|
||||||
|
globalThis.location.href = data.redirectUrl || "/dashboard";
|
||||||
|
} else {
|
||||||
|
if (notice) {
|
||||||
|
notice.textContent = data.error ||
|
||||||
|
"Invalid event code or workshop is full";
|
||||||
|
notice.style.display = "block";
|
||||||
|
notice.style.background = "var(--danger-bg)";
|
||||||
|
notice.style.color = "var(--danger-text)";
|
||||||
|
notice.style.border = "1px solid var(--danger-border)";
|
||||||
|
}
|
||||||
|
showNotice(data.error || "Failed to enter workshop", true);
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = "⚡ Enter Workshop & Claim Seat";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_err) {
|
||||||
|
if (notice) {
|
||||||
|
notice.textContent = "Network error connecting to event";
|
||||||
|
notice.style.display = "block";
|
||||||
|
notice.style.background = "var(--danger-bg)";
|
||||||
|
notice.style.color = "var(--danger-text)";
|
||||||
|
notice.style.border = "1px solid var(--danger-border)";
|
||||||
|
}
|
||||||
|
showNotice("Network error connecting to event", true);
|
||||||
|
if (btn) {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = "⚡ Enter Workshop & Claim Seat";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalThis.handleSplashJoin = handleSplashJoin;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ Deno.test("[Events] GET /join returns EventJoinPage HTML", async () => {
|
|||||||
assertEquals(res.status, 200);
|
assertEquals(res.status, 200);
|
||||||
const html = await res.text();
|
const html = await res.text();
|
||||||
assertStringIncludes(html, "Join Event or Workshop");
|
assertStringIncludes(html, "Join Event or Workshop");
|
||||||
assertStringIncludes(html, 'data-on-submit="@post('/api/join')"');
|
assertStringIncludes(html, 'onsubmit="handleJoin(event)"');
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("[Events] POST /api/join without code returns HTML error fragment", async () => {
|
Deno.test("[Events] POST /api/join without code returns HTML error fragment", async () => {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export const EventJoinPageFragment = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="joinForm" data-on-submit="@post('/api/join')">
|
<form id="joinForm" onsubmit="handleJoin(event)">
|
||||||
<div style="margin-bottom: 1.25rem;">
|
<div style="margin-bottom: 1.25rem;">
|
||||||
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.875rem; color: var(--text-secondary);">
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.875rem; color: var(--text-secondary);">
|
||||||
Event PIN or Slug Code
|
Event PIN or Slug Code
|
||||||
@ -73,6 +73,8 @@ export const EventJoinPageFragment = () => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="/public/sessions-scripts.js"></script>
|
||||||
</AuthLayoutFragment>
|
</AuthLayoutFragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,19 +76,22 @@ export const EventSplashPageFragment = ({ event }: { event: any }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="splashNotice"
|
||||||
|
style="display: none; margin-bottom: 1rem; padding: 0.75rem 1rem; border-radius: var(--radius-md); font-size: 0.9rem;"
|
||||||
|
/>
|
||||||
|
|
||||||
{!isFull
|
{!isFull
|
||||||
? (
|
? (
|
||||||
<form id="splashForm" data-on-submit="@post('/api/join')">
|
<button
|
||||||
<input type="hidden" name="code" value={event.slug} />
|
type="button"
|
||||||
<button
|
id="joinSplashBtn"
|
||||||
type="submit"
|
class="btn-primary"
|
||||||
id="joinSplashBtn"
|
style="width: 100%; min-height: 52px; font-size: 1.05rem; box-shadow: var(--shadow-sm);"
|
||||||
class="btn-primary"
|
onclick={`handleSplashJoin('${event.slug}')`}
|
||||||
style="width: 100%; min-height: 52px; font-size: 1.05rem; box-shadow: var(--shadow-sm);"
|
>
|
||||||
>
|
⚡ Enter Workshop & Claim Seat
|
||||||
⚡ Enter Workshop & Claim Seat
|
</button>
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
<button
|
<button
|
||||||
@ -111,6 +114,8 @@ export const EventSplashPageFragment = ({ event }: { event: any }) => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="/public/sessions-scripts.js"></script>
|
||||||
</AuthLayoutFragment>
|
</AuthLayoutFragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user