From 64cd7fc83d43a0ad7db1b51214291736bd245b44 Mon Sep 17 00:00:00 2001
From: Andrew Lee <alee14498@protonmail.com>
Date: Fri, 28 Jun 2024 20:31:02 -0400
Subject: Guestbook overhaul; Comments; New post; Updated packages

---
 src/components/GuestbookForm.jsx | 74 ++++++++++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 15 deletions(-)

(limited to 'src/components/GuestbookForm.jsx')

diff --git a/src/components/GuestbookForm.jsx b/src/components/GuestbookForm.jsx
index 613c9d3..1f1d3c9 100644
--- a/src/components/GuestbookForm.jsx
+++ b/src/components/GuestbookForm.jsx
@@ -1,6 +1,5 @@
 import { Component } from 'preact';
-import { createMessage } from '../services/GuestbookService';
-import '../styles/GuestbookForm.css';
+import '../styles/Form.css';
 import { marked } from "marked";
 import DOMPurify from 'dompurify';
 
@@ -10,8 +9,33 @@ class GuestbookForm extends Component {
         website: '',
         message: '',
         isMessageSent: false,
+        messageId: ''
     };
 
+    componentDidMount() {
+        // Ensure the Turnstile script is loaded with explicit rendering
+        const script = document.createElement('script');
+        script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=onloadTurnstileCallback';
+        script.defer = true;
+        document.body.appendChild(script);
+
+        // Callback function to handle Turnstile token
+        window.onloadTurnstileCallback = () => {
+            window.turnstile.render('#turnstile-container', {
+                sitekey: '0x4AAAAAAAdb4uvxFFzNEDxB',
+                callback: (token) => {
+                    // Here you can handle the token, e.g., by storing it in a hidden form field
+                    this.setState({turnstileToken: token});
+                },
+            });
+        };
+
+        // Cleanup function to remove the script when the component unmounts
+        return () => {
+            document.body.removeChild(script);
+        };
+    }
+
     handleChange = (e) => {
         this.setState({ [e.target.name]: e.target.value });
     }
@@ -26,20 +50,30 @@ class GuestbookForm extends Component {
             return;
         }
 
-        const urlRegex = /(https?:\/\/\S+)/g;
-        const imageRegex = /!\[.*]\(.*\)/g;
-
-        if (urlRegex.test(this.state.message) || imageRegex.test(this.state.message)) {
-            this.setState({
-                errorMessage: 'Links and images are not allowed.',
-            });
-            return;
-        }
-
         try {
             const messageHtml = marked(DOMPurify.sanitize(this.state.message));
             const { isMessageSent, errorMessage, ...messageData } = this.state; // Exclude isMessageSent from the data
-            await createMessage({ ...messageData, message: messageHtml });
+
+            const response = await fetch(`${import.meta.env.PUBLIC_API_URL}/guestbook`, {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify({ ...messageData, message: messageHtml }),
+            });
+
+            if (!response.ok) {
+                const errorBody = await response.json();
+                const errorMessage = `HTTP Error ${response.status}: ${response.statusText}<br>${errorBody.message}`;
+
+                this.setState({
+                    errorMessage: `There was an error submitting your message.<br>Details:<br>${errorMessage}`,
+                    isMessageSent: false,
+                });
+                return;
+            }
+
+            const responseBody = await response.json();
 
             this.setState({
                 name: '',
@@ -47,6 +81,7 @@ class GuestbookForm extends Component {
                 message: '',
                 isMessageSent: true,
                 errorMessage: '',
+                messageId: responseBody.id,
             });
 
             if (this.props.onMessageSent) {
@@ -54,7 +89,7 @@ class GuestbookForm extends Component {
             }
         } catch (error) {
             this.setState({
-                errorMessage: `There was an error submitting your message.<br>Details: ${error}<br>Check the console for more details.`,
+                errorMessage: `There was an error submitting your message.<br>Details:<br>${error.message}<br>Check the console for more details.`,
                 isMessageSent: false,
             });
         }
@@ -72,10 +107,19 @@ class GuestbookForm extends Component {
                     <label htmlFor="message">Message * (Supports <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank">Markdown</a>)</label>
                     <textarea name="message" placeholder="Enter your message here." required value={this.state.message}
                               onChange={this.handleChange} disabled={this.state.isMessageSent}></textarea>
+                    <div id="turnstile-container"></div>
                     <button class="button" type="submit" disabled={this.state.isMessageSent}>Send</button>
                 </form>
                 {this.state.errorMessage && <p dangerouslySetInnerHTML={{__html: this.state.errorMessage}}/>}
-                {this.state.isMessageSent && !this.state.errorMessage && <p>Sent successfully!</p>}
+                {this.state.isMessageSent && !this.state.errorMessage &&
+                    <div>
+                        <p>Sent successfully!</p>
+                        <p>(Optional)</p>
+                        <p>Save this message ID: {this.state.messageId}</p>
+                        <p>Then send it to me, to verify that you sent this message.</p>
+                        <p><a href="mailto:andrew@alee14.me">Email me</a> or tag/message me on these <a href="/contacts">platforms</a>.</p>
+                    </div>
+                }
             </div>
         );
     }
-- 
cgit v1.2.3

