ed
This commit is contained in:
		
							parent
							
								
									e3605df057
								
							
						
					
					
						commit
						db8f07a192
					
				
					 3 changed files with 798 additions and 0 deletions
				
			
		
							
								
								
									
										489
									
								
								resources/[tools]/nordi_infopoint/client/main.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										489
									
								
								resources/[tools]/nordi_infopoint/client/main.lua
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,489 @@
 | 
			
		|||
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)
 | 
			
		||||
							
								
								
									
										101
									
								
								resources/[tools]/nordi_infopoint/config.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								resources/[tools]/nordi_infopoint/config.lua
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
Config = {}
 | 
			
		||||
 | 
			
		||||
-- Infopoint Standorte
 | 
			
		||||
Config.InfoPoints = {
 | 
			
		||||
    {
 | 
			
		||||
        id = 1,
 | 
			
		||||
        name = "Polizei Station",
 | 
			
		||||
        coords = vector3(428.23, -984.28, 30.71),
 | 
			
		||||
        blip = {
 | 
			
		||||
            sprite = 480,
 | 
			
		||||
            color = 3,
 | 
			
		||||
            scale = 0.8,
 | 
			
		||||
            display = true
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        id = 2,
 | 
			
		||||
        name = "Krankenhaus",
 | 
			
		||||
        coords = vector3(307.7, -1433.4, 29.8),
 | 
			
		||||
        blip = {
 | 
			
		||||
            sprite = 61,
 | 
			
		||||
            color = 2,
 | 
			
		||||
            scale = 0.8,
 | 
			
		||||
            display = true
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        id = 3,
 | 
			
		||||
        name = "Rathaus Sandy",
 | 
			
		||||
        coords = vector3(1746.17, 3788.09, 35.55),
 | 
			
		||||
        blip = {
 | 
			
		||||
            sprite = 419,
 | 
			
		||||
            color = 5,
 | 
			
		||||
            scale = 0.8,
 | 
			
		||||
            display = true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- Job Berechtigungen
 | 
			
		||||
Config.JobPermissions = {
 | 
			
		||||
    -- Wer kann Events erstellen
 | 
			
		||||
    canCreateEvents = {
 | 
			
		||||
        'police', 'ambulance', 'mechanic', 'realestate', 'taxi', 'burgershot', 'kayas',
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
    -- Wer kann Vorfälle melden
 | 
			
		||||
    canReportIncidents = 'all', -- 'all' für alle, oder spezifische Jobs als Table
 | 
			
		||||
    
 | 
			
		||||
    -- Spezielle Job Informationen
 | 
			
		||||
    jobSpecificInfo = {
 | 
			
		||||
        ['police'] = {
 | 
			
		||||
            showIncidents = true,
 | 
			
		||||
            showJobOffers = true,
 | 
			
		||||
            showLicenseInfo = true,
 | 
			
		||||
            showCriminalRecords = true
 | 
			
		||||
        },
 | 
			
		||||
        ['ambulance'] = {
 | 
			
		||||
            showIncidents = true,
 | 
			
		||||
            showJobOffers = true,
 | 
			
		||||
            showMedicalRecords = true
 | 
			
		||||
        },
 | 
			
		||||
        ['mechanic'] = {
 | 
			
		||||
            showJobOffers = true,
 | 
			
		||||
            showVehicleInfo = true
 | 
			
		||||
        },
 | 
			
		||||
        ['realestate'] = {
 | 
			
		||||
            showJobOffers = true,
 | 
			
		||||
            showPropertyInfo = true
 | 
			
		||||
        },
 | 
			
		||||
        ['taxi'] = {
 | 
			
		||||
            showJobOffers = true
 | 
			
		||||
        },
 | 
			
		||||
        ['burgershot'] = {
 | 
			
		||||
            showJobOffers = true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- Vorfall Kategorien
 | 
			
		||||
Config.IncidentCategories = {
 | 
			
		||||
    'Diebstahl',
 | 
			
		||||
    'Vandalismus',
 | 
			
		||||
    'Ruhestörung',
 | 
			
		||||
    'Verkehrsunfall',
 | 
			
		||||
    'Verdächtige Aktivität',
 | 
			
		||||
    'Drogen',
 | 
			
		||||
    'Gewalt',
 | 
			
		||||
    'Sonstiges'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- Event Kategorien
 | 
			
		||||
Config.EventCategories = {
 | 
			
		||||
    'Öffentliche Veranstaltung',
 | 
			
		||||
    'Job Event',
 | 
			
		||||
    'Training',
 | 
			
		||||
    'Meeting',
 | 
			
		||||
    'Party',
 | 
			
		||||
    'Rennen',
 | 
			
		||||
    'Sonstiges'
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										208
									
								
								resources/[tools]/nordi_infopoint/server/main.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								resources/[tools]/nordi_infopoint/server/main.lua
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,208 @@
 | 
			
		|||
local QBCore = exports['qb-core']:GetCoreObject()
 | 
			
		||||
 | 
			
		||||
-- Datenbank Setup
 | 
			
		||||
CreateThread(function()
 | 
			
		||||
    MySQL.query([[
 | 
			
		||||
        CREATE TABLE IF NOT EXISTS infopoint_events (
 | 
			
		||||
            id INT AUTO_INCREMENT PRIMARY KEY,
 | 
			
		||||
            title VARCHAR(255) NOT NULL,
 | 
			
		||||
            description TEXT,
 | 
			
		||||
            category VARCHAR(100),
 | 
			
		||||
            location VARCHAR(255),
 | 
			
		||||
            event_date DATETIME,
 | 
			
		||||
            created_by VARCHAR(50),
 | 
			
		||||
            created_by_name VARCHAR(255),
 | 
			
		||||
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
            active BOOLEAN DEFAULT TRUE
 | 
			
		||||
        )
 | 
			
		||||
    ]])
 | 
			
		||||
    
 | 
			
		||||
    MySQL.query([[
 | 
			
		||||
        CREATE TABLE IF NOT EXISTS infopoint_incidents (
 | 
			
		||||
            id INT AUTO_INCREMENT PRIMARY KEY,
 | 
			
		||||
            title VARCHAR(255) NOT NULL,
 | 
			
		||||
            description TEXT,
 | 
			
		||||
            category VARCHAR(100),
 | 
			
		||||
            location VARCHAR(255),
 | 
			
		||||
            reported_by VARCHAR(50),
 | 
			
		||||
            reported_by_name VARCHAR(255),
 | 
			
		||||
            status VARCHAR(50) DEFAULT 'open',
 | 
			
		||||
            assigned_to VARCHAR(50),
 | 
			
		||||
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 | 
			
		||||
        )
 | 
			
		||||
    ]])
 | 
			
		||||
    
 | 
			
		||||
    MySQL.query([[
 | 
			
		||||
        CREATE TABLE IF NOT EXISTS infopoint_job_offers (
 | 
			
		||||
            id INT AUTO_INCREMENT PRIMARY KEY,
 | 
			
		||||
            job_name VARCHAR(100),
 | 
			
		||||
            title VARCHAR(255),
 | 
			
		||||
            description TEXT,
 | 
			
		||||
            requirements TEXT,
 | 
			
		||||
            salary VARCHAR(100),
 | 
			
		||||
            contact VARCHAR(255),
 | 
			
		||||
            created_by VARCHAR(50),
 | 
			
		||||
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
            active BOOLEAN DEFAULT TRUE
 | 
			
		||||
        )
 | 
			
		||||
    ]])
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Events abrufen
 | 
			
		||||
QBCore.Functions.CreateCallback('infopoint:getEvents', function(source, cb)
 | 
			
		||||
    MySQL.query('SELECT * FROM infopoint_events WHERE active = 1 ORDER BY event_date ASC', {}, function(result)
 | 
			
		||||
        cb(result)
 | 
			
		||||
    end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Vorfälle abrufen (nur für berechtigte Jobs)
 | 
			
		||||
QBCore.Functions.CreateCallback('infopoint:getIncidents', function(source, cb)
 | 
			
		||||
    local Player = QBCore.Functions.GetPlayer(source)
 | 
			
		||||
    if not Player then return cb({}) end
 | 
			
		||||
    
 | 
			
		||||
    local job = Player.PlayerData.job.name
 | 
			
		||||
    if Config.JobPermissions.jobSpecificInfo[job] and Config.JobPermissions.jobSpecificInfo[job].showIncidents then
 | 
			
		||||
        MySQL.query('SELECT * FROM infopoint_incidents ORDER BY created_at DESC', {}, function(result)
 | 
			
		||||
            cb(result)
 | 
			
		||||
        end)
 | 
			
		||||
    else
 | 
			
		||||
        cb({})
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Job Angebote abrufen
 | 
			
		||||
QBCore.Functions.CreateCallback('infopoint:getJobOffers', function(source, cb, jobName)
 | 
			
		||||
    local query = 'SELECT * FROM infopoint_job_offers WHERE active = 1'
 | 
			
		||||
    local params = {}
 | 
			
		||||
    
 | 
			
		||||
    if jobName then
 | 
			
		||||
        query = query .. ' AND job_name = ?'
 | 
			
		||||
        params = {jobName}
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    query = query .. ' ORDER BY created_at DESC'
 | 
			
		||||
    
 | 
			
		||||
    MySQL.query(query, params, function(result)
 | 
			
		||||
        cb(result)
 | 
			
		||||
    end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Lizenz Informationen abrufen
 | 
			
		||||
QBCore.Functions.CreateCallback('infopoint:getLicenseInfo', function(source, cb)
 | 
			
		||||
    local Player = QBCore.Functions.GetPlayer(source)
 | 
			
		||||
    if not Player then return cb({}) end
 | 
			
		||||
    
 | 
			
		||||
    local job = Player.PlayerData.job.name
 | 
			
		||||
    if job == 'police' then
 | 
			
		||||
        -- Hier könntest du Lizenz-Informationen aus der Datenbank abrufen
 | 
			
		||||
        local licenseInfo = {
 | 
			
		||||
            {type = 'Führerschein', price = '$500', requirements = 'Theorieprüfung bestehen'},
 | 
			
		||||
            {type = 'Waffenschein', price = '$2000', requirements = 'Saubere Akte, Prüfung'},
 | 
			
		||||
            {type = 'Pilotenschein', price = '$10000', requirements = 'Flugstunden nachweisen'}
 | 
			
		||||
        }
 | 
			
		||||
        cb(licenseInfo)
 | 
			
		||||
    else
 | 
			
		||||
        cb({})
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Event erstellen
 | 
			
		||||
RegisterNetEvent('infopoint:createEvent', function(eventData)
 | 
			
		||||
    local src = source
 | 
			
		||||
    local Player = QBCore.Functions.GetPlayer(src)
 | 
			
		||||
    if not Player then return end
 | 
			
		||||
    
 | 
			
		||||
    local job = Player.PlayerData.job.name
 | 
			
		||||
    local canCreate = false
 | 
			
		||||
    
 | 
			
		||||
    for _, allowedJob in pairs(Config.JobPermissions.canCreateEvents) do
 | 
			
		||||
        if job == allowedJob then
 | 
			
		||||
            canCreate = true
 | 
			
		||||
            break
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    if not canCreate then
 | 
			
		||||
        TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung Events zu erstellen!', 'error')
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    MySQL.insert('INSERT INTO infopoint_events (title, description, category, location, event_date, created_by, created_by_name) VALUES (?, ?, ?, ?, ?, ?, ?)', {
 | 
			
		||||
        eventData.title,
 | 
			
		||||
        eventData.description,
 | 
			
		||||
        eventData.category,
 | 
			
		||||
        eventData.location,
 | 
			
		||||
        eventData.date,
 | 
			
		||||
        Player.PlayerData.citizenid,
 | 
			
		||||
        Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
 | 
			
		||||
    }, function(insertId)
 | 
			
		||||
        if insertId then
 | 
			
		||||
            TriggerClientEvent('QBCore:Notify', src, 'Event erfolgreich erstellt!', 'success')
 | 
			
		||||
            TriggerClientEvent('infopoint:refreshData', -1)
 | 
			
		||||
        end
 | 
			
		||||
    end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Vorfall melden
 | 
			
		||||
RegisterNetEvent('infopoint:reportIncident', function(incidentData)
 | 
			
		||||
    local src = source
 | 
			
		||||
    local Player = QBCore.Functions.GetPlayer(src)
 | 
			
		||||
    if not Player then return end
 | 
			
		||||
    
 | 
			
		||||
    MySQL.insert('INSERT INTO infopoint_incidents (title, description, category, location, reported_by, reported_by_name) VALUES (?, ?, ?, ?, ?, ?)', {
 | 
			
		||||
        incidentData.title,
 | 
			
		||||
        incidentData.description,
 | 
			
		||||
        incidentData.category,
 | 
			
		||||
        incidentData.location,
 | 
			
		||||
        Player.PlayerData.citizenid,
 | 
			
		||||
        Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
 | 
			
		||||
    }, function(insertId)
 | 
			
		||||
        if insertId then
 | 
			
		||||
            TriggerClientEvent('QBCore:Notify', src, 'Vorfall erfolgreich gemeldet!', 'success')
 | 
			
		||||
            
 | 
			
		||||
            -- Benachrichtigung an alle Polizisten senden
 | 
			
		||||
            local Players = QBCore.Functions.GetQBPlayers()
 | 
			
		||||
            for _, player in pairs(Players) do
 | 
			
		||||
                if player.PlayerData.job.name == 'police' and player.PlayerData.job.onduty then
 | 
			
		||||
                    TriggerClientEvent('QBCore:Notify', player.PlayerData.source, 'Neuer Vorfall gemeldet: ' .. incidentData.title, 'primary')
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Job Angebot erstellen
 | 
			
		||||
RegisterNetEvent('infopoint:createJobOffer', function(jobData)
 | 
			
		||||
    local src = source
 | 
			
		||||
    local Player = QBCore.Functions.GetPlayer(src)
 | 
			
		||||
    if not Player then return end
 | 
			
		||||
    
 | 
			
		||||
    local job = Player.PlayerData.job.name
 | 
			
		||||
    local canCreate = false
 | 
			
		||||
    
 | 
			
		||||
    for _, allowedJob in pairs(Config.JobPermissions.canCreateEvents) do
 | 
			
		||||
        if job == allowedJob then
 | 
			
		||||
            canCreate = true
 | 
			
		||||
            break
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    if not canCreate then
 | 
			
		||||
        TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung Job-Angebote zu erstellen!', 'error')
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    MySQL.insert('INSERT INTO infopoint_job_offers (job_name, title, description, requirements, salary, contact, created_by) VALUES (?, ?, ?, ?, ?, ?, ?)', {
 | 
			
		||||
        job,
 | 
			
		||||
        jobData.title,
 | 
			
		||||
        jobData.description,
 | 
			
		||||
        jobData.requirements,
 | 
			
		||||
        jobData.salary,
 | 
			
		||||
        jobData.contact,
 | 
			
		||||
        Player.PlayerData.citizenid
 | 
			
		||||
    }, function(insertId)
 | 
			
		||||
        if insertId then
 | 
			
		||||
            TriggerClientEvent('QBCore:Notify', src, 'Job-Angebot erfolgreich erstellt!', 'success')
 | 
			
		||||
        end
 | 
			
		||||
    end)
 | 
			
		||||
end)
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue