feat: add deposit and weekend km allowance to vehicles, update migrations and booking flow
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
+6
-4
@@ -139,10 +139,7 @@
|
||||
<span data-i18n="adminPhotoUpload">Foto hochladen (JPG/PNG/WebP, max 50 MB)</span>
|
||||
<input type="file" id="photoInput" accept="image/*" />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="adminPhotoUrl">Foto-URL (wird automatisch gesetzt nach Upload)</span>
|
||||
<input type="url" name="photo_url" placeholder="https://..." />
|
||||
</label>
|
||||
<input type="hidden" name="photo_url" />
|
||||
|
||||
<div class="row2">
|
||||
<label><span data-i18n="adminBrand">Marke</span><input name="brand" required /></label>
|
||||
@@ -163,6 +160,11 @@
|
||||
|
||||
<div class="row3">
|
||||
<label><span>Max. km/Tag</span><input type="number" name="max_daily_km" min="0" value="150" /></label>
|
||||
<label><span data-i18n="adminKaution">Kaution (€)</span><input type="number" name="kaution_eur" min="1" value="5000" required /></label>
|
||||
<label><span data-i18n="adminMaxKmWeekend">Max. km/Wochenendtag</span><input type="number" name="max_km_weekend" min="0" placeholder="wie km/Tag" /></label>
|
||||
</div>
|
||||
|
||||
<div class="row2">
|
||||
<label><span data-i18n="adminSort">Reihenfolge</span><input type="number" name="sort_order" value="100" /></label>
|
||||
<label><span data-i18n="adminLocation">Standort</span><input name="location" value="Steiermark (TBD)" /></label>
|
||||
</div>
|
||||
|
||||
+11
-1
@@ -230,6 +230,8 @@ function loadForEdit(id) {
|
||||
vehicleForm.daily_price_eur.value = v.daily_price_eur;
|
||||
vehicleForm.weekend_price_eur.value = v.weekend_price_eur || 0;
|
||||
vehicleForm.max_daily_km.value = v.max_daily_km || 150;
|
||||
vehicleForm.kaution_eur.value = v.kaution_eur || 5000;
|
||||
vehicleForm.max_km_weekend.value = v.max_km_weekend || '';
|
||||
vehicleForm.sort_order.value = v.sort_order;
|
||||
vehicleForm.location.value = v.location;
|
||||
vehicleForm.description_de.value = v.description_de;
|
||||
@@ -250,6 +252,8 @@ resetBtn.addEventListener("click", () => {
|
||||
vehicleForm.seats.value = 2;
|
||||
vehicleForm.max_daily_km.value = 150;
|
||||
vehicleForm.weekend_price_eur.value = 0;
|
||||
vehicleForm.kaution_eur.value = 5000;
|
||||
vehicleForm.max_km_weekend.value = '';
|
||||
state.currentPhotoPath = null;
|
||||
updatePreview("");
|
||||
formTitle.textContent = "Neues Fahrzeug";
|
||||
@@ -273,6 +277,8 @@ vehicleForm.addEventListener("submit", async (e) => {
|
||||
daily_price_eur: +fd.get("daily_price_eur") || 0,
|
||||
weekend_price_eur: +fd.get("weekend_price_eur") || 0,
|
||||
max_daily_km: +fd.get("max_daily_km") || 150,
|
||||
kaution_eur: +fd.get("kaution_eur") || 5000,
|
||||
max_km_weekend: fd.get("max_km_weekend") ? +fd.get("max_km_weekend") : null,
|
||||
sort_order: +fd.get("sort_order") || 100,
|
||||
location: fd.get("location") || "Steiermark (TBD)",
|
||||
description_de: fd.get("description_de") || "",
|
||||
@@ -316,11 +322,15 @@ photoInput.addEventListener("change", async () => {
|
||||
formFeedback.className = "form-feedback";
|
||||
formFeedback.textContent = "Uploading photo...";
|
||||
try {
|
||||
// Delete old photo if exists
|
||||
if (state.currentPhotoPath) {
|
||||
await supabase.storage.from("vehicle-photos").remove([state.currentPhotoPath]);
|
||||
}
|
||||
const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
|
||||
const path = `${crypto.randomUUID()}.${ext}`;
|
||||
const { error: upErr } = await supabase.storage
|
||||
.from("vehicle-photos")
|
||||
.upload(path, file, { contentType: file.type, upsert: false });
|
||||
.upload(path, file, { contentType: file.type, upsert: true });
|
||||
if (upErr) throw upErr;
|
||||
const { data: pub } = supabase.storage.from("vehicle-photos").getPublicUrl(path);
|
||||
state.currentPhotoPath = path;
|
||||
|
||||
+12
-2
@@ -196,6 +196,14 @@ function openDetails(id) {
|
||||
<div><strong>${v.top_speed_kmh}</strong><span>${t("kmh")}</span></div>
|
||||
<div><strong>${escapeHtml(v.acceleration)}</strong><span>${t("accel")}</span></div>
|
||||
</div>
|
||||
<div class="spec-row" style="margin:1rem 0;">
|
||||
<div><strong>${v.seats}</strong><span>${t("seats")}</span></div>
|
||||
<div><strong>€ ${v.weekend_price_eur || v.daily_price_eur}</strong><span>${t("bpfWeekendRate")}</span></div>
|
||||
<div><strong>${v.max_daily_km || 150}</strong><span>${t("bpfMaxKm")}</span></div>
|
||||
</div>
|
||||
<div class="spec-row" style="margin:1rem 0;grid-template-columns:1fr;">
|
||||
<div><strong>€ ${(v.kaution_eur || 5000).toLocaleString("de-DE")}</strong><span>${t("bpfDeposit")}</span></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-top:1rem;">
|
||||
<div class="vehicle-price">€ ${v.daily_price_eur}<span> / ${t("perDay")}</span></div>
|
||||
<button class="btn" id="dialogBook">${t("bookNow")}</button>
|
||||
@@ -364,8 +372,10 @@ function updateSidebar() {
|
||||
const subtotal = weekdayCost + weekendCost;
|
||||
const vat = Math.round(subtotal * 0.20);
|
||||
const total = subtotal + vat;
|
||||
const deposit = Math.round(v.daily_price_eur * 2.5);
|
||||
const includedKm = (v.max_daily_km || 150) * totalDays;
|
||||
const deposit = v.kaution_eur || 5000;
|
||||
const kmPerWeekendDay = v.max_km_weekend || v.max_daily_km || 150;
|
||||
const kmPerWeekday = v.max_daily_km || 150;
|
||||
const includedKm = (weekdays * kmPerWeekday) + (weekendDays * kmPerWeekendDay);
|
||||
|
||||
bpfSidebarPlaceholder.style.display = "none";
|
||||
bpfSidebarContent.style.display = "block";
|
||||
|
||||
+4
-2
@@ -133,7 +133,6 @@ export const translations = {
|
||||
adminNewVehicle: "Neues Fahrzeug",
|
||||
adminAllVehicles: "Alle Fahrzeuge",
|
||||
adminPhotoUpload: "Foto hochladen (JPG/PNG/WebP, max 50 MB)",
|
||||
adminPhotoUrl: "Foto-URL (wird automatisch gesetzt nach Upload)",
|
||||
adminBrand: "Marke",
|
||||
adminModel: "Modell",
|
||||
adminPower: "PS",
|
||||
@@ -169,6 +168,8 @@ export const translations = {
|
||||
adminReceived: "Eingang",
|
||||
adminVehicleTab: "Fahrzeug",
|
||||
adminPeriod: "Zeitraum",
|
||||
adminKaution: "Kaution (€)",
|
||||
adminMaxKmWeekend: "Max. km/Wochenendtag",
|
||||
},
|
||||
en: {
|
||||
navCars: "Fleet",
|
||||
@@ -303,7 +304,6 @@ export const translations = {
|
||||
adminNewVehicle: "New vehicle",
|
||||
adminAllVehicles: "All vehicles",
|
||||
adminPhotoUpload: "Upload photo (JPG/PNG/WebP, max 50 MB)",
|
||||
adminPhotoUrl: "Photo URL (auto-set after upload)",
|
||||
adminBrand: "Brand",
|
||||
adminModel: "Model",
|
||||
adminPower: "HP",
|
||||
@@ -339,6 +339,8 @@ export const translations = {
|
||||
adminReceived: "Received",
|
||||
adminVehicleTab: "Vehicle",
|
||||
adminPeriod: "Period",
|
||||
adminKaution: "Deposit (€)",
|
||||
adminMaxKmWeekend: "Max. km/weekend day",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user