feat: add RPC for public lead creation and update migrations in docker-compose files
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
+26
-18
@@ -48,10 +48,12 @@ const bpfPhone = document.querySelector("#bpfPhone");
|
||||
const bpfMessage = document.querySelector("#bpfMessage");
|
||||
const bpfFileId = document.querySelector("#bpfFileId");
|
||||
const bpfFileIncome = document.querySelector("#bpfFileIncome");
|
||||
const bpfSubmitBtn = document.querySelector("#bpfSubmit");
|
||||
const bpfSidebar = document.querySelector("#bpfSidebar");
|
||||
const bpfSidebarContent = document.querySelector("#bpfSidebarContent");
|
||||
const bpfSidebarPlaceholder = document.querySelector(".bpf-sidebar-placeholder");
|
||||
let bpfDurationMode = "custom"; // "day" | "weekend" | "custom"
|
||||
let bpfSubmitting = false;
|
||||
|
||||
function formatYmdLocal(d) {
|
||||
const y = d.getFullYear();
|
||||
@@ -220,21 +222,20 @@ function openDetails(id) {
|
||||
|
||||
// ---------------- Reviews ----------------
|
||||
function renderReviews() {
|
||||
const list = REVIEWS[getLang()];
|
||||
state.reviewIdx = state.reviewIdx % list.length;
|
||||
const r = list[state.reviewIdx];
|
||||
state.reviewIdx = state.reviewIdx % REVIEWS.length;
|
||||
const r = REVIEWS[state.reviewIdx];
|
||||
reviewStrip.innerHTML = `
|
||||
<p class="review-quote">"${escapeHtml(r.quote)}"</p>
|
||||
<p class="review-author">${escapeHtml(r.author)}</p>
|
||||
`;
|
||||
reviewDots.innerHTML = list.map((_, i) =>
|
||||
reviewDots.innerHTML = REVIEWS.map((_, i) =>
|
||||
`<button class="${i === state.reviewIdx ? 'active' : ''}" data-rev="${i}" aria-label="${t("review")} ${i + 1}"></button>`
|
||||
).join("");
|
||||
reviewDots.querySelectorAll("button").forEach(b => {
|
||||
b.addEventListener("click", () => { state.reviewIdx = +b.dataset.rev; renderReviews(); });
|
||||
});
|
||||
}
|
||||
setInterval(() => { state.reviewIdx++; renderReviews(); }, 6000);
|
||||
setInterval(() => { state.reviewIdx++; renderReviews(); }, 5000);
|
||||
|
||||
// ---------------- BPF WIZARD ----------------
|
||||
const bpfStepPanels = [
|
||||
@@ -402,38 +403,43 @@ bpfTo.addEventListener("change", updateSidebar);
|
||||
|
||||
// Submit BPF
|
||||
document.querySelector("#bpfSubmit").addEventListener("click", async () => {
|
||||
if (bpfSubmitting) return;
|
||||
bpfSubmitting = true;
|
||||
if (bpfSubmitBtn) bpfSubmitBtn.disabled = true;
|
||||
bookingFeedback.className = "form-feedback";
|
||||
bookingFeedback.textContent = "...";
|
||||
|
||||
const vehicle = state.vehicles.find(v => v.id === bpfCar.value);
|
||||
const payload = {
|
||||
name: bpfName.value,
|
||||
email: bpfEmail.value,
|
||||
phone: bpfPhone.value || "",
|
||||
vehicle_id: bpfCar.value || null,
|
||||
vehicle_label: vehicle ? `${vehicle.brand} ${vehicle.model}` : "",
|
||||
date_from: bpfFrom.value || null,
|
||||
date_to: bpfTo.value || null,
|
||||
message: bpfMessage.value || "",
|
||||
source: "website",
|
||||
p_name: bpfName.value,
|
||||
p_email: bpfEmail.value,
|
||||
p_phone: bpfPhone.value || "",
|
||||
p_vehicle_id: bpfCar.value || null,
|
||||
p_vehicle_label: vehicle ? `${vehicle.brand} ${vehicle.model}` : "",
|
||||
p_date_from: bpfFrom.value || null,
|
||||
p_date_to: bpfTo.value || null,
|
||||
p_message: bpfMessage.value || "",
|
||||
p_source: "website",
|
||||
};
|
||||
|
||||
// Create lead
|
||||
const { data: lead, error } = await supabase.from("leads").insert(payload).select("id").single();
|
||||
// Create lead via RPC (returns inserted id without anon SELECT privileges)
|
||||
const { data: leadId, error } = await supabase.rpc("create_lead", payload);
|
||||
if (error) {
|
||||
console.error(error);
|
||||
bookingFeedback.className = "form-feedback error";
|
||||
bookingFeedback.textContent = t("bookingFailed");
|
||||
bpfSubmitting = false;
|
||||
if (bpfSubmitBtn) bpfSubmitBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Upload files
|
||||
const uploads = [];
|
||||
if (bpfFileId.files[0]) {
|
||||
uploads.push(uploadDoc(lead.id, bpfFileId.files[0], "id_document"));
|
||||
uploads.push(uploadDoc(leadId, bpfFileId.files[0], "id_document"));
|
||||
}
|
||||
if (bpfFileIncome.files[0]) {
|
||||
uploads.push(uploadDoc(lead.id, bpfFileIncome.files[0], "income_proof"));
|
||||
uploads.push(uploadDoc(leadId, bpfFileIncome.files[0], "income_proof"));
|
||||
}
|
||||
await Promise.all(uploads);
|
||||
|
||||
@@ -453,6 +459,8 @@ document.querySelector("#bpfSubmit").addEventListener("click", async () => {
|
||||
document.querySelector("#bpfFileIncomeName").textContent = "";
|
||||
setDurationMode("custom");
|
||||
updateSidebar();
|
||||
bpfSubmitting = false;
|
||||
if (bpfSubmitBtn) bpfSubmitBtn.disabled = false;
|
||||
});
|
||||
|
||||
async function uploadDoc(leadId, file, kind) {
|
||||
|
||||
Reference in New Issue
Block a user