feat: implement server-side pricing calculation and add site settings management
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -177,6 +177,7 @@ const tabPanels = {
|
||||
customers: document.querySelector("#tab-customers"),
|
||||
orders: document.querySelector("#tab-orders"),
|
||||
vehicles: document.querySelector("#tab-vehicles"),
|
||||
settings: document.querySelector("#tab-settings"),
|
||||
};
|
||||
let activeTab = "leads";
|
||||
|
||||
@@ -206,6 +207,7 @@ function renderActiveTab() {
|
||||
if (activeTab === "customers") renderCustomers();
|
||||
if (activeTab === "orders") renderOrders();
|
||||
if (activeTab === "vehicles") renderVehicles();
|
||||
if (activeTab === "settings") renderSettings();
|
||||
}
|
||||
|
||||
// Sub-tabs (active/inactive leads)
|
||||
@@ -1100,4 +1102,47 @@ leadDialog.addEventListener("close", onDialogClose);
|
||||
customerDialog.addEventListener("close", onDialogClose);
|
||||
orderDialog.addEventListener("close", onDialogClose);
|
||||
|
||||
// =========================================================================
|
||||
// SETTINGS
|
||||
// =========================================================================
|
||||
const heroPreview = document.querySelector("#heroPreview");
|
||||
const heroImageInput = document.querySelector("#heroImageInput");
|
||||
const heroFeedback = document.querySelector("#heroFeedback");
|
||||
|
||||
async function renderSettings() {
|
||||
const { data } = await supabase.from("site_settings").select("value").eq("key", "hero_image_url").single();
|
||||
const url = data?.value || "/images/ferrari-main-car.png";
|
||||
heroPreview.style.backgroundImage = `url('${url}')`;
|
||||
}
|
||||
|
||||
heroImageInput.addEventListener("change", async () => {
|
||||
const file = heroImageInput.files?.[0];
|
||||
if (!file) return;
|
||||
heroFeedback.className = "form-feedback";
|
||||
heroFeedback.textContent = "Uploading...";
|
||||
try {
|
||||
const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
|
||||
const path = `site/hero.${ext}`;
|
||||
const { error: upErr } = await supabase.storage
|
||||
.from("vehicle-photos")
|
||||
.upload(path, file, { contentType: file.type, upsert: true });
|
||||
if (upErr) throw upErr;
|
||||
const { data: pub } = supabase.storage.from("vehicle-photos").getPublicUrl(path);
|
||||
const publicUrl = pub.publicUrl;
|
||||
|
||||
// Save to site_settings
|
||||
const { error: dbErr } = await supabase
|
||||
.from("site_settings")
|
||||
.upsert({ key: "hero_image_url", value: publicUrl, updated_at: new Date().toISOString() }, { onConflict: "key" });
|
||||
if (dbErr) throw dbErr;
|
||||
|
||||
heroPreview.style.backgroundImage = `url('${publicUrl}')`;
|
||||
heroFeedback.className = "form-feedback";
|
||||
heroFeedback.textContent = "Gespeichert.";
|
||||
} catch (err) {
|
||||
heroFeedback.className = "form-feedback error";
|
||||
heroFeedback.textContent = err.message || String(err);
|
||||
}
|
||||
});
|
||||
|
||||
bootstrap();
|
||||
|
||||
Reference in New Issue
Block a user