added contact page
This commit is contained in:
parent
69359e8980
commit
445bc39b9e
4 changed files with 1220 additions and 4 deletions
880
package-lock.json
generated
880
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,7 @@
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"@types/jquery": "^3.5.29",
|
"@types/jquery": "^3.5.29",
|
||||||
"sass": "^1.70.0"
|
"sass": "^1.70.0"
|
||||||
}
|
}
|
||||||
|
|
341
src/pages/contact.astro
Normal file
341
src/pages/contact.astro
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
---
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<div
|
||||||
|
class="bg-ieee h-[35em] rounded-b-[10%] my-auto flex flex-col items-center justify-center bg-blend-overlay bg-no-repeat bg-cover align-center bg-center"
|
||||||
|
style="background-image: url('/backgrounds/fa21qp.png');"
|
||||||
|
>
|
||||||
|
<!-- BLUE BG -->
|
||||||
|
<div class="flex flex-col items-center justify-center text-center">
|
||||||
|
<div class="text-[3.2em] text-white font-bold mb-4 w-[11em]">
|
||||||
|
Need to reach out? Fill out the form below!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="isolate bg-white px-6 py-24 sm:py-32 lg:px-8">
|
||||||
|
<div
|
||||||
|
class="absolute inset-x-0 top-[-10rem] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[-20rem]"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="relative left-1/2 -z-10 aspect-[1155/678] w-[36.125rem] max-w-none -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-40rem)] sm:w-[72.1875rem]"
|
||||||
|
style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mx-auto max-w-2xl text-center">
|
||||||
|
<h2
|
||||||
|
class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"
|
||||||
|
>
|
||||||
|
Contact Form
|
||||||
|
</h2>
|
||||||
|
<p class="mt-2 text-lg leading-8 text-gray-600">
|
||||||
|
Make sure you fill out the required fields. Double check to make
|
||||||
|
sure all the information is correct before submitting!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
action="#"
|
||||||
|
method="POST"
|
||||||
|
class="mx-auto mt-16 max-w-xl sm:mt-12"
|
||||||
|
id="contactForm"
|
||||||
|
>
|
||||||
|
<div class="grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for="first-name"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>First name</label
|
||||||
|
>
|
||||||
|
<div class="mt-2.5">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="first-name"
|
||||||
|
id="first-name"
|
||||||
|
autocomplete="given-name"
|
||||||
|
required
|
||||||
|
maxlength="1024"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for="last-name"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>Last name</label
|
||||||
|
>
|
||||||
|
<div class="mt-2.5">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="last-name"
|
||||||
|
id="last-name"
|
||||||
|
autocomplete="family-name"
|
||||||
|
required
|
||||||
|
maxlength="1024"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label
|
||||||
|
for="email"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>Email</label
|
||||||
|
>
|
||||||
|
<div class="mt-2.5">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
id="email"
|
||||||
|
autocomplete="email"
|
||||||
|
required
|
||||||
|
maxlength="1024"
|
||||||
|
pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label
|
||||||
|
for="phone-number"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>Phone number</label
|
||||||
|
>
|
||||||
|
<div class="relative mt-2.5">
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
name="phone-number"
|
||||||
|
id="phone-number"
|
||||||
|
autocomplete="tel"
|
||||||
|
required
|
||||||
|
maxlength="16"
|
||||||
|
pattern="\+?[0-9]{1,3}?[-. ]?[0-9]{2,3}?[-. ]?[0-9]{3,4}?[-. ]?[0-9]{3,4}"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label
|
||||||
|
for="subject"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>Subject</label
|
||||||
|
>
|
||||||
|
<div class="mt-2.5">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="subject"
|
||||||
|
id="subject"
|
||||||
|
autocomplete="subject"
|
||||||
|
required
|
||||||
|
maxlength="1024"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label
|
||||||
|
for="message"
|
||||||
|
class="block text-sm font-semibold leading-6 text-gray-900"
|
||||||
|
>Message</label
|
||||||
|
>
|
||||||
|
<div class="mt-2.5">
|
||||||
|
<textarea
|
||||||
|
name="message"
|
||||||
|
id="message"
|
||||||
|
rows="4"
|
||||||
|
required
|
||||||
|
maxlength="1024"
|
||||||
|
class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-ieee sm:text-sm sm:leading-6"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-x-4 sm:col-span-2">
|
||||||
|
<div class="flex h-6 items-center">
|
||||||
|
<!-- Enabled: "bg-[#0072b5]", Not Enabled: "bg-gray-200" -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="bg-gray-200 flex w-8 flex-none cursor-pointer rounded-full p-px ring-1 ring-inset ring-gray-900/5 transition-colors duration-200 ease-in-out focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ieee"
|
||||||
|
role="switch"
|
||||||
|
aria-checked="false"
|
||||||
|
aria-labelledby="switch-1-label"
|
||||||
|
>
|
||||||
|
<span class="sr-only">Agree to policies</span>
|
||||||
|
<!-- Enabled: "translate-x-3.5", Not Enabled: "translate-x-0" -->
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="translate-x-0 h-4 w-4 transform rounded-full bg-white shadow-sm ring-1 ring-gray-900/5 transition duration-200 ease-in-out"
|
||||||
|
></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
class="text-sm leading-6 text-gray-600"
|
||||||
|
id="switch-1-label"
|
||||||
|
>
|
||||||
|
By selecting this, you agree to our
|
||||||
|
<a
|
||||||
|
href="https://www.ieee.org/security-privacy.html"
|
||||||
|
class="font-semibold text-ieee"
|
||||||
|
>privacy policy</a
|
||||||
|
>.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-10">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
id="policyAgree"
|
||||||
|
class="block w-full rounded-md bg-ieee px-3.5 py-2.5 text-center text-sm font-semibold text-white shadow-sm hover:bg-[#0072b5] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ieee"
|
||||||
|
>Submit to IEEE @ UCSD</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const { PUBLIC_DISCORD_WEBHOOK_LINK } = import.meta.env;
|
||||||
|
const { PUBLIC_SLACK_WEBHOOK_LINK } = import.meta.env;
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const form = document.getElementById("contactForm");
|
||||||
|
const policyAgreeButton = document.querySelector(
|
||||||
|
'button[role="switch"]'
|
||||||
|
);
|
||||||
|
let policyAgreed = false;
|
||||||
|
|
||||||
|
// Toggle privacy policy agreement
|
||||||
|
policyAgreeButton.addEventListener("click", function () {
|
||||||
|
policyAgreed = !policyAgreed;
|
||||||
|
this.setAttribute("aria-checked", policyAgreed);
|
||||||
|
const indicator = this.querySelector(
|
||||||
|
'span[aria-hidden="true"]'
|
||||||
|
);
|
||||||
|
if (policyAgreed) {
|
||||||
|
this.classList.replace("bg-gray-200", "bg-ieee");
|
||||||
|
indicator.classList.replace(
|
||||||
|
"translate-x-0",
|
||||||
|
"translate-x-3.5"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.classList.replace("bg-ieee", "bg-gray-200");
|
||||||
|
indicator.classList.replace(
|
||||||
|
"translate-x-3.5",
|
||||||
|
"translate-x-0"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
form.addEventListener("submit", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!policyAgreed) {
|
||||||
|
alert("Please agree to the privacy policy.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData(form);
|
||||||
|
const formProps = Object.fromEntries(formData);
|
||||||
|
|
||||||
|
const discordPayload = {
|
||||||
|
content: "New contact form submission",
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: "Contact Form Submission",
|
||||||
|
color: 25243,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "First Name",
|
||||||
|
value: formProps["first-name"],
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Last Name",
|
||||||
|
value: formProps["last-name"],
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{ name: "Email", value: formProps["email"] },
|
||||||
|
{
|
||||||
|
name: "Phone Number",
|
||||||
|
value: formProps["phone-number"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Subject",
|
||||||
|
value: formProps["subject"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Message",
|
||||||
|
value: formProps["message"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slack payload may need to be adjusted depending on your Slack app's requirements
|
||||||
|
const slackPayload = {
|
||||||
|
text: "New contact form submission",
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
color: "#36a64f",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
title: "Name",
|
||||||
|
value: `${formProps["first-name"]} ${formProps["last-name"]}`,
|
||||||
|
short: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Email",
|
||||||
|
value: formProps["email"],
|
||||||
|
short: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Phone Number",
|
||||||
|
value: formProps["phone-number"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Subject",
|
||||||
|
value: formProps["subject"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Message",
|
||||||
|
value: formProps["message"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
fetch(PUBLIC_DISCORD_WEBHOOK_LINK, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(discordPayload),
|
||||||
|
}),
|
||||||
|
fetch(PUBLIC_SLACK_WEBHOOK_LINK, {
|
||||||
|
method: "POST",
|
||||||
|
|
||||||
|
body: JSON.stringify(slackPayload),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
.then((responses) => {
|
||||||
|
// Check all responses are ok (could refine to check each individually)
|
||||||
|
if (responses.every((response) => response.ok)) {
|
||||||
|
alert("Form submitted successfully.");
|
||||||
|
form.reset(); // Reset form fields after successful submission
|
||||||
|
// Reset the policy button
|
||||||
|
policyAgreeButton.click(); // This toggles it off
|
||||||
|
} else {
|
||||||
|
alert("Failed to submit form. Please try again.");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error:", error);
|
||||||
|
alert("An error occurred. Please try again.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</Layout>
|
|
@ -11,5 +11,5 @@ export default {
|
||||||
"editor.quickSuggestions": {
|
"editor.quickSuggestions": {
|
||||||
strings: "on",
|
strings: "on",
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [require("@tailwindcss/forms")],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue