added subscriptions

This commit is contained in:
2023-01-24 16:30:49 +10:00
parent 4c83399d4a
commit 0b1fee1cdc
15 changed files with 690 additions and 73 deletions

View File

@@ -65,6 +65,14 @@ export const routes = [
},
component: () => import("@/views/Rules.vue"),
},
{
path: "/unsubscribe",
name: "unsubscribe",
meta: {
title: "Unsubscribe",
},
component: () => import("@/views/Unsubscribe.vue"),
},
{
path: "/terms",
name: "terms",

View File

@@ -110,25 +110,67 @@
Join our mailing list to receive tips, tricks and be notified of
upcoming workshops.
</p>
<div class="form-row">
<SMInput ref="email" type="email" placeholder="Email address" />
<SMButton label="Subscribe" @click="handleSubscribe" />
</div>
<SMDialog :loading="formLoading" class="p-0">
<form @submit.prevent="handleSubscribe">
<div class="form-row">
<SMMessage
v-if="formMessage.message"
:type="formMessage.type"
:message="formMessage.message"
:icon="formMessage.icon" />
<SMInput
v-model="subscribeFormData.email.value"
placeholder="Email address"
:error="subscribeFormData.email.error"
@blur="fieldValidate(subscribeFormData.email)" />
<SMCaptchaNotice />
<SMButton type="submit" label="Subscribe" />
</div>
</form>
</SMDialog>
</SMContainer>
</SMContainer>
</template>
<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";
import { reactive, ref } from "vue";
import { buildUrlQuery, excerpt } from "../helpers/common";
import {
useValidation,
isValidated,
fieldValidate,
restParseErrors,
} from "../helpers/validation";
import SMInput from "../components/SMInput.vue";
import SMButton from "../components/SMButton.vue";
import SMCarousel from "../components/SMCarousel.vue";
import SMCarouselSlide from "../components/SMCarouselSlide.vue";
import SMMessage from "../components/SMMessage.vue";
import SMCaptchaNotice from "../components/SMCaptchaNotice.vue";
import SMDialog from "../components/SMDialog.vue";
import { useReCaptcha } from "vue-recaptcha-v3";
const slides = ref([]);
const email = ref(null);
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
const subscribeFormData = reactive({
email: {
value: "",
error: "",
rules: {
required: true,
required_message: "An email address is needed.",
email: true,
email_message: "That does not appear to be an email address.",
},
},
});
const formMessage = reactive({
message: "",
type: "error",
icon: "",
});
const formLoading = ref(false);
const handleLoad = async () => {
slides.value = [];
@@ -179,10 +221,34 @@ const handleLoad = async () => {
}
};
const handleSubscribe = () => {
console.log("form");
const handleSubscribe = async () => {
formLoading.value = true;
formMessage.icon = "";
formMessage.type = "error";
formMessage.message = "";
try {
if (isValidated(subscribeFormData)) {
await recaptchaLoaded();
const captcha = await executeRecaptcha("submit");
await axios.post("subscriptions", {
email: subscribeFormData.email.value,
captcha_token: captcha,
});
subscribeFormData.email.value = "";
formMessage.type = "success";
formMessage.message = "Your email address has been subscribed.";
}
} catch (err) {
restParseErrors(subscribeFormData, [formMessage, "message"], err);
}
formLoading.value = false;
};
useValidation(subscribeFormData);
handleLoad();
</script>

View File

@@ -0,0 +1,118 @@
<template>
<SMContainer>
<SMRow>
<SMDialog narrow :loading="formLoading">
<template v-if="!formDone">
<h1>Unsubscribe</h1>
<p>
If you would like to unsubscribe from our mailing list,
you have come to the right page!
</p>
<SMMessage
v-if="formMessage.message"
:type="formMessage.type"
:message="formMessage.message"
:icon="formMessage.icon" />
<form @submit.prevent="submit">
<SMInput
v-model="formData.email.value"
name="email"
label="Email"
required
:error="formData.email.error"
@blur="fieldValidate(formData.email)" />
<SMCaptchaNotice />
<SMFormFooter>
<template #right>
<SMButton type="submit" label="Unsubscribe" />
</template>
</SMFormFooter>
</form>
</template>
<template v-else>
<h1>Unsubscribed</h1>
<p class="text-center">
You have now been unsubscribed from our newsletter.
</p>
<SMRow class="pb-2">
<SMColumn class="justify-content-center">
<SMButton :to="{ name: 'home' }" label="Home" />
</SMColumn>
</SMRow>
</template>
</SMDialog>
</SMRow>
</SMContainer>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import SMInput from "../components/SMInput.vue";
import SMButton from "../components/SMButton.vue";
import SMFormFooter from "../components/SMFormFooter.vue";
import SMDialog from "../components/SMDialog.vue";
import SMMessage from "../components/SMMessage.vue";
import axios from "axios";
import { useRoute } from "vue-router";
import {
useValidation,
isValidated,
fieldValidate,
restParseErrors,
} from "../helpers/validation";
import SMCaptchaNotice from "../components/SMCaptchaNotice.vue";
import { useReCaptcha } from "vue-recaptcha-v3";
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
const formLoading = ref(false);
const formDone = ref(false);
const formMessage = reactive({
message: "",
type: "error",
icon: "",
});
const formData = reactive({
email: {
value: "",
error: "",
rules: {
required: true,
required_message: "An email address is required.",
email: true,
email_message: "That does not look like an email address.",
},
},
});
useValidation(formData);
const submit = async () => {
formLoading.value = true;
formMessage.type = "error";
formMessage.icon = "fa-solid fa-circle-exclamation";
formMessage.message = "";
try {
if (isValidated(formData)) {
await recaptchaLoaded();
const captcha = await executeRecaptcha("submit");
await axios.delete("subscriptions", {
email: formData.email.value,
captcha_token: captcha,
});
formDone.value = true;
}
} catch (err) {
restParseErrors(formData, [formMessage, "message"], err);
}
formLoading.value = false;
};
if (useRoute().query.email !== undefined) {
formData.email.value = useRoute().query.email;
submit();
}
</script>