227 lines
9.6 KiB
JavaScript
227 lines
9.6 KiB
JavaScript
const app = new Vue({
|
|
el: '#app',
|
|
data: {
|
|
show: false, showAdminPanel: false, isAdmin: false,
|
|
garageId: null, garageType: 'normal',
|
|
playerName: '', avatar: 'images/defaultimage.png',
|
|
vehicles: [], activeTab: 'all', showFavorites: false,
|
|
searchQuery: '',
|
|
selectedVehicle: null, selectedIndex: null,
|
|
impound: false, impoundPrice: 1500,
|
|
adminGarages: [], editingGarage: null,
|
|
deleteConfirmId: null, capturingField: null,
|
|
windowWidth: window.innerWidth,
|
|
posFields: [
|
|
{ field: 'npc', label: 'NPC Position', hasHeading: true },
|
|
{ field: 'spawn', label: 'Spawn Position (Fahrzeug erscheint)', hasHeading: true },
|
|
{ field: 'park', label: 'Einpark-Zone (Marker am Boden)', hasHeading: false },
|
|
],
|
|
jobVehicles: [], // Fahrzeuge für die aktuelle Jobgarage
|
|
newJobVehicle: '', // Eingabe: neues Modell
|
|
},
|
|
|
|
computed: {
|
|
filteredVehicles() {
|
|
return this.vehicles.filter(v => {
|
|
if (this.showFavorites && v.favorite != 1) return false;
|
|
if (this.searchQuery) {
|
|
const q = this.searchQuery.toLowerCase();
|
|
if (!v.carname.toLowerCase().includes(q) && !v.plate.toLowerCase().includes(q)) return false;
|
|
}
|
|
const cls = v.vehClass || 0;
|
|
if (this.activeTab === 'cars') return ![8,13,14,15,16].includes(cls);
|
|
if (this.activeTab === 'motor') return cls === 8;
|
|
if (this.activeTab === 'bikes') return cls === 13;
|
|
if (this.activeTab === 'boat') return cls === 14;
|
|
if (this.activeTab === 'aircraft') return cls === 15 || cls === 16;
|
|
return true;
|
|
});
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
close() {
|
|
this.show = false; this.showAdminPanel = false;
|
|
this.selectedVehicle = null;
|
|
$.post(`https://${GetParentResourceName()}/close`, JSON.stringify({}));
|
|
},
|
|
setTab(tab) {
|
|
this.activeTab = tab; this.showFavorites = false;
|
|
this.selectedVehicle = null; this.selectedIndex = null;
|
|
},
|
|
toggleFavorites() {
|
|
this.showFavorites = !this.showFavorites;
|
|
this.selectedVehicle = null; this.selectedIndex = null;
|
|
},
|
|
selectVehicle(v, index) {
|
|
this.selectedVehicle = v; this.selectedIndex = index;
|
|
$.post(`https://${GetParentResourceName()}/previewVehicle`, JSON.stringify({ modelname: v.modelname, props: v.props }));
|
|
},
|
|
takeOut() {
|
|
if (!this.selectedVehicle) return;
|
|
$.post(`https://${GetParentResourceName()}/takeOut`, JSON.stringify({ plate: this.selectedVehicle.plate, vehClass: this.selectedVehicle.vehClass || 0 }));
|
|
this.show = false; this.showAdminPanel = false;
|
|
},
|
|
|
|
parkFromPanel() {
|
|
if (!this.selectedVehicle || !this.selectedVehicle.nearby) return;
|
|
$.post(`https://${GetParentResourceName()}/parkFromPanel`, JSON.stringify({ plate: this.selectedVehicle.plate }));
|
|
},
|
|
|
|
parkJobVehicle() {
|
|
if (!this.selectedVehicle || !this.selectedVehicle.nearby) return;
|
|
$.post(`https://${GetParentResourceName()}/parkJobVehicle`, JSON.stringify({
|
|
plate: this.selectedVehicle.plate,
|
|
nearbyJobPlate: this.selectedVehicle.nearbyJobPlate || null,
|
|
}));
|
|
},
|
|
|
|
toggleFav(plate, current) {
|
|
const newVal = current == 1 ? 0 : 1;
|
|
$.post(`https://${GetParentResourceName()}/setFavorite`, JSON.stringify({ plate, value: newVal }));
|
|
const v = this.vehicles.find(x => x.plate === plate);
|
|
if (v) { v.favorite = newVal; if (this.selectedVehicle && this.selectedVehicle.plate === plate) this.selectedVehicle.favorite = newVal; }
|
|
},
|
|
|
|
// ADMIN
|
|
openAdmin() {
|
|
this.showAdminPanel = true;
|
|
this.isAdmin = true;
|
|
this.loadAdminGarages();
|
|
},
|
|
|
|
openAdminFromGarage() {
|
|
// Via NUI Callback damit Lua die Kamera sauber aufräumt
|
|
$.post(`https://${GetParentResourceName()}/openAdminFromGarage`, JSON.stringify({}));
|
|
},
|
|
closeAdmin() {
|
|
this.showAdminPanel = false; this.show = false;
|
|
$.post(`https://${GetParentResourceName()}/closeAdmin`, JSON.stringify({}));
|
|
},
|
|
loadAdminGarages() {
|
|
$.post(`https://${GetParentResourceName()}/getAdminGarages`, JSON.stringify({}), (data) => {
|
|
try {
|
|
const d = typeof data === 'string' ? JSON.parse(data) : data;
|
|
if (Array.isArray(d) && d.length > 0) {
|
|
this.adminGarages = d.sort((a,b) => a.label.localeCompare(b.label));
|
|
}
|
|
// Falls leer: Daten kommen via ADMIN_GARAGES message
|
|
} catch(e) {}
|
|
});
|
|
},
|
|
newGarage() {
|
|
this.editingGarage = { _isNew: true, id:'', label:'', type:'normal', access:'none', gang:'none', npc_model:'a_m_m_prolhost_01', blip_show:1, blip_show_bool:true, blip_type:357, blip_colour:3, npc_x:0,npc_y:0,npc_z:0,npc_heading:0, spawn_x:0,spawn_y:0,spawn_z:0,spawn_heading:0, park_x:0,park_y:0,park_z:0,park_heading:0 };
|
|
this.jobVehicles = [];
|
|
},
|
|
editGarage(g) {
|
|
this.editingGarage = Object.assign({ _isNew: false, blip_show_bool: g.blip_show == 1 }, g);
|
|
// Job-Fahrzeuge laden falls Jobgarage
|
|
if (g.type === 'jobgarage') {
|
|
this.jobVehicles = g.job_vehicles ? [...g.job_vehicles] : [];
|
|
} else {
|
|
this.jobVehicles = [];
|
|
}
|
|
},
|
|
confirmDelete(id) { this.deleteConfirmId = id; },
|
|
deleteGarage() {
|
|
if (!this.deleteConfirmId) return;
|
|
$.post(`https://${GetParentResourceName()}/adminDeleteGarage`, JSON.stringify({ id: this.deleteConfirmId }));
|
|
this.adminGarages = this.adminGarages.filter(g => g.id !== this.deleteConfirmId);
|
|
if (this.editingGarage && this.editingGarage.id === this.deleteConfirmId) this.editingGarage = null;
|
|
this.deleteConfirmId = null;
|
|
},
|
|
// Job-Fahrzeug hinzufügen
|
|
addJobVehicle() {
|
|
const model = this.newJobVehicle.trim().toLowerCase();
|
|
if (!model) return;
|
|
if (!this.jobVehicles.find(v => v.model === model)) {
|
|
this.jobVehicles.push({ model, label: model.toUpperCase() });
|
|
}
|
|
this.newJobVehicle = '';
|
|
},
|
|
removeJobVehicle(index) {
|
|
this.jobVehicles.splice(index, 1);
|
|
},
|
|
saveGarage() {
|
|
const g = this.editingGarage;
|
|
if (!g) return;
|
|
if (!g.id || !g.id.trim()) { return; }
|
|
if (!g.label || !g.label.trim()) { return; }
|
|
g.id = g.id.trim().replace(/\s+/g,'_');
|
|
const payload = Object.assign({}, g);
|
|
delete payload._isNew; delete payload.blip_show_bool;
|
|
payload.blip_show = g.blip_show_bool ? 1 : 0;
|
|
if (g.type === 'jobgarage') {
|
|
payload.job_vehicles = this.jobVehicles;
|
|
}
|
|
$.post(`https://${GetParentResourceName()}/adminSaveGarage`, JSON.stringify(payload));
|
|
const i = this.adminGarages.findIndex(x => x.id === payload.id);
|
|
if (i >= 0) this.adminGarages.splice(i, 1, payload); else this.adminGarages.push(payload);
|
|
this.adminGarages.sort((a,b) => a.label.localeCompare(b.label));
|
|
this.editingGarage._isNew = false;
|
|
},
|
|
teleportTo(g) { $.post(`https://${GetParentResourceName()}/teleportToGarage`, JSON.stringify({ x:g.npc_x, y:g.npc_y, z:g.npc_z, heading:g.npc_heading })); },
|
|
capturePos(field) {
|
|
this.capturingField = field;
|
|
$.post(`https://${GetParentResourceName()}/startCapture`, JSON.stringify({ field }));
|
|
},
|
|
getFieldLabel(field) {
|
|
const l = { npc:'NPC Position', spawn:'Spawn Position', park:'Einpark-Zone' };
|
|
return l[field] || field;
|
|
},
|
|
getTypeIcon(type) {
|
|
const m = { normal:'fas fa-car', aircraft:'fas fa-plane', boat:'fas fa-ship', jobgarage:'fas fa-briefcase', impound:'fas fa-lock', impoundboat:'fas fa-ship', impoundplane:'fas fa-plane' };
|
|
return m[type] || 'fas fa-warehouse';
|
|
},
|
|
applyCapture(field, x, y, z, heading) {
|
|
if (!this.editingGarage) return;
|
|
this.editingGarage[field+'_x'] = x;
|
|
this.editingGarage[field+'_y'] = y;
|
|
this.editingGarage[field+'_z'] = z;
|
|
if (heading !== undefined) this.editingGarage[field+'_heading'] = heading;
|
|
},
|
|
}
|
|
});
|
|
|
|
window.addEventListener('message', function(e) {
|
|
const msg = e.data;
|
|
if (!msg || !msg.action) return;
|
|
switch(msg.action) {
|
|
case 'OPEN':
|
|
app.show = true; app.showAdminPanel = false;
|
|
app.garageId = msg.garageId; app.garageType = msg.garageType || 'normal';
|
|
app.vehicles = msg.vehicles || []; app.playerName = msg.playerName || '';
|
|
app.impound = msg.impound || false; app.impoundPrice = msg.impoundPrice || 1500;
|
|
app.selectedVehicle = null; app.selectedIndex = null;
|
|
app.showFavorites = false; app.searchQuery = '';
|
|
if (msg.garageType === 'aircraft' || msg.garageType === 'impoundplane') app.activeTab = 'aircraft';
|
|
else if (msg.garageType === 'boat' || msg.garageType === 'impoundboat') app.activeTab = 'boat';
|
|
else app.activeTab = 'all';
|
|
break;
|
|
case 'CLOSE': app.show = false; app.showAdminPanel = false; break;
|
|
case 'OPEN_ADMIN':
|
|
app.show = true; app.showAdminPanel = true; app.isAdmin = true;
|
|
app.loadAdminGarages(); break;
|
|
case 'SET_PROFILE': app.playerName = msg.name || ''; app.avatar = msg.avatar || 'images/defaultimage.png'; break;
|
|
case 'SET_ADMIN': app.isAdmin = msg.isAdmin || false; break;
|
|
case 'POSITION_CAPTURED':
|
|
app.capturingField = null;
|
|
if (app.editingGarage) app.applyCapture(msg.field, msg.x, msg.y, msg.z, msg.heading);
|
|
break;
|
|
case 'CAPTURE_CANCELLED': app.capturingField = null; break;
|
|
case 'ADMIN_GARAGES':
|
|
if (msg.garages) {
|
|
app.adminGarages = msg.garages.sort((a,b) => a.label.localeCompare(b.label));
|
|
}
|
|
break;
|
|
case 'SYNC_GARAGES_DONE': if (app.showAdminPanel) app.loadAdminGarages(); break;
|
|
}
|
|
});
|
|
|
|
$(document).keydown(function(e) {
|
|
if (e.keyCode === 27) {
|
|
if (app.showAdminPanel) app.closeAdmin();
|
|
else app.close();
|
|
}
|
|
});
|