add webhook
This commit is contained in:
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
type Projects = {
|
type Projects = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
|
||||||
priority: string;
|
priority: string;
|
||||||
add_to_po: boolean;
|
add_to_po: boolean;
|
||||||
description_of_the_issue: string;
|
description_of_the_issue: string;
|
||||||
@@ -49,10 +48,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const columns: columns[] = [
|
const columns: columns[] = [
|
||||||
{ key: "name", title: "Project Name" },
|
{ key: "description_of_the_issue", title: "Issue Description" },
|
||||||
|
{ key: "project_number", title: "Project Number" },
|
||||||
{ key: "priority", title: "Priority" },
|
{ key: "priority", title: "Priority" },
|
||||||
{ key: "add_to_po", title: "Add to PO" },
|
{ key: "add_to_po", title: "Add to PO" },
|
||||||
{ key: "description_of_the_issue", title: "Description" },
|
|
||||||
{ key: "picture_link", title: "Picture Link" },
|
{ key: "picture_link", title: "Picture Link" },
|
||||||
{ key: "need_approval", title: "Need Approval" },
|
{ key: "need_approval", title: "Need Approval" },
|
||||||
{ key: "area_of_villa", title: "Area of Villa" },
|
{ key: "area_of_villa", title: "Area of Villa" },
|
||||||
@@ -61,7 +60,6 @@
|
|||||||
{ key: "villa_name", title: "Villa Name" },
|
{ key: "villa_name", title: "Villa Name" },
|
||||||
{ key: "report_date", title: "Report Date" },
|
{ key: "report_date", title: "Report Date" },
|
||||||
{ key: "project_due_date", title: "Project Due Date" },
|
{ key: "project_due_date", title: "Project Due Date" },
|
||||||
{ key: "project_number", title: "Project Number" },
|
|
||||||
{ key: "updated_at", title: "Updated At" },
|
{ key: "updated_at", title: "Updated At" },
|
||||||
{ key: "updated_name", title: "Updated By" },
|
{ key: "updated_name", title: "Updated By" },
|
||||||
{ key: "actions", title: "Actions" },
|
{ key: "actions", title: "Actions" },
|
||||||
@@ -109,7 +107,7 @@
|
|||||||
}
|
}
|
||||||
// Apply search term if provided
|
// Apply search term if provided
|
||||||
if (searchTerm) {
|
if (searchTerm) {
|
||||||
query = query.ilike("issue_name", `%${searchTerm}%`);
|
query = query.ilike("description_of_the_issue", `%${searchTerm}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch projects
|
// Fetch projects
|
||||||
@@ -143,12 +141,9 @@
|
|||||||
return {
|
return {
|
||||||
...project,
|
...project,
|
||||||
id: project.id,
|
id: project.id,
|
||||||
name: issue ? issue.name : "Unknown",
|
description_of_the_issue: issue ? issue.description_of_the_issue : "Unknown",
|
||||||
priority: issue ? issue.priority : "Unknown",
|
priority: issue ? issue.priority : "Unknown",
|
||||||
add_to_po: project.add_to_po,
|
add_to_po: project.add_to_po,
|
||||||
description_of_the_issue: issue
|
|
||||||
? issue.description_of_the_issue
|
|
||||||
: "No description",
|
|
||||||
picture_link: project.picture_link,
|
picture_link: project.picture_link,
|
||||||
need_approval: issue ? issue.need_approval : false,
|
need_approval: issue ? issue.need_approval : false,
|
||||||
area_of_villa: issue ? issue.area_of_villa : "Unknown",
|
area_of_villa: issue ? issue.area_of_villa : "Unknown",
|
||||||
@@ -185,7 +180,6 @@
|
|||||||
"issue_id",
|
"issue_id",
|
||||||
"number_project",
|
"number_project",
|
||||||
"input_by",
|
"input_by",
|
||||||
"name",
|
|
||||||
"priority",
|
"priority",
|
||||||
"description_of_the_issue",
|
"description_of_the_issue",
|
||||||
"need_approval",
|
"need_approval",
|
||||||
@@ -256,7 +250,7 @@
|
|||||||
async function fetchIssueIds() {
|
async function fetchIssueIds() {
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from("vb_issues")
|
.from("vb_issues")
|
||||||
.select("id, name")
|
.select("id, description_of_the_issue")
|
||||||
.order("id", { ascending: false });
|
.order("id", { ascending: false });
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -266,7 +260,7 @@
|
|||||||
|
|
||||||
dataIssueIds = data.map((issue) => ({
|
dataIssueIds = data.map((issue) => ({
|
||||||
id: issue.id,
|
id: issue.id,
|
||||||
name: issue.name,
|
description_of_the_issue: issue.description_of_the_issue,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +467,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value="">Filter by Priority</option>
|
<option value="">Filter by Priority</option>
|
||||||
|
<option value="High">Critical</option>
|
||||||
<option value="High">High</option>
|
<option value="High">High</option>
|
||||||
<option value="Medium">Medium</option>
|
<option value="Medium">Medium</option>
|
||||||
<option value="Low">Low</option>
|
<option value="Low">Low</option>
|
||||||
@@ -484,12 +479,6 @@
|
|||||||
>
|
>
|
||||||
🔄 Reset
|
🔄 Reset
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
|
|
||||||
on:click={() => openModal()}
|
|
||||||
>
|
|
||||||
➕ Add Project
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-x-auto rounded-lg shadow mb-4">
|
<div class="overflow-x-auto rounded-lg shadow mb-4">
|
||||||
@@ -497,7 +486,7 @@
|
|||||||
<thead class="bg-gray-100">
|
<thead class="bg-gray-100">
|
||||||
<tr>
|
<tr>
|
||||||
{#each columns as col}
|
{#each columns as col}
|
||||||
{#if col.key === "name"}
|
{#if col.key === "description_of_the_issue"}
|
||||||
<th
|
<th
|
||||||
class="sticky left-0 px-4 py-3 text-left font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap"
|
class="sticky left-0 px-4 py-3 text-left font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap"
|
||||||
style="background-color: #f0f8ff; z-index: 10;"
|
style="background-color: #f0f8ff; z-index: 10;"
|
||||||
@@ -518,7 +507,7 @@
|
|||||||
{#each paginatedRows as row}
|
{#each paginatedRows as row}
|
||||||
<tr class="hover:bg-gray-50 transition">
|
<tr class="hover:bg-gray-50 transition">
|
||||||
{#each columns as col}
|
{#each columns as col}
|
||||||
{#if col.key === "name"}
|
{#if col.key === "description_of_the_issue"}
|
||||||
<td
|
<td
|
||||||
class="sticky left-0 px-4 py-2 font-medium text-blue-600"
|
class="sticky left-0 px-4 py-2 font-medium text-blue-600"
|
||||||
style="background-color: #f0f8ff; cursor: pointer;"
|
style="background-color: #f0f8ff; cursor: pointer;"
|
||||||
@@ -802,7 +791,7 @@
|
|||||||
>
|
>
|
||||||
<option value="" disabled selected>Select Issue</option>
|
<option value="" disabled selected>Select Issue</option>
|
||||||
{#each dataIssueIds as issueId}
|
{#each dataIssueIds as issueId}
|
||||||
<option value={issueId.id}>{issueId.name}</option>
|
<option value={issueId.id}>{issueId.description_of_the_issue}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { supabase } from "$lib/supabaseClient";
|
import { supabase } from "$lib/supabaseClient";
|
||||||
|
import { onMount } from "svelte";
|
||||||
import StarRating from "$lib/StarRating.svelte";
|
import StarRating from "$lib/StarRating.svelte";
|
||||||
import villaBugisImage from "$lib/images/villa-bugis.png";
|
import villaBugisImage from "$lib/images/villa-bugis.png";
|
||||||
|
|
||||||
@@ -25,6 +26,23 @@
|
|||||||
let nextstay_disc = false;
|
let nextstay_disc = false;
|
||||||
let become_sponsor = false;
|
let become_sponsor = false;
|
||||||
|
|
||||||
|
let villaOptions = [];
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.from("vb_villas")
|
||||||
|
.select("villa_name")
|
||||||
|
.eq("villa_status", "Active")
|
||||||
|
.order("villa_name", { ascending: true });
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error("Failed to load villa names:", error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
villaOptions = data.map((v) => v.villa_name);
|
||||||
|
});
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
errorMessage = "";
|
errorMessage = "";
|
||||||
|
|
||||||
@@ -40,7 +58,9 @@
|
|||||||
|
|
||||||
const user = (await supabase.auth.getUser()).data.user;
|
const user = (await supabase.auth.getUser()).data.user;
|
||||||
|
|
||||||
const { data, error } = await supabase.from("vb_feedback").insert([
|
const { data, error } = await supabase
|
||||||
|
.from("vb_feedback")
|
||||||
|
.insert([
|
||||||
{
|
{
|
||||||
villa_name,
|
villa_name,
|
||||||
customer_name,
|
customer_name,
|
||||||
@@ -57,7 +77,9 @@
|
|||||||
nextstay_disc,
|
nextstay_disc,
|
||||||
become_sponsor,
|
become_sponsor,
|
||||||
},
|
},
|
||||||
]);
|
])
|
||||||
|
.select()
|
||||||
|
.single();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("Error submitting feedback:", error.message);
|
console.error("Error submitting feedback:", error.message);
|
||||||
@@ -67,22 +89,7 @@
|
|||||||
await fetch(WEBHOOK_URL, {
|
await fetch(WEBHOOK_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify(data),
|
||||||
villa_name,
|
|
||||||
customer_name,
|
|
||||||
checkin_date,
|
|
||||||
checkout_date,
|
|
||||||
feedback,
|
|
||||||
book_process,
|
|
||||||
airport_greet,
|
|
||||||
arrival_greet,
|
|
||||||
maintenance_proc,
|
|
||||||
bf_service,
|
|
||||||
overal_star,
|
|
||||||
extend_disc,
|
|
||||||
nextstay_disc,
|
|
||||||
become_sponsor,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
} catch (webhookError) {
|
} catch (webhookError) {
|
||||||
console.error("Webhook failed:", webhookError);
|
console.error("Webhook failed:", webhookError);
|
||||||
@@ -137,14 +144,17 @@
|
|||||||
<div class="text-red-600 font-semibold">{errorMessage}</div>
|
<div class="text-red-600 font-semibold">{errorMessage}</div>
|
||||||
{/if}
|
{/if}
|
||||||
<label for="fb_villaname" class="flex flex-col">Villa Name</label>
|
<label for="fb_villaname" class="flex flex-col">Villa Name</label>
|
||||||
<input
|
<select
|
||||||
id="fb_villaname"
|
id="fb_villaname"
|
||||||
type="text"
|
|
||||||
bind:value={villa_name}
|
bind:value={villa_name}
|
||||||
placeholder="Villa Name"
|
|
||||||
required
|
required
|
||||||
class="p-2 border rounded-md"
|
class="p-2 border rounded-md"
|
||||||
/>
|
>
|
||||||
|
<option value="" disabled selected>Select a Villa</option>
|
||||||
|
{#each villaOptions as name}
|
||||||
|
<option value={name}>{name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
<label for="fb_gn" class="flex flex-col">Name</label>
|
<label for="fb_gn" class="flex flex-col">Name</label>
|
||||||
<input
|
<input
|
||||||
id="fb_gn"
|
id="fb_gn"
|
||||||
|
|||||||
Reference in New Issue
Block a user