This commit is contained in:
2021-07-08 17:15:02 +02:00
parent 33248653a4
commit 02daf1485f
7 changed files with 182 additions and 6 deletions

View File

@@ -14,9 +14,10 @@
</div>
</div>
<div class="my-3">
<form v-if="!success" class="relative right-0 top-0">
<form v-if="!success" class="relative">
<input
required
type="text"
:placeholder="$t('guestbook.placeholder')"
v-model="form.message"
class="pl-4 pr-32 py-2 mt-1 block w-full border-gray-300 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
@@ -24,7 +25,7 @@
<button
@click.prevent="handleForm"
v-if="form.message && form.message.length > 0"
class="flex items-center justify-center absolute right-1 top-1 px-8 py-1 font-bold bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded hover:bg-gray-300 duration-300"
class="button flex items-center justify-center px-8 py-1 font-bold bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded hover:bg-gray-300 duration-300"
>
{{ $t('guestbook.sign') }}
</button>
@@ -138,4 +139,9 @@ export default defineComponent({
.icon-parent:hover svg {
@apply transform scale-110;
}
.button {
position: absolute;
top: 0.25rem;
right: 0.25rem;
}
</style>

View File

@@ -15,7 +15,8 @@ export default {
projects: 'My projects',
contact: 'Contact me',
env: 'My environment',
guestbook: 'My guestbook'
guestbook: 'My guestbook',
newsletter: 'My newsletter'
},
footer: {
@@ -200,6 +201,20 @@ export default {
success: 'Thank you for your message 😉'
},
newsletter: {
description: 'My newsletter provides a behind-the-scenes look into what I\'m working on and writing about. I frequently share some of my favorite articles I\'ve read, as well as anything fascinating about technology.',
title: 'Subscribe to my newsletter',
subtitle: 'Get emails from me about web development, tech, and early access to new articles.',
placeholder: 'elon@tesla.com',
subscribe: 'Subscribe',
error: 'Error during your subscription ❌',
success: 'Thank you for your subscription 😉',
count: '{count} subscriber(s)',
infos: 'Your information is only used to receive new emails from me.',
no_spam: 'No spam.',
exist: "The email address is already subscribed 👍"
},
date: {
today: 'Today'
},

View File

@@ -15,7 +15,8 @@ export default {
projects: 'Mes projets',
blog: 'Mon blog',
env: 'Mon environnement',
guestbook: "Mon livre d'or"
guestbook: "Mon livre d'or",
newsletter: 'Ma newsletter'
},
footer: {
@@ -200,6 +201,20 @@ export default {
success: 'Merci pour votre message 😉'
},
newsletter: {
description: 'Ma newsletter fournit un aperçu des coulisses de ce sur quoi je travaille et sur quoi j\'écris. Je partage fréquemment certains de mes articles préférés que j\'ai lus, ainsi que tout ce qui est fascinant sur la technologie.',
title: 'Abonnez-vous à ma newsletter',
subtitle: "Recevez des e-mails de ma part sur le développement Web, la technologie et l'accès anticipé aux nouveaux articles.",
placeholder: 'elon@tesla.com',
subscribe: "S'abonner",
error: "Erreur lors de votre abonnement ❌",
success: 'Merci pour votre abonnement 😉',
count: '{count} abonné(s)',
infos: 'Vos informations ne sont utilisées uniquement pour recevoir de nouveaux mails de ma part.',
no_spam: 'Pas de spam.',
exist: "L'adresse email est déjà abonnée 👍"
},
date: {
today: "Aujourd'hui"
},

View File

@@ -145,6 +145,7 @@ export default defineComponent({
likes.value = response.data.likes
}).catch((error) => {
$sentry.captureEvent(error)
app.error({statusCode: 500})
})
})
@@ -161,6 +162,7 @@ export default defineComponent({
$storage.removeCookie(`${slug.value}`)
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
} else {
const response = await $axios.post(`/posts/${post.value?.slug}/like`, {}, {
@@ -176,6 +178,7 @@ export default defineComponent({
})
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
}
}

View File

@@ -30,7 +30,7 @@ export default defineComponent({
}
},
setup() {
const { $axios, $sentry } = useContext()
const { $axios, $sentry, app } = useContext()
const guestbook_messages = ref([])
useAsync(async () => {
@@ -43,6 +43,7 @@ export default defineComponent({
guestbook_messages.value = response.data.guestbook_messages
})
.catch(error => {
app.error({statusCode: 500})
$sentry.captureEvent(error)
})
})

132
src/pages/newsletter.vue Normal file
View File

@@ -0,0 +1,132 @@
<template>
<main class="flex flex-col mb-12 px-4 xl:px-64">
<PageTitle class="self-center" title="part.newsletter"/>
<section class="flex flex-col 2xl:flex-row items-center py-8">
<div class="ml-2 text-lg leading-6 text-justify dark:text-gray-400 text-gray-700">
<p>{{ $t('newsletter.description') }}</p>
</div>
</section>
<section class="p-6 border border-indigo-600 dark:border-indigo-700 rounded-lg text-justify">
<h1 class="text-black font-bold dark:text-white text-2xl">{{ $t('newsletter.title') }}</h1>
<h3 class="text-gray-500 dark:text-gray-400">{{ $t('newsletter.subtitle') }}</h3>
<div class="my-3">
<form v-if="!success && !exist" class="relative">
<input
required
type="email"
:placeholder="$t('newsletter.placeholder')"
v-model="form.email"
class="pl-4 pr-32 py-2 mt-1 block w-full border-gray-300 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
>
<button
@click.prevent="handleForm"
v-if="form.email && form.email.length > 0"
class="button flex items-center justify-center px-8 py-1 font-bold bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded hover:bg-gray-300 duration-300"
>
{{ $t('newsletter.subscribe') }}
</button>
</form>
<div class="flex">
<div v-if="error" class="py-1 text-red-400 text-sm">
{{ $t('newsletter.error') }}
</div>
</div>
<div class="flex">
<div v-if="success" class="py-1 text-green-400 text-sm">
{{ $t('newsletter.success') }}
</div>
</div>
<div class="flex">
<div v-if="exist" class="py-1 text-green-400 text-sm">
{{ $t('newsletter.exist') }}
</div>
</div>
</div>
<p class="text-sm text-gray-700 dark:text-gray-300">{{ $t('newsletter.count', { count: subscribersCount }) }}</p>
<p class="text-sm text-gray-700 dark:text-gray-300">{{ $t('newsletter.infos') }} <strong>{{ $t('newsletter.no_spam') }}</strong></p>
</section>
</main>
</template>
<script lang="ts">
import {defineComponent, ref, useAsync, useContext} from "@nuxtjs/composition-api";
import {NewsletterForm} from "~/types/types";
export default defineComponent({
name: "newsletter",
head() {
return {
title: `${this.$i18n.t('header.newsletter')} - Arthur Danjou`
}
},
setup() {
const { $axios, $sentry, app } = useContext()
const subscribersCount = ref(0)
useAsync(() => {
$axios.get('/subscribers', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`,
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.status === 200) {
subscribersCount.value = response.data.count
}
}).catch((error) => {
$sentry.captureEvent(error)
app.error({statusCode: 500})
})
})
const error = ref(false)
const success = ref(false)
const exist = ref(false)
const form = ref<NewsletterForm>({} as NewsletterForm)
const handleForm = () => {
$axios.post('/subscribers', {
email: form.value.email
}, {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
}).then((response) => {
if (response.status === 200) {
form.value.email = ''
success.value = true
} else if (response.status === 201) {
form.value.email = ""
exist.value = true
} else {
$sentry.captureEvent(response.data)
error.value = true
setTimeout(() => {
error.value = false
}, 5000)
}
}).catch(error => {
$sentry.captureEvent(error)
})
}
return {
subscribersCount,
error,
success,
form,
handleForm,
exist
}
}
})
</script>
<style scoped>
.button {
position: absolute;
top: 0.25rem;
right: 0.25rem;
}
</style>

View File

@@ -65,4 +65,8 @@ interface GuestbookForm {
message: string
}
export { Form, InfoData, Skill, Experience, Formation, Post, Tag, Project, GuestbookForm }
interface NewsletterForm {
email: string
}
export { Form, InfoData, Skill, Experience, Formation, Post, Tag, Project, GuestbookForm, NewsletterForm }