22import type { Form as Props } from ' ~/types' ;
33import Button from ' ~/components/ui/Button.astro' ;
44
5+ const isProd = import .meta .env .PROD ;
6+ const siteKey = isProd ? ' 0x4AAAAAAByo9pKriiVamG2A' : ' 3x00000000000000000000FF' ;
7+
58const { inputs, textarea, disclaimer, button = ' Contact us' , description = ' ' } = Astro .props ;
69---
710
811<form >
912 {
1013 inputs &&
1114 inputs .map (
12- ({ type = ' text' , name , label = ' ' , autocomplete = ' on' , placeholder = ' ' }) =>
15+ ({ type = ' text' , name , label = ' ' , autocomplete = ' on' , placeholder = ' ' , required = false }) =>
1316 name && (
1417 <div class = " mb-6" >
1518 { label && (
@@ -23,6 +26,7 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
2326 id = { name }
2427 autocomplete = { autocomplete }
2528 placeholder = { placeholder }
29+ required = { required }
2630 class = " py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900"
2731 />
2832 </div >
@@ -42,6 +46,7 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
4246 rows = { textarea .rows ? textarea .rows : 4 }
4347 placeholder = { textarea .placeholder }
4448 class = " py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900"
49+ required = { textarea .required || false }
4550 />
4651 </div >
4752 )
@@ -69,7 +74,10 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
6974
7075 {
7176 button && (
72- <div class = " mt-10 grid" >
77+ <div class = " grid" >
78+ <div class = " checkbox my-3 mx-auto" >
79+ <div class = " cf-turnstile" data-sitekey = { siteKey } data-theme = " dark" />
80+ </div >
7381 <Button variant = " primary" type = " submit" >
7482 { button }
7583 </Button >
@@ -85,3 +93,54 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
8593 )
8694 }
8795</form >
96+
97+ <script define:vars ={ { siteKey }} is:inline >
98+ window.onloadTurnstileCallback = function () {
99+ turnstile.render('#turnstile-challenge', {
100+ sitekey: siteKey,
101+ callback: function (_) {
102+ document.querySelector('button').disabled = false;
103+ },
104+ });
105+ };
106+
107+ // Add event listener for form submission
108+ document.querySelector('form')?.addEventListener('submit', async (e) => {
109+ e.preventDefault();
110+ const formData = new FormData(e.target);
111+
112+ // Call the contact webhook
113+ try {
114+ const response = await fetch('https://ktech-studio-contact-form.deno.dev/contact', {
115+ method: 'POST',
116+ body: formData,
117+ });
118+
119+ if (!response.ok) {
120+ throw new Error('Network response was not ok');
121+ }
122+
123+ window
124+ .Toastify({
125+ text: 'Message sent successfully',
126+ style: { background: 'green' },
127+ })
128+ .showToast();
129+
130+ // Clear the form fields
131+ document.querySelectorAll('input,textarea').forEach((x) => (x.value = ''));
132+ window.turnstile.reset();
133+ document.querySelector('button').disabled = true;
134+ } catch (error) {
135+ console.error('Error sending message:', error);
136+ window
137+ .Toastify({
138+ text: 'Error sending message',
139+ style: { background: 'red' },
140+ })
141+ .showToast();
142+ }
143+ });
144+ </script >
145+
146+ <script src =" https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer ></script >
0 commit comments