Files
service-finder/code-server-config/data/User/History/-52e5c41d/E3XE.html

179 lines
9.5 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<title>Szerviz Kereső - Flotta Menedzser</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<style>
body { background: #f0f2f5; font-family: 'Inter', sans-serif; }
.auth-card { background: white; padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); width: 100%; max-width: 400px; }
.navbar { background: white !important; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
.garage-card { border: none; border-radius: 15px; transition: 0.3s; cursor: pointer; background: white; }
.garage-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.08); }
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; display: flex; align-items: center; justify-content: center; }
</style>
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-lg navbar-light px-4 mb-4" v-if="isLoggedIn">
<div class="container">
<a class="navbar-brand fw-bold text-primary" href="#" @click="view='garage'"><i class="bi bi-tools me-2"></i>SZERVIZ KERESŐ</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link" :class="{active: view==='garage'}" @click="view='garage'" href="#">Garázs</a></li>
<li class="nav-item"><a class="nav-link" href="#">Szervizek</a></li>
<li class="nav-item"><a class="nav-link" href="#">Csapatom</a></li>
</ul>
<div class="d-flex align-items-center">
<select class="form-select form-select-sm me-3" style="width: auto;"><option>🇭🇺 HU</option><option>🇬🇧 EN</option></select>
<button class="btn btn-outline-danger btn-sm" @click="logout"><i class="bi bi-box-arrow-right"></i></button>
</div>
</div>
</div>
</nav>
<div v-if="!isLoggedIn" class="d-flex align-items-center justify-content-center" style="height:100vh">
<div class="auth-card">
<h2 class="text-center fw-bold mb-4 text-primary">Service Finder</h2>
<div v-if="authMode === 'login'">
<input type="email" class="form-control mb-3" v-model="authForm.email" placeholder="Email cím">
<input type="password" class="form-control mb-3" v-model="authForm.password" placeholder="Jelszó">
<button class="btn btn-primary w-100 py-2" @click="handleLogin">Bejelentkezés</button>
<p class="text-center mt-3 small">Nincs még fiókod? <a href="#" @click="authMode='register'">Regisztráció</a></p>
</div>
<div v-else>
<input type="email" class="form-control mb-3" v-model="authForm.email" placeholder="Új Email cím">
<input type="password" class="form-control mb-3" v-model="authForm.password" placeholder="Új Jelszó">
<button class="btn btn-success w-100 py-2" @click="handleRegister">Fiók létrehozása</button>
<p class="text-center mt-3 small"><a href="#" @click="authMode='login'">Vissza a belépéshez</a></p>
</div>
</div>
</div>
<div v-else class="container">
<div v-if="view === 'garage'">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="fw-bold">Garázsom</h3>
<button class="btn btn-primary" @click="modals.reg = true"><i class="bi bi-plus-lg me-2"></i>Új Jármű</button>
</div>
<div class="row g-4">
<div class="col-md-4" v-for="car in myCars">
<div class="card garage-card p-4 shadow-sm" @click="selectedCar=car; view='detail'">
<div class="d-flex justify-content-between mb-2">
<h5 class="fw-bold mb-0">{{car.brand}}</h5>
<span class="badge bg-warning text-dark">{{car.plate}}</span>
</div>
<div class="text-muted small">{{car.model}}</div>
<div class="mt-3 d-flex justify-content-between">
<button class="btn btn-sm btn-outline-success" @click.stop="openCost(car)">Költség +</button>
<button class="btn btn-sm btn-outline-secondary">Részletek</button>
</div>
</div>
</div>
</div>
</div>
<div v-if="view === 'detail' && selectedCar">
<button class="btn btn-link ps-0 mb-3 text-decoration-none" @click="view='garage'"><i class="bi bi-arrow-left"></i> Vissza</button>
<div class="card p-4 rounded-4 border-0 shadow-sm">
<h2 class="fw-bold">{{selectedCar.brand}} {{selectedCar.model}}</h2>
<p class="text-muted">Rendszám: {{selectedCar.plate}}</p>
<hr>
<div class="row text-center mt-4">
<div class="col-4"><h6>Állapot</h6><h5 class="text-success">Kiváló</h5></div>
<div class="col-4"><h6>Szerviz</h6><h5>Aktuális</h5></div>
<div class="col-4"><h6>Csapat</h6><h5>1 Sofőr</h5></div>
</div>
</div>
</div>
</div>
<div v-if="modals.reg" class="modal-overlay">
<div class="auth-card" style="max-width: 500px;">
<h4 class="fw-bold mb-4">Új Jármű</h4>
<select class="form-select mb-3" v-model="regForm.cat" @change="regForm.brand=''; regForm.model_id=''">
<option value="" disabled>Kategória...</option>
<option v-for="(brands, cat) in meta.hierarchy" :value="cat">{{cat}}</option>
</select>
<select class="form-select mb-3" v-model="regForm.brand" :disabled="!regForm.cat">
<option value="" disabled>Márka...</option>
<option v-for="(models, brand) in meta.hierarchy[regForm.cat]" :value="brand">{{brand}}</option>
</select>
<select class="form-select mb-3" v-model="regForm.model_id" :disabled="!regForm.brand">
<option value="" disabled>Típus...</option>
<option v-for="m in meta.hierarchy[regForm.cat]?.[regForm.brand]" :value="m.id">{{m.name}}</option>
</select>
<input type="text" class="form-control mb-3" v-model="regForm.plate" placeholder="Rendszám">
<div class="d-flex gap-2">
<button class="btn btn-light w-100" @click="modals.reg=false">Mégse</button>
<button class="btn btn-primary w-100" @click="submitReg">Mentés</button>
</div>
</div>
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const { createApp } = Vue
createApp({
data() {
return {
isLoggedIn: !!localStorage.getItem('token'),
authMode: 'login',
view: 'garage',
authForm: { email: '', password: '' },
regForm: { cat: '', brand: '', model_id: '', plate: '', mileage: 0 },
myCars: [],
meta: { hierarchy: {}, costTypes: {} },
modals: { reg: false },
selectedCar: null
}
},
methods: {
async handleLogin() {
const p = new URLSearchParams(); p.append('username', this.authForm.email); p.append('password', this.authForm.password);
const res = await fetch('/api/auth/login', { method: 'POST', body: p });
if (res.ok) {
const d = await res.json();
localStorage.setItem('token', d.access_token);
this.isLoggedIn = true;
this.initApp();
} else alert("Hibás belépés!");
},
async handleRegister() {
const f = new FormData(); f.append('email', this.authForm.email); f.append('password', this.authForm.password);
const res = await fetch('/api/auth/register', { method: 'POST', body: f });
if (res.ok) { alert("Sikeres regisztráció! Most jelentkezz be."); this.authMode = 'login'; }
else alert("Hiba a regisztráció során.");
},
async initApp() {
const token = localStorage.getItem('token');
if(!token) return;
const headers = { 'Authorization': 'Bearer ' + token };
const [r1, r2, r3] = await Promise.all([
fetch('/api/my_vehicles', { headers }),
fetch('/api/meta/vehicle-hierarchy'),
fetch('/api/meta/cost-types')
]);
if(r1.ok) this.myCars = await r1.json();
if(r2.ok) this.meta.hierarchy = await r2.json();
},
async submitReg() {
const res = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem('token') },
body: JSON.stringify({ ...this.regForm, vin: 'AUTO'+Math.random(), purchase_date: '2026-01-01' })
});
if(res.ok) { this.modals.reg = false; this.initApp(); }
},
logout() { localStorage.clear(); this.isLoggedIn = false; }
},
mounted() { if(this.isLoggedIn) this.initApp(); }
}).mount('#app')
</script>
</body>
</html>