2026-04-15 20:50:01 +02:00

291 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MercyV Garage</title>
<link rel="stylesheet" href="style.css">
<script src="vue.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div id="app" v-show="show">
<!-- ══════════════════════════ GARAGE PANEL ══════════════════════════ -->
<div class="mv-backdrop-transparent" v-show="!showAdminPanel">
<div class="mv-modal">
<!-- HEADER -->
<div class="mv-header">
<div class="mv-header-left">
<div class="mv-header-icon">
<img src="images/logo/logo.png" class="mv-logo-img" alt="MercyV" onerror="this.style.display='none'">
</div>
<div class="mv-header-title">
<span class="mv-title-main">MercyV Garage</span>
<span class="mv-title-sub">{{ garageId || 'Garage' }}</span>
</div>
</div>
<div class="mv-header-right">
<div class="mv-player-name">{{ playerName }}</div>
<button class="mv-close-btn" @click="close()"><i class="fas fa-times"></i></button>
</div>
</div>
<!-- BODY -->
<div class="mv-body">
<!-- SIDEBAR -->
<div class="mv-sidebar">
<div class="mv-sidebar-item" :class="activeTab==='all'?'active':''" @click="setTab('all')" v-show="garageType==='normal'||garageType==='jobgarage'||garageType==='impound'||garageType==='impoundboat'||garageType==='impoundplane'">
<i class="fas fa-border-all"></i><span>Alle</span>
</div>
<div class="mv-sidebar-item" :class="activeTab==='cars'?'active':''" @click="setTab('cars')" v-show="garageType==='normal'||garageType==='jobgarage'||garageType==='impound'">
<i class="fas fa-car"></i><span>Autos</span>
</div>
<div class="mv-sidebar-item" :class="activeTab==='motor'?'active':''" @click="setTab('motor')" v-show="garageType==='normal'||garageType==='jobgarage'||garageType==='impound'">
<i class="fas fa-motorcycle"></i><span>Moto</span>
</div>
<div class="mv-sidebar-item" :class="activeTab==='bikes'?'active':''" @click="setTab('bikes')" v-show="garageType==='normal'||garageType==='jobgarage'||garageType==='impound'">
<i class="fas fa-bicycle"></i><span>Bikes</span>
</div>
<div class="mv-sidebar-item" :class="activeTab==='boat'?'active':''" @click="setTab('boat')" v-show="garageType==='boat'||garageType==='impoundboat'">
<i class="fas fa-ship"></i><span>Boote</span>
</div>
<div class="mv-sidebar-item" :class="activeTab==='aircraft'?'active':''" @click="setTab('aircraft')" v-show="garageType==='aircraft'||garageType==='impoundplane'">
<i class="fas fa-plane"></i><span>Flug</span>
</div>
<div class="mv-sidebar-divider"></div>
<div class="mv-sidebar-item" :class="showFavorites?'active-fav':''" @click="toggleFavorites()" v-show="garageType!=='jobgarage'">
<i :class="showFavorites?'fas fa-star':'far fa-star'"></i><span>Favoriten</span>
</div>
<div class="mv-sidebar-spacer"></div>
<div class="mv-sidebar-item mv-admin-item" v-if="isAdmin" @click="openAdminFromGarage()">
<i class="fas fa-cog"></i><span>Admin</span>
</div>
</div>
<!-- MAIN -->
<div class="mv-main">
<!-- TOPBAR -->
<div class="mv-topbar">
<div class="mv-search-wrap">
<i class="fas fa-search mv-search-icon"></i>
<input v-model="searchQuery" class="mv-search" placeholder="Fahrzeug suchen...">
</div>
<div class="mv-impound-badge" v-if="garageType==='impound'||garageType==='impoundboat'||garageType==='impoundplane'">
<i class="fas fa-euro-sign"></i> Abholgebühr: <strong>{{ impoundPrice }}$</strong>
</div>
</div>
<!-- CONTENT ROW: Grid + Detail -->
<div class="mv-content-row">
<!-- GRID -->
<div class="mv-grid">
<div class="mv-card" v-for="(v, i) in filteredVehicles" :key="v.plate"
@click="selectVehicle(v, i)"
:class="selectedIndex===i ? 'mv-card-active' : ''">
<div class="mv-card-status" :class="v.nearby ? 'status-nearby' : v.stored===0 ? 'status-out' : 'status-in'">
{{ v.nearby ? 'In der Nähe' : v.stored===0 ? 'Draußen' : 'Eingelagert' }}
</div>
<img :src="'images/cars/'+v.carimage+'.png'" class="mv-card-img" onerror="this.src='images/defaultimage.png'">
<div class="mv-card-name">{{ v.carname }}</div>
<div class="mv-card-plate">{{ v.plate }}</div>
<div class="mv-card-fav" @click.stop="toggleFav(v.plate, v.favorite)">
<i :class="v.favorite===1?'fas fa-star':'far fa-star'"></i>
</div>
</div>
<div class="mv-empty" v-if="filteredVehicles.length===0">
<i class="fas fa-car-side"></i>
<p>Keine Fahrzeuge</p>
</div>
</div>
<!-- DETAIL -->
<div class="mv-detail" v-if="selectedVehicle">
<div class="mv-detail-img-wrap">
<img :src="'images/cars/'+selectedVehicle.carimage+'.png'" class="mv-detail-img" onerror="this.src='images/defaultimage.png'">
</div>
<div class="mv-detail-name">{{ selectedVehicle.carname }}</div>
<div class="mv-detail-plate"><i class="fas fa-id-card"></i> {{ selectedVehicle.plate }}</div>
<div class="mv-detail-garage" v-if="selectedVehicle.parking"><i class="fas fa-warehouse"></i> {{ selectedVehicle.parking }}</div>
<div class="mv-detail-status" :class="selectedVehicle.stored===0?'ds-out':'ds-in'">
<i :class="selectedVehicle.stored===0?'fas fa-map-marker-alt':'fas fa-lock'"></i>
{{ selectedVehicle.stored===0 ? 'Aktuell draußen' : 'Eingelagert' }}
</div>
<button class="mv-takeout-btn" @click="takeOut()" v-if="selectedVehicle.stored===1">
<i class="fas fa-car"></i> Fahrzeug holen
</button>
<button class="mv-parkin-btn" @click="parkFromPanel()" v-if="selectedVehicle.nearby && selectedVehicle.stored===0">
<i class="fas fa-parking"></i> Fahrzeug einparken
</button>
<div class="mv-already-out" v-if="!selectedVehicle.nearby && selectedVehicle.stored===0">
<i class="fas fa-map-marker-alt"></i> Fahrzeug ist draußen
</div>
<div class="mv-detail-fav" @click="toggleFav(selectedVehicle.plate, selectedVehicle.favorite)">
<i :class="selectedVehicle.favorite===1?'fas fa-star':'far fa-star'"></i>
{{ selectedVehicle.favorite===1 ? 'Favorit entfernen' : 'Zu Favoriten' }}
</div>
</div>
</div><!-- /.mv-content-row -->
</div><!-- /.mv-main -->
</div><!-- /.mv-body -->
</div><!-- /.mv-modal -->
</div><!-- garage panel -->
<!-- ══════════════════════════ ADMIN PANEL ══════════════════════════ -->
<div class="mv-backdrop-transparent" v-if="showAdminPanel">
<div class="mv-modal mv-modal-wide">
<div class="mv-header">
<div class="mv-header-left">
<div class="mv-header-icon">
<i class="fas fa-cog" style="color:#E8830A;font-size:14px;"></i>
</div>
<div class="mv-header-title">
<span class="mv-title-main">Garage Editor</span>
<span class="mv-title-sub">Admin Tool</span>
</div>
</div>
<div class="mv-header-right">
<button class="mv-btn-orange" @click="newGarage()"><i class="fas fa-plus"></i> Neue Garage</button>
<button class="mv-close-btn" @click="closeAdmin()"><i class="fas fa-times"></i></button>
</div>
</div>
<div class="mv-body">
<div class="mv-sidebar mv-admin-sidebar">
<div style="padding:10px 12px 6px;font-size:11px;color:rgba(255,255,255,0.3);letter-spacing:0.1em;text-transform:uppercase;">
Garagen ({{ adminGarages.length }})
</div>
<div class="mv-admin-list">
<div class="mv-admin-list-item"
v-for="g in adminGarages" :key="g.id"
:class="editingGarage && editingGarage.id===g.id ? 'admin-item-active':''"
@click="editGarage(g)">
<div class="mv-admin-item-icon" :class="'type-icon-'+g.type">
<i :class="getTypeIcon(g.type)"></i>
</div>
<div class="mv-admin-item-info">
<div class="mv-admin-item-label">{{ g.label }}</div>
<div class="mv-admin-item-type">{{ g.type }}</div>
</div>
<div class="mv-admin-item-btns">
<button class="mv-icon-btn mv-icon-btn-blue" @click.stop="teleportTo(g)"><i class="fas fa-location-arrow"></i></button>
<button class="mv-icon-btn mv-icon-btn-red" @click.stop="confirmDelete(g.id)"><i class="fas fa-trash"></i></button>
</div>
</div>
</div>
</div>
<div class="mv-main mv-admin-main" v-if="editingGarage">
<div class="mv-topbar" style="border-bottom:1px solid rgba(255,255,255,0.06);">
<div style="font-size:14px;font-weight:600;color:#fff;">
{{ editingGarage._isNew ? 'Neue Garage erstellen' : 'Bearbeiten: ' + editingGarage.label }}
</div>
<button class="mv-btn-orange" @click="saveGarage()"><i class="fas fa-save"></i> Speichern</button>
</div>
<div class="mv-form-scroll">
<div class="mv-form-section">
<div class="mv-form-section-title"><i class="fas fa-info-circle"></i> Basis</div>
<div class="mv-form-grid">
<div class="mv-form-field">
<label>ID</label>
<input v-model="editingGarage.id" :disabled="!editingGarage._isNew" placeholder="garage_ls_01">
</div>
<div class="mv-form-field">
<label>Anzeigename</label>
<input v-model="editingGarage.label" placeholder="Garage LS">
</div>
<div class="mv-form-field">
<label>Typ</label>
<select v-model="editingGarage.type">
<option value="normal">Normal</option>
<option value="aircraft">Flugzeuge</option>
<option value="boat">Boote</option>
<option value="jobgarage">Job-Garage</option>
<option value="impound">Abschlepphof (Auto)</option>
<option value="impoundboat">Abschlepphof (Boot)</option>
<option value="impoundplane">Abschlepphof (Flugzeug)</option>
</select>
</div>
<div class="mv-form-field">
<label>Job-Zugang</label>
<input v-model="editingGarage.access" placeholder="none">
</div>
<div class="mv-form-field">
<label>NPC Model</label>
<input v-model="editingGarage.npc_model" placeholder="a_m_m_prolhost_01">
</div>
<div class="mv-form-field mv-form-field-check">
<label>Blip anzeigen</label>
<input type="checkbox" v-model="editingGarage.blip_show_bool">
</div>
</div>
</div>
<div class="mv-form-section">
<div class="mv-form-section-title">
<i class="fas fa-map-marker-alt"></i> Positionen
<span class="mv-hint-pill"><i class="fas fa-info-circle"></i> Position aufsuchen → "Hier erfassen" → E drücken</span>
</div>
<div class="mv-pos-block" v-for="pos in posFields" :key="pos.field">
<div class="mv-pos-label">{{ pos.label }}</div>
<div class="mv-pos-row">
<input type="number" step="0.0001" v-model.number="editingGarage[pos.field+'_x']" placeholder="X">
<input type="number" step="0.0001" v-model.number="editingGarage[pos.field+'_y']" placeholder="Y">
<input type="number" step="0.0001" v-model.number="editingGarage[pos.field+'_z']" placeholder="Z">
<input type="number" step="0.0001" v-model.number="editingGarage[pos.field+'_heading']" placeholder="Heading" v-if="pos.hasHeading">
</div>
<button class="mv-capture-btn" @click="capturePos(pos.field)">
<i class="fas fa-crosshairs"></i> Hier erfassen
</button>
</div>
</div>
</div>
</div>
<div class="mv-admin-empty" v-else>
<i class="fas fa-warehouse"></i>
<p>Garage auswählen oder neue erstellen</p>
</div>
</div><!-- /.mv-body -->
</div><!-- /.mv-modal-wide -->
</div><!-- admin panel -->
<!-- DELETE CONFIRM -->
<div class="mv-confirm-overlay" v-if="deleteConfirmId">
<div class="mv-confirm-box">
<i class="fas fa-exclamation-triangle mv-confirm-icon"></i>
<p class="mv-confirm-title">Garage löschen?</p>
<p class="mv-confirm-sub"><strong>{{ deleteConfirmId }}</strong> wird permanent entfernt.</p>
<div class="mv-confirm-btns">
<button class="mv-btn-danger" @click="deleteGarage()"><i class="fas fa-trash"></i> Löschen</button>
<button class="mv-btn-ghost" @click="deleteConfirmId=null">Abbrechen</button>
</div>
</div>
</div>
<!-- CAPTURE OVERLAY -->
<div class="mv-capture-overlay" v-if="capturingField">
<div class="mv-capture-box">
<i class="fas fa-crosshairs mv-capture-icon"></i>
<p class="mv-capture-title">Position erfassen</p>
<p class="mv-capture-field">{{ getFieldLabel(capturingField) }}</p>
<p class="mv-capture-hint">Geh zur Position → <kbd>E</kbd> drücken</p>
<p class="mv-capture-cancel"><kbd>ESC</kbd> = Abbrechen</p>
</div>
</div>
</div><!-- /#app -->
<script src="script.js"></script>
</body>
</html>