Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 41s
This commit updates the newsletter subscription component to display the user's email when logged in, improving user experience. It also adds logic to load the user's profile data upon authentication, ensuring that the email field is pre-filled for logged-in users. Additionally, the server-side subscription handler is modified to check user authentication status, allowing only logged-in users to subscribe to certain groups. This change enhances the overall subscription process and aligns it with user authentication state.
256 lines
7.1 KiB
Vue
256 lines
7.1 KiB
Vue
<template>
|
|
<div class="min-h-full py-16 bg-gray-50">
|
|
<div class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="bg-white rounded-xl shadow-lg p-8">
|
|
<h1 class="text-3xl font-display font-bold text-gray-900 mb-6">
|
|
Newsletter abonnieren
|
|
</h1>
|
|
<div class="w-24 h-1 bg-primary-600 mb-8" />
|
|
|
|
<div
|
|
v-if="loadingGroups"
|
|
class="text-center py-8"
|
|
>
|
|
<p class="text-gray-600">
|
|
Lade verfügbare Newsletter...
|
|
</p>
|
|
</div>
|
|
|
|
<form
|
|
v-else
|
|
class="space-y-6"
|
|
@submit.prevent="subscribe"
|
|
>
|
|
<div>
|
|
<label
|
|
for="groupId"
|
|
class="block text-sm font-medium text-gray-700 mb-2"
|
|
>
|
|
Newsletter auswählen *
|
|
</label>
|
|
<select
|
|
id="groupId"
|
|
v-model="form.groupId"
|
|
required
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
|
@change="checkSubscription"
|
|
>
|
|
<option value="">
|
|
Bitte wählen Sie einen Newsletter
|
|
</option>
|
|
<option
|
|
v-for="group in groups"
|
|
:key="group.id"
|
|
:value="group.id"
|
|
>
|
|
{{ group.name }}
|
|
</option>
|
|
</select>
|
|
<p
|
|
v-if="selectedGroup?.description"
|
|
class="mt-2 text-sm text-gray-600"
|
|
>
|
|
{{ selectedGroup.description }}
|
|
</p>
|
|
<div
|
|
v-if="alreadySubscribed"
|
|
class="mt-2 p-3 bg-blue-50 border border-blue-200 rounded-lg"
|
|
>
|
|
<p class="text-sm text-blue-700">
|
|
✓ Sie sind bereits für diesen Newsletter angemeldet.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
for="email"
|
|
class="block text-sm font-medium text-gray-700 mb-2"
|
|
>
|
|
E-Mail-Adresse *
|
|
</label>
|
|
<input
|
|
id="email"
|
|
v-model="form.email"
|
|
type="email"
|
|
required
|
|
:readonly="isLoggedIn"
|
|
:class="[
|
|
'w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500',
|
|
isLoggedIn ? 'bg-gray-100 border-gray-300 cursor-not-allowed' : 'border-gray-300'
|
|
]"
|
|
placeholder="ihre.email@example.com"
|
|
@blur="checkSubscription"
|
|
>
|
|
<p
|
|
v-if="isLoggedIn"
|
|
class="mt-1 text-xs text-gray-500"
|
|
>
|
|
Ihre E-Mail-Adresse wird aus Ihrem Profil verwendet.
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
for="name"
|
|
class="block text-sm font-medium text-gray-700 mb-2"
|
|
>
|
|
Name (optional)
|
|
</label>
|
|
<input
|
|
id="name"
|
|
v-model="form.name"
|
|
type="text"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
|
placeholder="Ihr Name"
|
|
>
|
|
</div>
|
|
|
|
<div
|
|
v-if="error"
|
|
class="p-4 bg-red-50 border border-red-200 rounded-lg text-red-700"
|
|
>
|
|
{{ error }}
|
|
</div>
|
|
|
|
<div
|
|
v-if="success"
|
|
class="p-4 bg-green-50 border border-green-200 rounded-lg text-green-700"
|
|
>
|
|
{{ success }}
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
:disabled="loading || alreadySubscribed || !form.groupId"
|
|
class="w-full px-6 py-3 bg-primary-600 text-white font-semibold rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
>
|
|
{{ loading ? 'Wird verarbeitet...' : alreadySubscribed ? 'Bereits abonniert' : 'Newsletter abonnieren' }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue'
|
|
import { useAuthStore } from '~/stores/auth'
|
|
|
|
useHead({
|
|
title: 'Newsletter abonnieren - Harheimer TC',
|
|
})
|
|
|
|
const authStore = useAuthStore()
|
|
const groups = ref([])
|
|
const loadingGroups = ref(true)
|
|
const loadingProfile = ref(false)
|
|
const form = ref({
|
|
groupId: '',
|
|
email: '',
|
|
name: ''
|
|
})
|
|
|
|
const loading = ref(false)
|
|
const checking = ref(false)
|
|
const error = ref('')
|
|
const success = ref('')
|
|
const alreadySubscribed = ref(false)
|
|
|
|
const selectedGroup = computed(() => {
|
|
return groups.value.find(g => g.id === form.value.groupId)
|
|
})
|
|
|
|
const isLoggedIn = computed(() => authStore.isLoggedIn)
|
|
const userEmail = computed(() => authStore.user?.email || '')
|
|
const userName = computed(() => authStore.user?.name || '')
|
|
|
|
async function loadGroups() {
|
|
try {
|
|
const response = await $fetch('/api/newsletter/groups/public-list')
|
|
groups.value = response.groups || []
|
|
} catch (err) {
|
|
console.error('Fehler beim Laden der Newsletter-Gruppen:', err)
|
|
error.value = 'Fehler beim Laden der verfügbaren Newsletter. Bitte versuchen Sie es später erneut.'
|
|
} finally {
|
|
loadingGroups.value = false
|
|
}
|
|
}
|
|
|
|
async function loadProfile() {
|
|
if (!isLoggedIn.value) {
|
|
return
|
|
}
|
|
|
|
loadingProfile.value = true
|
|
try {
|
|
const response = await $fetch('/api/profile')
|
|
if (response.success && response.user) {
|
|
form.value.email = response.user.email || ''
|
|
form.value.name = response.user.name || ''
|
|
}
|
|
} catch (err) {
|
|
console.error('Fehler beim Laden des Profils:', err)
|
|
} finally {
|
|
loadingProfile.value = false
|
|
}
|
|
}
|
|
|
|
async function checkSubscription() {
|
|
if (!form.value.groupId || !form.value.email || !form.value.email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
|
|
alreadySubscribed.value = false
|
|
return
|
|
}
|
|
|
|
checking.value = true
|
|
try {
|
|
const response = await $fetch('/api/newsletter/check-subscription', {
|
|
query: {
|
|
email: form.value.email,
|
|
groupId: form.value.groupId
|
|
}
|
|
})
|
|
alreadySubscribed.value = response.subscribed || false
|
|
} catch (_err) {
|
|
// Fehler ignorieren - könnte bedeuten, dass nicht abonniert ist
|
|
alreadySubscribed.value = false
|
|
} finally {
|
|
checking.value = false
|
|
}
|
|
}
|
|
|
|
async function subscribe() {
|
|
if (alreadySubscribed.value) {
|
|
return
|
|
}
|
|
|
|
loading.value = true
|
|
error.value = ''
|
|
success.value = ''
|
|
|
|
try {
|
|
const response = await $fetch('/api/newsletter/subscribe', {
|
|
method: 'POST',
|
|
body: form.value
|
|
})
|
|
|
|
success.value = response.message || 'Eine Bestätigungsmail wurde an Ihre E-Mail-Adresse gesendet.'
|
|
form.value = { groupId: form.value.groupId, email: '', name: '' }
|
|
alreadySubscribed.value = false
|
|
} catch (err) {
|
|
error.value = err.data?.statusMessage || err.message || 'Fehler bei der Anmeldung. Bitte versuchen Sie es später erneut.'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await authStore.checkAuth()
|
|
await loadGroups()
|
|
if (isLoggedIn.value) {
|
|
await loadProfile()
|
|
}
|
|
})
|
|
</script>
|
|
|