local QBCore = exports['qb-core']:GetCoreObject() local nearInfoPoint = false local currentInfoPoint = nil -- Blips erstellen CreateThread(function() for _, point in pairs(Config.InfoPoints) do if point.blip.display then local blip = AddBlipForCoord(point.coords.x, point.coords.y, point.coords.z) SetBlipSprite(blip, point.blip.sprite) SetBlipColour(blip, point.blip.color) SetBlipScale(blip, point.blip.scale) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") AddTextComponentString(point.name .. " - Infopoint") EndTextCommandSetBlipName(blip) end end end) -- Hauptschleife für Nähe-Erkennung CreateThread(function() while true do local sleep = 1000 local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed) nearInfoPoint = false currentInfoPoint = nil for _, point in pairs(Config.InfoPoints) do local distance = #(playerCoords - point.coords) if distance < 2.0 then nearInfoPoint = true currentInfoPoint = point sleep = 0 -- Draw Text anzeigen lib.showTextUI('[E] - Infopoint öffnen\n' .. point.name, { position = "top-center", icon = 'info-circle' }) -- E-Taste abfragen if IsControlJustPressed(0, 38) then -- E openInfoPointMenu() end break end end if not nearInfoPoint then lib.hideTextUI() end Wait(sleep) end end) -- Infopoint Menü öffnen function openInfoPointMenu() local PlayerData = QBCore.Functions.GetPlayerData() local job = PlayerData.job.name local jobPermissions = Config.JobPermissions.jobSpecificInfo[job] or {} local menuOptions = { { title = 'Events anzeigen', description = 'Aktuelle Events und Veranstaltungen', icon = 'calendar', onSelect = function() showEvents() end } } -- Event erstellen (nur für berechtigte Jobs) local canCreateEvents = false for _, allowedJob in pairs(Config.JobPermissions.canCreateEvents) do if job == allowedJob then canCreateEvents = true break end end if canCreateEvents then table.insert(menuOptions, { title = 'Event erstellen', description = 'Neues Event oder Veranstaltung erstellen', icon = 'plus', onSelect = function() createEventDialog() end }) table.insert(menuOptions, { title = 'Job-Angebot erstellen', description = 'Neues Job-Angebot veröffentlichen', icon = 'briefcase', onSelect = function() createJobOfferDialog() end }) end -- Vorfall melden (für alle oder spezifische Jobs) if Config.JobPermissions.canReportIncidents == 'all' or (type(Config.JobPermissions.canReportIncidents) == 'table' and table.contains(Config.JobPermissions.canReportIncidents, job)) then table.insert(menuOptions, { title = 'Vorfall melden', description = 'Einen Vorfall an die Behörden melden', icon = 'exclamation-triangle', onSelect = function() reportIncidentDialog() end }) end -- Job-spezifische Optionen if jobPermissions.showIncidents then table.insert(menuOptions, { title = 'Vorfälle anzeigen', description = 'Gemeldete Vorfälle einsehen', icon = 'list', onSelect = function() showIncidents() end }) end if jobPermissions.showJobOffers then table.insert(menuOptions, { title = 'Job-Angebote', description = 'Verfügbare Job-Angebote anzeigen', icon = 'briefcase', onSelect = function() showJobOffers() end }) end if jobPermissions.showLicenseInfo then table.insert(menuOptions, { title = 'Lizenz Informationen', description = 'Informationen zu verfügbaren Lizenzen', icon = 'id-card', onSelect = function() showLicenseInfo() end }) end lib.registerContext({ id = 'infopoint_main', title = currentInfoPoint.name .. ' - Infopoint', options = menuOptions }) lib.showContext('infopoint_main') end -- Events anzeigen function showEvents() QBCore.Functions.TriggerCallback('infopoint:getEvents', function(events) local eventOptions = {} if #events == 0 then table.insert(eventOptions, { title = 'Keine Events verfügbar', description = 'Derzeit sind keine Events geplant', icon = 'info' }) else for _, event in pairs(events) do local eventDate = event.event_date and os.date('%d.%m.%Y %H:%M', os.time({ year = tonumber(string.sub(event.event_date, 1, 4)), month = tonumber(string.sub(event.event_date, 6, 7)), day = tonumber(string.sub(event.event_date, 9, 10)), hour = tonumber(string.sub(event.event_date, 12, 13)), min = tonumber(string.sub(event.event_date, 15, 16)) })) or 'Kein Datum' table.insert(eventOptions, { title = event.title, description = 'Datum: ' .. eventDate .. '\nOrt: ' .. (event.location or 'Nicht angegeben') .. '\nErstellt von: ' .. event.created_by_name, icon = 'calendar', onSelect = function() showEventDetails(event) end }) end end table.insert(eventOptions, { title = '← Zurück', icon = 'arrow-left', onSelect = function() openInfoPointMenu() end }) lib.registerContext({ id = 'infopoint_events', title = 'Events & Veranstaltungen', options = eventOptions }) lib.showContext('infopoint_events') end) end -- Event Details anzeigen function showEventDetails(event) local eventDate = event.event_date and os.date('%d.%m.%Y %H:%M', os.time({ year = tonumber(string.sub(event.event_date, 1, 4)), month = tonumber(string.sub(event.event_date, 6, 7)), day = tonumber(string.sub(event.event_date, 9, 10)), hour = tonumber(string.sub(event.event_date, 12, 13)), min = tonumber(string.sub(event.event_date, 15, 16)) })) or 'Kein Datum' lib.alertDialog({ header = event.title, content = 'Kategorie: ' .. (event.category or 'Keine') .. '\n\n' .. 'Datum: ' .. eventDate .. '\n\n' .. 'Ort: ' .. (event.location or 'Nicht angegeben') .. '\n\n' .. 'Beschreibung:\n' .. (event.description or 'Keine Beschreibung verfügbar') .. '\n\n' .. 'Erstellt von: ' .. event.created_by_name, centered = true, cancel = true }) end -- Event erstellen Dialog function createEventDialog() local input = lib.inputDialog('Event erstellen', { {type = 'input', label = 'Titel', required = true, max = 100}, {type = 'textarea', label = 'Beschreibung', max = 500}, {type = 'select', label = 'Kategorie', options = Config.EventCategories, required = true}, {type = 'input', label = 'Ort', max = 100}, {type = 'date', label = 'Datum', required = true}, {type = 'time', label = 'Uhrzeit', required = true} }) if input then local eventData = { title = input[1], description = input[2], category = input[3], location = input[4], date = input[5] .. ' ' .. input[6] .. ':00' } TriggerServerEvent('infopoint:createEvent', eventData) end end -- Vorfälle anzeigen function showIncidents() QBCore.Functions.TriggerCallback('infopoint:getIncidents', function(incidents) local incidentOptions = {} if #incidents == 0 then table.insert(incidentOptions, { title = 'Keine Vorfälle', description = 'Derzeit sind keine Vorfälle gemeldet', icon = 'info' }) else for _, incident in pairs(incidents) do local statusColor = incident.status == 'open' and '🔴' or '🟢' local createdDate = os.date('%d.%m.%Y %H:%M', os.time({ year = tonumber(string.sub(incident.created_at, 1, 4)), month = tonumber(string.sub(incident.created_at, 6, 7)), day = tonumber(string.sub(incident.created_at, 9, 10)), hour = tonumber(string.sub(incident.created_at, 12, 13)), min = tonumber(string.sub(incident.created_at, 15, 16)) })) table.insert(incidentOptions, { title = statusColor .. ' ' .. incident.title, description = 'Gemeldet: ' .. createdDate .. '\nOrt: ' .. (incident.location or 'Nicht angegeben') .. '\nStatus: ' .. incident.status, icon = 'exclamation-triangle', onSelect = function() showIncidentDetails(incident) end }) end end table.insert(incidentOptions, { title = '← Zurück', icon = 'arrow-left', onSelect = function() openInfoPointMenu() end }) lib.registerContext({ id = 'infopoint_incidents', title = 'Gemeldete Vorfälle', options = incidentOptions }) lib.showContext('infopoint_incidents') end) end -- Vorfall Details anzeigen function showIncidentDetails(incident) local createdDate = os.date('%d.%m.%Y %H:%M', os.time({ year = tonumber(string.sub(incident.created_at, 1, 4)), month = tonumber(string.sub(incident.created_at, 6, 7)), day = tonumber(string.sub(incident.created_at, 9, 10)), hour = tonumber(string.sub(incident.created_at, 12, 13)), min = tonumber(string.sub(incident.created_at, 15, 16)) })) lib.alertDialog({ header = incident.title, content = 'Kategorie: ' .. (incident.category or 'Keine') .. '\n\n' .. 'Gemeldet am: ' .. createdDate .. '\n\n' .. 'Ort: ' .. (incident.location or 'Nicht angegeben') .. '\n\n' .. 'Status: ' .. incident.status .. '\n\n' .. 'Beschreibung:\n' .. (incident.description or 'Keine Beschreibung verfügbar') .. '\n\n' .. 'Gemeldet von: ' .. incident.reported_by_name, centered = true, cancel = true }) end -- Vorfall melden Dialog function reportIncidentDialog() local input = lib.inputDialog('Vorfall melden', { {type = 'input', label = 'Titel', required = true, max = 100}, {type = 'textarea', label = 'Beschreibung', required = true, max = 500}, {type = 'select', label = 'Kategorie', options = Config.IncidentCategories, required = true}, {type = 'input', label = 'Ort', max = 100} }) if input then local incidentData = { title = input[1], description = input[2], category = input[3], location = input[4] } TriggerServerEvent('infopoint:reportIncident', incidentData) end end -- Job-Angebote anzeigen function showJobOffers() local PlayerData = QBCore.Functions.GetPlayerData() local job = PlayerData.job.name QBCore.Functions.TriggerCallback('infopoint:getJobOffers', function(offers) local offerOptions = {} if #offers == 0 then table.insert(offerOptions, { title = 'Keine Job-Angebote', description = 'Derzeit sind keine Job-Angebote verfügbar', icon = 'info' }) else for _, offer in pairs(offers) do table.insert(offerOptions, { title = offer.title, description = 'Job: ' .. offer.job_name .. '\nGehalt: ' .. (offer.salary or 'Verhandelbar') .. '\nKontakt: ' .. (offer.contact or 'Nicht angegeben'), icon = 'briefcase', onSelect = function() showJobOfferDetails(offer) end }) end end table.insert(offerOptions, { title = '← Zurück', icon = 'arrow-left', onSelect = function() openInfoPointMenu() end }) lib.registerContext({ id = 'infopoint_job_offers', title = 'Job-Angebote', options = offerOptions }) lib.showContext('infopoint_job_offers') end, nil) end -- Job-Angebot Details anzeigen function showJobOfferDetails(offer) lib.alertDialog({ header = offer.title, content = 'Job: ' .. offer.job_name .. '\n\n' .. 'Gehalt: ' .. (offer.salary or 'Verhandelbar') .. '\n\n' .. 'Kontakt: ' .. (offer.contact or 'Nicht angegeben') .. '\n\n' .. 'Anforderungen:\n' .. (offer.requirements or 'Keine besonderen Anforderungen') .. '\n\n' .. 'Beschreibung:\n' .. (offer.description or 'Keine Beschreibung verfügbar'), centered = true, cancel = true }) end -- Job-Angebot erstellen Dialog function createJobOfferDialog() local input = lib.inputDialog('Job-Angebot erstellen', { {type = 'input', label = 'Titel', required = true, max = 100}, {type = 'textarea', label = 'Beschreibung', max = 500}, {type = 'textarea', label = 'Anforderungen', max = 300}, {type = 'input', label = 'Gehalt', max = 50}, {type = 'input', label = 'Kontakt', max = 100} }) if input then local jobData = { title = input[1], description = input[2], requirements = input[3], salary = input[4], contact = input[5] } TriggerServerEvent('infopoint:createJobOffer', jobData) end end -- Lizenz Informationen anzeigen function showLicenseInfo() QBCore.Functions.TriggerCallback('infopoint:getLicenseInfo', function(licenses) local licenseOptions = {} if #licenses == 0 then table.insert(licenseOptions, { title = 'Keine Informationen verfügbar', description = 'Du hast keine Berechtigung diese Informationen zu sehen', icon = 'info' }) else for _, license in pairs(licenses) do table.insert(licenseOptions, { title = license.type, description = 'Preis: ' .. license.price .. '\nAnforderungen: ' .. license.requirements, icon = 'id-card' }) end end table.insert(licenseOptions, { title = '← Zurück', icon = 'arrow-left', onSelect = function() openInfoPointMenu() end }) lib.registerContext({ id = 'infopoint_licenses', title = 'Lizenz Informationen', options = licenseOptions }) lib.showContext('infopoint_licenses') end) end -- Hilfsfunktion für table.contains function table.contains(table, element) for _, value in pairs(table) do if value == element then return true end end return false end -- Event Listener für Daten-Refresh RegisterNetEvent('infopoint:refreshData', function() -- Hier könntest du lokale Daten aktualisieren wenn nötig end)