feat(admin): replace checkbox with toggle-switch slider, add i18n multilanguage

This commit is contained in:
Lago
2026-04-18 00:01:03 +02:00
parent c5fa51ce63
commit 1820f7d766
4 changed files with 212 additions and 56 deletions
+48 -44
View File
@@ -61,19 +61,20 @@
<div class="admin-bar">
<h1>MC Cars · Admin</h1>
<div style="display:flex;gap:0.6rem;align-items:center;flex-wrap:wrap;">
<a href="index.html" class="btn ghost small">Website</a>
<a href="index.html" class="btn ghost small" data-i18n="adminNavWebsite">Website</a>
<button class="lang-toggle" type="button" aria-label="Sprache wechseln" style="margin-left:auto;">EN</button>
<span id="adminWho" style="color:var(--muted);font-size:0.85rem;"></span>
<button id="changePwBtn" class="btn ghost small">Passwort aendern</button>
<button id="logoutBtn" class="btn small">Logout</button>
<span id="adminWho" style="color:var(--muted);font-size:0.85rem;margin-left:1rem;"></span>
<button id="changePwBtn" class="btn ghost small" data-i18n="adminChangePw">Passwort aendern</button>
<button id="logoutBtn" class="btn small" data-i18n="adminLogout">Logout</button>
</div>
</div>
<!-- Tabs -->
<div class="admin-tabs" role="tablist">
<button class="tab active" data-tab="leads" role="tab">Leads <span id="leadsBadge" class="tab-badge">0</span></button>
<button class="tab" data-tab="customers" role="tab">Kunden <span id="customersBadge" class="tab-badge">0</span></button>
<button class="tab" data-tab="vehicles" role="tab">Fahrzeuge</button>
<button class="tab active" data-tab="leads" role="tab"><span data-i18n="adminLeads">Leads</span> <span id="leadsBadge" class="tab-badge">0</span></button>
<button class="tab" data-tab="customers" role="tab"><span data-i18n="adminCustomers">Kunden</span> <span id="customersBadge" class="tab-badge">0</span></button>
<button class="tab" data-tab="vehicles" role="tab" data-i18n="adminVehicles">Fahrzeuge</button>
</div>
<!-- LEADS -->
@@ -82,18 +83,18 @@
<div style="display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;margin-bottom:1rem;">
<h2 style="margin:0;">Leads</h2>
<div class="sub-tabs" role="tablist">
<button class="sub-tab active" data-lview="active">Aktive Leads</button>
<button class="sub-tab" data-lview="inactive">Abgeschlossen</button>
<button class="sub-tab active" data-lview="active" data-i18n="adminActiveLeads">Aktive Leads</button>
<button class="sub-tab" data-lview="inactive" data-i18n="adminClosedLeads">Abgeschlossen</button>
</div>
</div>
<table class="admin-table" id="leadsTable">
<thead>
<tr>
<th>Eingang</th>
<th>Name / E-Mail</th>
<th>Fahrzeug</th>
<th>Zeitraum</th>
<th>Status</th>
<th data-i18n="adminReceived">Eingang</th>
<th data-i18n="adminNameEmail">Name / E-Mail</th>
<th data-i18n="adminVehicleTab">Fahrzeug</th>
<th data-i18n="adminPeriod">Zeitraum</th>
<th data-i18n="adminStatus">Status</th>
<th></th>
</tr>
</thead>
@@ -111,11 +112,11 @@
<table class="admin-table" id="customersTable">
<thead>
<tr>
<th>Erster Kontakt</th>
<th>Name / E-Mail</th>
<th>Telefon</th>
<th>Quelle (Lead)</th>
<th>Status</th>
<th data-i18n="adminFirstContact">Erster Kontakt</th>
<th data-i18n="adminNameEmail">Name / E-Mail</th>
<th data-i18n="adminPhone">Telefon</th>
<th data-i18n="adminSourceLead">Quelle (Lead)</th>
<th data-i18n="adminStatus">Status</th>
<th></th>
</tr>
</thead>
@@ -129,73 +130,76 @@
<div class="tab-panel" id="tab-vehicles" style="display:none;">
<div class="admin-grid">
<div class="panel">
<h2 id="formTitle">Neues Fahrzeug</h2>
<h2 id="formTitle" data-i18n="adminNewVehicle">Neues Fahrzeug</h2>
<form class="admin-form" id="vehicleForm">
<input type="hidden" name="vid" />
<div class="admin-photo-preview" id="photoPreview"></div>
<label>
<span>Foto hochladen (JPG/PNG/WebP, max 50 MB)</span>
<span data-i18n="adminPhotoUpload">Foto hochladen (JPG/PNG/WebP, max 50 MB)</span>
<input type="file" id="photoInput" accept="image/*" />
</label>
<label>
<span>Foto-URL (wird automatisch gesetzt nach Upload)</span>
<span data-i18n="adminPhotoUrl">Foto-URL (wird automatisch gesetzt nach Upload)</span>
<input type="url" name="photo_url" placeholder="https://..." />
</label>
<div class="row2">
<label><span>Marke</span><input name="brand" required /></label>
<label><span>Modell</span><input name="model" required /></label>
<label><span data-i18n="adminBrand">Marke</span><input name="brand" required /></label>
<label><span data-i18n="adminModel">Modell</span><input name="model" required /></label>
</div>
<div class="row3">
<label><span>PS</span><input type="number" name="power_hp" min="0" /></label>
<label><span>Top-Speed km/h</span><input type="number" name="top_speed_kmh" min="0" /></label>
<label><span>0-100</span><input name="acceleration" placeholder="3.2s" /></label>
<label><span data-i18n="adminPower">PS</span><input type="number" name="power_hp" min="0" /></label>
<label><span data-i18n="adminSpeed">Top-Speed km/h</span><input type="number" name="top_speed_kmh" min="0" /></label>
<label><span data-i18n="adminAccel">0-100</span><input name="acceleration" placeholder="3.2s" /></label>
</div>
<div class="row3">
<label><span>Sitze</span><input type="number" name="seats" min="1" value="2" /></label>
<label><span>Preis / Tag (€)</span><input type="number" name="daily_price_eur" min="0" required /></label>
<label><span>Reihenfolge</span><input type="number" name="sort_order" value="100" /></label>
<label><span data-i18n="adminSeats">Sitze</span><input type="number" name="seats" min="1" value="2" /></label>
<label><span data-i18n="adminPrice">Preis / Tag (€)</span><input type="number" name="daily_price_eur" min="0" required /></label>
<label><span data-i18n="adminSort">Reihenfolge</span><input type="number" name="sort_order" value="100" /></label>
</div>
<label>
<span>Standort</span>
<span data-i18n="adminLocation">Standort</span>
<input name="location" value="Steiermark (TBD)" />
</label>
<label>
<span>Beschreibung (Deutsch)</span>
<span data-i18n="adminDescDe">Beschreibung (Deutsch)</span>
<textarea name="description_de" rows="3"></textarea>
</label>
<label>
<span>Description (English)</span>
<span data-i18n="adminDescEn">Description (English)</span>
<textarea name="description_en" rows="3"></textarea>
</label>
<label style="flex-direction:row;align-items:center;gap:0.5rem;">
<input type="checkbox" name="is_active" checked style="width:auto;" />
<span>Aktiv / auf Website sichtbar</span>
<label style="flex-direction:row;align-items:center;gap:0.8rem;margin-top:0.5rem;cursor:pointer;">
<div class="toggle-switch">
<input type="checkbox" name="is_active" id="isActiveCheck" checked />
<span class="toggle-slider"></span>
</div>
<span data-i18n="adminActiveVisible" style="user-select:none;">Aktiv / auf Website sichtbar</span>
</label>
<div style="display:flex;gap:0.5rem;">
<button class="btn" type="submit" id="saveBtn">Speichern</button>
<button class="btn ghost" type="button" id="resetBtn">Neu</button>
<div style="display:flex;gap:0.5rem;margin-top:1rem;">
<button class="btn" type="submit" id="saveBtn" data-i18n="adminSave">Speichern</button>
<button class="btn ghost" type="button" id="resetBtn" data-i18n="adminReset">Neu</button>
</div>
<p class="form-feedback" id="formFeedback"></p>
</form>
</div>
<div class="panel">
<h2>Alle Fahrzeuge</h2>
<h2 data-i18n="adminAllVehicles">Alle Fahrzeuge</h2>
<table class="admin-table" id="adminTable">
<thead>
<tr>
<th>Foto</th>
<th>Marke / Modell</th>
<th>€ / Tag</th>
<th>Aktiv</th>
<th data-i18n="adminPhoto">Foto</th>
<th data-i18n="adminBrandTable">Marke / Modell</th>
<th data-i18n="adminPriceTable">€ / Tag</th>
<th data-i18n="adminActive">Aktiv</th>
<th></th>
</tr>
</thead>