Files
spritesheet-generator/src/components/FeedbackModal.vue
root 5c302277be - Added text to home page
- Added feedback form
2025-08-11 02:42:16 +02:00

104 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<Modal :is-open="isOpen" @close="close" title="Send feedback" :initialWidth="700" :initialHeight="520">
<form class="h-full flex flex-col" @submit.prevent="submit" novalidate>
<div class="flex-1 overflow-auto p-4 space-y-4 dark:bg-gray-800">
<p class="text-sm text-gray-600 dark:text-gray-300">Wed love to hear your thoughts. Only the fields below are required and will be sent securely.</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" for="fb-name">Name</label>
<input id="fb-name" v-model="name" type="text" class="w-full px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none" placeholder="Jane Doe" />
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" for="fb-contact">Contact</label>
<input id="fb-contact" v-model="contact" type="text" class="w-full px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none" placeholder="email, matrix, discord, etc." />
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" for="fb-content">Content</label>
<textarea
id="fb-content"
v-model="content"
rows="6"
class="w-full px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
placeholder="Describe your feedback here..."
required
></textarea>
</div>
<p v-if="error" class="text-sm text-red-600 dark:text-red-400">{{ error }}</p>
<p v-if="success" class="text-sm text-green-600 dark:text-green-400">{{ success }}</p>
</div>
<div class="border-t border-gray-200 dark:border-gray-700 p-3 flex justify-end gap-2">
<button type="button" class="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-100" @click="close" :disabled="loading">Close</button>
<button type="submit" class="px-4 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-60 disabled:cursor-not-allowed" :disabled="loading">
<span v-if="!loading">Send feedback</span>
<span v-else>Sending</span>
</button>
</div>
</form>
</Modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Modal from './utilities/Modal.vue';
const props = defineProps<{ isOpen: boolean }>();
const emit = defineEmits<{ (e: 'close'): void }>();
const name = ref('');
const contact = ref('');
const content = ref('');
const loading = ref(false);
const error = ref('');
const success = ref('');
const close = () => emit('close');
const submit = async () => {
error.value = '';
success.value = '';
if (!content.value.trim()) {
error.value = 'Please enter some feedback (content).';
return;
}
loading.value = true;
try {
const res = await fetch('https://pb1.adhd.sh/api/collections/feedback/records', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name.value || null,
contact: contact.value || null,
content: content.value,
}),
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(text || `Request failed with status ${res.status}`);
}
success.value = 'Thank you! Your feedback was sent.';
// Reset fields
name.value = '';
contact.value = '';
content.value = '';
// Optionally close after short delay
setTimeout(() => close(), 600);
} catch (e: any) {
console.error('Failed to send feedback:', e);
error.value = 'Failed to send feedback. Please try again later.';
} finally {
loading.value = false;
}
};
</script>