Skip to content

Commit 5e62518

Browse files
authored
docs: ShaderHunt form tweaks (#1889)
1 parent 2802126 commit 5e62518

1 file changed

Lines changed: 74 additions & 50 deletions

File tree

apps/typegpu-docs/src/components/shaderhunt/ChallengesSignupPopover.astro

Lines changed: 74 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
<div data-challenges-signup-popover="true" class="contents">
55
<slot />
6-
<dialog class="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 border border-gray-300 dark:border-gray-700 p-6 rounded-none shadow-lg max-w-md w-full backdrop:bg-black/20 dark:backdrop:bg-black/50 backdrop:backdrop-blur-md">
7-
<form method="dialog">
6+
<dialog data-success="false" class="group fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 border border-gray-300 dark:border-gray-700 p-6 rounded-none shadow-lg max-w-md w-full backdrop:bg-black/20 dark:backdrop:bg-black/50 backdrop:backdrop-blur-md">
7+
<form method="dialog" class="hidden group-[[data-success='false']]:block">
88
<p class="text-justify text-base mb-12">Sign up to be notified when the <strong>ShaderHunt</strong> platform is available, along with interactive examples teaching TypeGPU from the ground up.</p>
99
<label for="name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Your name (required)</label>
1010
<input type="text" id="name" name="name" required class="w-full mb-8 px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 rounded-none focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400" />
@@ -22,64 +22,88 @@
2222
</div>
2323
<button type="submit" class="mt-4 w-full px-4 py-2 bg-accent-600 dark:bg-accent-700 text-white font-medium border-none rounded-none hover:bg-accent-700 dark:hover:bg-accent-800 focus:outline-none focus:ring-2 focus:ring-accent-500 dark:focus:ring-accent-400">Get Notified</button>
2424
</form>
25+
<div class="hidden group-[[data-success='true']]:block">
26+
<p class="text-2xl font-bold text-center text-gray-700 dark:text-gray-300 mb-5">Thank you for signing up for ShaderHunt updates!</p>
27+
<p class="text-sm text-center text-gray-700 dark:text-gray-300 my-3">You should receive a confirmation email shortly.</p>
28+
<button data-close type="button" class="mt-4 w-full px-4 py-2 bg-accent-600 dark:bg-accent-700 text-white font-medium border-none rounded-none hover:bg-accent-700 dark:hover:bg-accent-800 focus:outline-none focus:ring-2 focus:ring-accent-500 dark:focus:ring-accent-400">Close</button>
29+
</div>
2530
</dialog>
2631
</div>
2732

2833
<script>
2934
const popovers = document.querySelectorAll('[data-challenges-signup-popover="true"]');
30-
popovers.forEach((popover) => {
31-
const linkElement: HTMLAnchorElement|null = popover.querySelector('a');
32-
const dialogElement: HTMLDialogElement|null = popover.querySelector('dialog');
33-
const formElement: HTMLFormElement|null = popover.querySelector('form');
3435

35-
if (!linkElement || !dialogElement || !formElement) {
36-
return;
37-
}
38-
39-
// Check if URL hash indicates popover should be open
40-
if (window.location.hash === '#challenges-signup') {
41-
dialogElement?.showModal();
42-
}
36+
class DialogBox {
37+
readonly dialogElement: HTMLDialogElement;
4338

44-
linkElement.addEventListener('click', (e) => {
45-
e.preventDefault();
46-
window.location.hash = '#challenges-signup';
47-
dialogElement?.showModal();
48-
});
39+
constructor(popover: Element) {
40+
const linkElement: HTMLAnchorElement|null = popover.querySelector('a');
41+
const dialogElement: HTMLDialogElement|null = popover.querySelector('dialog');
42+
const formElement: HTMLFormElement|null = popover.querySelector('form');
43+
const closeButton: HTMLButtonElement|null = popover.querySelector('button[data-close]');
4944

50-
dialogElement.addEventListener('close', () => {
51-
if (window.location.hash === '#challenges-signup') {
52-
window.location.hash = '';
45+
if (!linkElement || !dialogElement || !formElement || !closeButton) {
46+
throw new Error(`Missing required elements: link: ${linkElement ? '✅' : '🚫'}, dialog: ${dialogElement ? '✅' : '🚫'}, form: ${formElement ? '✅' : '🚫'}, closeButton: ${closeButton ? '✅' : '🚫'}`);
5347
}
54-
});
5548

56-
formElement.addEventListener('submit', async (e) => {
57-
e.preventDefault();
58-
const formData = new FormData(formElement);
59-
const data = {
60-
name: formData.get('name'),
61-
email: formData.get('email'),
62-
newsletterAgree: formData.get('newsletter-agree') === 'on'
63-
};
49+
this.dialogElement = dialogElement;
50+
this.dialogElement.dataset.success = 'false';
51+
52+
linkElement.addEventListener('click', (e) => {
53+
e.preventDefault();
54+
window.location.hash = '#challenges-signup';
55+
dialogElement?.showModal();
56+
});
6457

65-
try {
66-
const response = await fetch('https://swmansion.dev/api/shaderhunt/signin', {
67-
method: 'POST',
68-
headers: {
69-
'Content-Type': 'application/json'
70-
},
71-
body: JSON.stringify(data)
72-
});
73-
console.log(await response.text());
74-
if (response.ok) {
75-
formElement.reset();
76-
dialogElement.close();
77-
} else {
78-
alert('Error submitting form. Please try again.');
58+
dialogElement.addEventListener('close', () => {
59+
if (window.location.hash === '#challenges-signup') {
60+
window.location.hash = '';
7961
}
80-
} catch (error) {
81-
alert('Network error. Please try again.');
82-
}
83-
});
84-
});
62+
});
63+
64+
formElement.addEventListener('submit', async (e) => {
65+
e.preventDefault();
66+
const formData = new FormData(formElement);
67+
const data = {
68+
name: formData.get('name'),
69+
email: formData.get('email'),
70+
newsletterAgree: formData.get('newsletter-agree') === 'on'
71+
};
72+
73+
try {
74+
const response = await fetch('https://swmansion.dev/api/shaderhunt/signin', {
75+
method: 'POST',
76+
headers: {
77+
'Content-Type': 'application/json'
78+
},
79+
body: JSON.stringify(data)
80+
});
81+
console.log(await response.text());
82+
if (response.ok) {
83+
formElement.reset();
84+
dialogElement.dataset.success = 'true';
85+
} else {
86+
alert('Error submitting form. Please try again.');
87+
}
88+
} catch (error) {
89+
alert('Network error. Please try again.');
90+
}
91+
});
92+
93+
closeButton.addEventListener('click', () => {
94+
dialogElement.close();
95+
});
96+
}
97+
}
98+
99+
const dialogBoxes = Array.from(popovers).map((popover) => new DialogBox(popover));
100+
101+
// Check if URL hash indicates popover should be open
102+
if (window.location.hash === '#challenges-signup') {
103+
const firstDialogBox = dialogBoxes[0]
104+
if (!firstDialogBox) {
105+
throw new Error('Expected at least one dialog box');
106+
}
107+
firstDialogBox.dialogElement.showModal();
108+
}
85109
</script>

0 commit comments

Comments
 (0)