Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #21 from thepurplebubble/form
Browse files Browse the repository at this point in the history
Add email form
  • Loading branch information
taciturnaxolotl authored Dec 19, 2023
2 parents 2dbdd29 + 88f28dd commit b30c5c6
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 112 deletions.
7 changes: 6 additions & 1 deletion netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@

[build]
command = "npm run build"
publish = "dist"
publish = "dist"

[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
45 changes: 45 additions & 0 deletions netlify/functions/fetch/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// fetch.js
const axios = require('axios');
const qs = require('qs'); // Add this line

exports.handler = async function (event, context) {
try {
// Parse the incoming form data from the request body
const { name, email, gdpr, hp, list, subform, boolean } = JSON.parse(event.body);

// Stringify the data into a query string
const data = qs.stringify({
name,
email,
gdpr,
hp,
list,
subform,
boolean,
});

// Make the cURL request using axios
const response = await axios.post('https://postal.hackclub.com/subscribe', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});

// log the response for debugging purposes
console.log(response.data);

// Return the response from the external API
return {
statusCode: response.status,
body: JSON.stringify(response.data),
};
} catch (error) {
// Return an error response if something goes wrong
// log the error for debugging purposes
console.log(error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Internal Server Error' }),
};
}
};
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"private": true,
"dependencies": {
"@lottiefiles/lottie-player": "1.5.7",
"astro": "^4.0.4",
"axios": "^1.6.2",
"parcel": "^2.10.3",
"astro": "^4.0.4"
"qs": "^6.11.2"
},
"scripts": {
"prepare": "husky install",
Expand All @@ -26,4 +28,4 @@
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
}
}
}
Binary file modified public/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/chevron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
205 changes: 205 additions & 0 deletions src/components/Email-Form.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
<div id="email-form">
<div class="signup-container">
<div class="signup-container1">
<div class="signup-container2">
<div class="signup-container3">
<form accept-charset="utf-8" id="subscribeForm">
<h2>Newsletter Signup</h2>
<br />
<input
type="text"
name="name"
id="name"
placeholder="Name"
required
/>
<input
type="email"
name="email"
id="email"
placeholder="Email"
required
/>
<label>
<input
type="checkbox"
name="gdpr"
id="gdpr"
value="consent given"
class="css-checkbox"
required
/>
<label for="gdpr" class="css-label"></label>
<span>
<strong>Marketing permission</strong>
: I give my consent to Purple Bubble to be in touch with me via
email using the information I have provided in this form for the
purpose of news, updates and marketing.
</span>
</label>
<br />
<br />
<div style="display:none;">
<label for="hp">HP</label>
<br />
<input type="text" name="hp" id="hp" />
</div>
<input type="hidden" name="list" value="xjAecLBfJ3HdnmuBXhvkfg" />
<input type="hidden" name="subform" value="yes" />
<input
type="text"
name="boolean"
id="boolean"
value="true"
hidden
/>
<button
type="submit"
name="submit"
id="submit"
class="home-button button">Submit</button
>
</form>
</div>
</div>
</div>
</div>
</div>

<style>
#email-form {
transform: translateY(33em);
visibility: hidden;
position: absolute;
}

form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 50%;
margin: auto;
background-color: var(--black);
color: var(--dl-color-gray-white);
padding: 20px;
border-radius: 4px;
border: 1px solid var(--dl-color-gray-white); /* added white border */
}

input[type="text"],
input[type="email"] {
width: 100%;
padding: 10px;
border: 1px solid var(--dl-color-gray-white);
border-radius: 4px; /* reduced border-radius */
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
background-color: var(--black);
color: var(--dl-color-gray-white);
}

input[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 0.95em;
height: 0.95rem;
border: 1px solid var(--dl-color-gray-white);
border-radius: 0.15em;
transform: translateY(0.115em);
margin-top: 10px;
background-color: var(--black);
color: var(--dl-color-gray-white);
}

input[type="checkbox"]:checked::before {
content: "";
display: inline-block;
width: 0.55em;
height: 0.55em;
border: 1px solid var(--dl-color-purple-300);
border-radius: 0.15em;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--dl-color-purple-300);
}

input[type="submit"] {
background-color: var(--dl-color-purple-300);
color: var(--dl-color-gray-white);
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}

input[type="submit"]:hover {
background-color: hsl(273, 100%, 70%);
}

input[type="text"]::placeholder,
input[type="email"]::placeholder {
color: var(--gray);
opacity: 1;
}
</style>

<script>
document
.getElementById("subscribeForm")
.addEventListener("submit", function (event) {
event.preventDefault();

const formData = new FormData(event.target as HTMLFormElement);
const notification = document.getElementById("notification");
const chevronButton = document.getElementById("chevron-button");
const emailForm = document.getElementById("email-form");
const notificationTitle = document.getElementById("notification-title");
const notificationMessage = document.getElementById(
"notification-message",
);

function displayNotification(title, message) {
notificationTitle.innerHTML = title;
notificationMessage.innerHTML = message;

notification.classList.add("show");
// hide the form
emailForm.style.visibility = "hidden";
chevronButton.style.visibility = "visible";
}

fetch("/api/fetch", {
method: "POST",
body: JSON.stringify(Object.fromEntries(formData)),
headers: {
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => {
if (data != "true") {
throw new Error(data);
} else {
console.log("Success:", data);
displayNotification(
"Success!",
"Thank you for signing up to our newsletter!",
);
}
})
.catch((error) => {
// Handle errors
console.error("Error:", error);
displayNotification(
"Error!",
"There was an error signing you up to our newsletter." +
"<br/><br/>" +
error,
);
});
});
</script>
91 changes: 91 additions & 0 deletions src/components/Notification.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<style>
.notification {
position: fixed;
bottom: 1vh;
right: 1vw;
color: var(--dl-color-gray-black);
padding: 0.5rem;
border-color: var(--dl-color-gray-black);
border-width: 1px;
border-radius: 4px;
/* make background a slight blur */
background: rgba(0, 0, 0, 0.8);
}

.notification {
visibility: hidden;
}

.notification.show {
visibility: visible;
animation: disappear 5s forwards;
}

@keyframes disappear {
0% {
bottom: -10vh;
}

10% {
bottom: 1vh;
}

90% {;
bottom: 1vh;
}

100% {
bottom: -10vh;
}
}

.progress-bar {
background-color: var(--dl-color-purple-300);
height: 1rem;
width: 0;
border-radius: 4px;
}

.progress-bar.start {
width: 0;
animation: progress-bar-animation 5s linear forwards;
}

@keyframes progress-bar-animation {
0% {
width: 0;
}

100% {
width: 100%;
}
}
</style>

<div class="notification" id="notification">
<h2 id="notification-title"></h2>
<br/>
<p id="notification-message"></p>
<br/>
<!-- progress bar -->
<div class="progress" id="notification-progress">
<div class="progress-bar" id="notification-progress-bar" style="height:24px;width:1%"></div>
</div>

<script>
const notification = document.getElementById('notification');
const progress = document.getElementById('notification-progress-bar');

// Add an event listener for the animationend event
notification.addEventListener('animationend', function () {
// Remove the show class when the animation ends
notification.classList.remove('show');
// remove progress bar
progress.classList.remove('start');
});

notification.addEventListener('animationstart', function () {
// star progress bar animation
progress.classList.add('start');
});
</script>
Loading

0 comments on commit b30c5c6

Please sign in to comment.