update feedback form, tambahan lib untuk star rating

This commit is contained in:
2025-06-06 11:45:34 +08:00
parent f568b365c7
commit 7d8a08770e
3 changed files with 154 additions and 12 deletions

24
src/lib/StarRating.svelte Normal file
View File

@@ -0,0 +1,24 @@
<script>
export let value = 0;
export let name = '';
export let size = 'base'; // 'base', 'lg', 'xl'
let sizeClass = {
base: 'text-2xl',
lg: 'text-3xl',
xl: 'text-4xl'
}[size] || 'text-2xl';
</script>
<div class="flex items-center gap-1">
{#each Array(5) as _, i}
<button
type="button"
class={`focus:outline-none ${sizeClass}`}
on:click={() => value = i + 1}
aria-label="{name} {i + 1} stars"
>
<span class={i < value ? 'text-yellow-400' : 'text-gray-300'}>★</span>
</button>
{/each}
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,6 +1,8 @@
<script>
import { supabase } from '$lib/supabaseClient';
import StarRating from '$lib/StarRating.svelte';
import villaBugisImage from '$lib/images/villa-bugis.png';
let villa_name = '';
let customer_name = '';
let checkin_date = '';
@@ -8,11 +10,23 @@
let feedback = '';
let errorMessage = '';
// Star ratings (1-5)
let book_process = 0;
let airport_greet = 0;
let arrival_greet = 0;
let bf_service = 0;
let overal_star = 0;
// Boolean checkboxes
let extend_disc = false;
let nextstay_disc = false;
let become_sponsor = false;
async function handleSubmit() {
errorMessage = '';
if (!villa_name.trim() || !customer_name.trim() || !feedback.trim()) {
errorMessage = 'Villa name, customer name, and feedback are required.';
errorMessage = 'Villa, Name, and feedback are required.';
return;
}
@@ -21,6 +35,8 @@
return;
}
const user = (await supabase.auth.getUser()).data.user;
const { data, error } = await supabase
.from('vb_feedback')
.insert([{
@@ -28,36 +44,138 @@
customer_name,
checkin_date,
checkout_date,
feedback
feedback,
book_process,
airport_greet,
arrival_greet,
bf_service,
overal_star,
extend_disc,
nextstay_disc,
become_sponsor
}]);
if (error) {
console.error('Error submitting feedback:', error.message);
errorMessage = 'Failed to submit feedback. Please try again.';
} else {
console.log('Feedback submitted:', data);
// Reset form
villa_name = '';
customer_name = '';
checkin_date = '';
checkout_date = '';
feedback = '';
book_process = 0;
airport_greet = 0;
arrival_greet = 0;
bf_service = 0;
overal_star = 0;
extend_disc = false;
nextstay_disc = false;
become_sponsor = false;
alert("Feedback submitted successfully!");
}
}
</script>
<h1 class="text-3xl font-bold text-center my-6">Feedback Form</h1>
<div class="max-w-xl mx-auto px-4">
<div class="flex justify-between items-center p-4">
<div class="w-1/3 flex justify-start">
<img
src="https://api.qrserver.com/v1/create-qr-code/?data=https%3A%2F%2Fvillabugis.com&size=200x200"
alt="Villa Bugis QR Code"
class="h-24 w-24 object-contain"
/>
</div>
<div class="w-1/3 text-center">
<h1 class="text-3xl font-bold text-green-800 leading-snug">
Guest<br />Feedback<br />Form
</h1>
</div>
<div class="w-1/3 flex justify-end">
<img src={villaBugisImage} alt="Villa Bugis Logo" class="h-24 w-auto" />
</div>
</div>
</div>
<form on:submit|preventDefault={handleSubmit} class="flex flex-col gap-4 max-w-xl mx-auto p-6 bg-white rounded-xl shadow-md">
<form on:submit|preventDefault={handleSubmit} class="flex flex-col gap-4 max-w-md mx-auto p-6 bg-white rounded-xl shadow-md">
{#if errorMessage}
<div class="text-red-600 font-semibold">{errorMessage}</div>
{/if}
<label for="fb_villaname" class="flex flex-col">Villa Name</label>
<input id="fb_villaname" type="text" bind:value={villa_name} placeholder="Villa Name" required class="p-2 border rounded-md" />
<label for="fb_gn" class="flex flex-col">Name</label>
<input id="fb_gn" type="text" bind:value={customer_name} placeholder="Customer Name" required class="p-2 border rounded-md" />
<label for="fb_cid" class="flex flex-col">Checkin Date</label>
<input id="fb_cid" type="date" bind:value={checkin_date} required class="p-2 border rounded-md" />
<label for="fb_cod" class="flex flex-col">Checkout Date</label>
<input id="fb_cod" type="date" bind:value={checkout_date} required class="p-2 border rounded-md" />
<!-- Star Ratings -->
<label class="flex flex-col">
Booking Process:
<small class="text-sm text-gray-500 mb-1">Please highlights of the booking process (anything neglected by the staff or something done well by the staff)</small>
<StarRating bind:value={book_process} name="Booking Process" />
</label>
<input type="text" bind:value={villa_name} placeholder="Villa Name" class="p-2 border rounded-md" required />
<input type="text" bind:value={customer_name} placeholder="Customer Name" class="p-2 border rounded-md" required />
<input type="date" bind:value={checkin_date} class="p-2 border rounded-md" required />
<input type="date" bind:value={checkout_date} class="p-2 border rounded-md" required />
<textarea bind:value={feedback} placeholder="Write your feedback here..." class="p-2 border rounded-md min-h-[120px]" required></textarea>
<button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">Submit Feedback</button>
<label class="flex flex-col">
Airport Greeting and Transportation:
<small class="text-sm text-gray-500 mb-1">Please highlights of the airport transfer experience (anything neglected by the staff or something done well by the staff)</small>
<StarRating bind:value={airport_greet} name="Airport Greeting" />
</label>
<label class="flex flex-col">
Arrival & Check-in:
<small class="text-sm text-gray-500 mb-1">Please highlights of the arrival and check-in process(anything neglected by the staff or something done well by the staff)</small>
<StarRating bind:value={arrival_greet} name="Arrival Greeting" />
</label>
<label class="flex flex-col">
Breakfast Service or other food and beverage service utilized:
<small class="text-sm text-gray-500 mb-1">Please highlighs of the breakfast service(anything neglected by the staff or something done well by the staff)</small>
<StarRating bind:value={bf_service} name="Breakfast Service" />
</label>
<label for="fb_ov">What did you think of the villa in General</label>
<small class="text-sm text-gray-500 mb-1">Did you have any other issue of area you would like to highligh during stay? Please let us know any other comments you have - the good, the bad, and the ugly</small>
<textarea id="fb_ov" bind:value={feedback} placeholder="Write your feedback here..." required class="p-2 border rounded-md min-h-[120px]"></textarea>
<!-- Centered big star-->
<div class="text-center mt-6">
<small class="text-sm text-gray-500 block mb-2">
Overall Stay Please rate your overall stay. 5 stars = a great stay!<br />
We aim to provide 5-star services to you!
</small>
<div class="flex justify-center">
<StarRating bind:value={overal_star} name="Overall Satisfaction" size="xl" />
</div>
</div>
<!-- Checkboxes -->
<label class="flex flex-col">
<span class="flex items-center gap-2">
<input type="checkbox" bind:checked={extend_disc} />
<small class="text-sm text-gray-500 mb-1">I would like to discuss extending my stay for 30% off!</small>
</span>
</label>
<label class="flex flex-col">
<span class="flex items-center gap-2">
<input type="checkbox" bind:checked={nextstay_disc} />
<small class="text-sm text-gray-500 mb-1">I would like to discuss booking my next stayto receive an extra discount!</small>
</span>
</label>
<label class="flex flex-col">
<span class="flex items-center gap-2">
<input type="checkbox" bind:checked={become_sponsor} />
<small class="text-sm text-gray-500 mb-1">I would like to know more about sponsoring a Balinese child with Damara (for only AU$150 a year!)(100% of the AU$150 goes to the childs schooling - there are no overheads with Damara!)</small>
</span>
</label>
<!-- Submit Button -->
<button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">
Submit Feedback
</button>
</form>