Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 1 addition & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,3 @@
DONT FORGET TO BUILT IT
THIS CHANGES NEEDS TO BE DONE:
```lua
CREATE TABLE IF NOT EXISTS mdt_patrols (
id VARCHAR(64) PRIMARY KEY,
name VARCHAR(64) NOT NULL,
color VARCHAR(7) NOT NULL,
zone_points LONGTEXT NULL DEFAULT NULL,
sort_order INT NOT NULL DEFAULT 0,
member_ids TEXT NOT NULL DEFAULT '[]'
);

CREATE TABLE IF NOT EXISTS `mdt_bulletin_posts` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL,
`content` LONGTEXT NOT NULL,
`author` VARCHAR(100) NOT NULL,
`author_rank` VARCHAR(100) NOT NULL DEFAULT '',
`category` VARCHAR(48) NOT NULL DEFAULT 'general',
`priority` ENUM(
'low',
'normal',
'high',
'urgent'
) NOT NULL DEFAULT 'normal',
`pinned` TINYINT(1) NOT NULL DEFAULT 0,
`job` VARCHAR(50) NOT NULL DEFAULT '',
`created_by` VARCHAR(60) NOT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_job` (`job`),
KEY `idx_category` (`category`),
KEY `idx_pinned` (`pinned`),
KEY `idx_deleted_at` (`deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `mdt_bulletin_categories` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`job` VARCHAR(50) NOT NULL,
`value` VARCHAR(48) NOT NULL,
`label` VARCHAR(48) NOT NULL,
`icon` VARCHAR(48) NOT NULL DEFAULT 'label',
`color` VARCHAR(7) NOT NULL DEFAULT '#6B7280',
`sort_order` SMALLINT NOT NULL DEFAULT 0,
`is_default` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uq_job_value` (`job`, `value`),
INDEX `idx_job_order` (`job`, `sort_order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=UTF8MB4_UNICODE_CI;
```

# ps-mdt v3

Police MDT (Mobile Data Terminal) for FiveM. Built with Svelte 5 and Lua. Works on QBCore and QBX through the ps_lib abstraction layer.
Expand Down Expand Up @@ -358,4 +305,4 @@ We host some of the biggest FiveM servers in the industry such as Prodigy RP, Sm
- Free transfer of files and setup
- Free Windows licenses
- Windows Remote Desktop
- 24/7 Support with ~30 min average ticket response
- 24/7 Support with ~30 min average ticket response
10 changes: 5 additions & 5 deletions client/animation.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local tabletProp = nil
local isPlayingTabletAnim = false
local animDict = Config.Animation and Config.Animation.Dict or 'amb@code_human_in_bus_passenger_idles@female@tablet@idle_a'
local animName = Config.Animation and Config.Animation.Name or 'idle_a'
local animDict = Config.Animation and Config.Animation.Dict or 'amb@world_human_tourist_map@male@base'
local animName = Config.Animation and Config.Animation.Name or 'base'
local propModel = 'ps-mdt'

-- Helper to always get current ped (never stale)
Expand All @@ -12,10 +12,10 @@ end
-- Options ----------------------------------

local propOptions = {
xPos = -0.050, -- X-axis offset from the center of entity2
yPos = 0.0, -- Y-axis offset from the center of entity2
xPos = 0.0, -- X-axis offset from the center of entity2
yPos = -0.03, -- Y-axis offset from the center of entity2
zPos = 0.0, -- Z-axis offset from the center of entity2
xRot = 0.0, -- X-axis rotation
xRot = 20.0, -- X-axis rotation
yRot = -90.0, -- Y-axis rotation
zRot = 0.0, -- Z-axis rotation
p9 = true, -- Unknown
Expand Down
2 changes: 1 addition & 1 deletion client/backend/bodycams.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RegisterNUICallback('viewBodycam', function(data, cb)
local result = ps.callback(resourceName .. ':server:viewBodycam', bodycamId)

if result and result.success then
CloseMDT(true)
CloseMDT()
cb({ success = true })
else
cb({ success = false, message = result and result.error or 'Failed to view bodycam' })
Expand Down
86 changes: 0 additions & 86 deletions client/backend/bulletinboard.lua

This file was deleted.

2 changes: 1 addition & 1 deletion client/backend/cameras.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RegisterNUICallback('viewCamera', function(data, cb)
local result = ps.callback(resourceName .. ':server:viewCamera', cameraId)

if result and result.success then
CloseMDT(true)
CloseMDT()
cb({ success = true })
else
cb({ success = false, message = result and result.error or 'Failed to view camera' })
Expand Down
22 changes: 6 additions & 16 deletions client/backend/cases.lua
Original file line number Diff line number Diff line change
Expand Up @@ -190,22 +190,12 @@ RegisterNUICallback('addEvidenceItem', function(data, cb)
return
end

local payload = data or {}

if payload.evidence then
local result = ps.callback(
resourceName .. ':server:addEvidenceItem',
payload
)
cb(result or { success = false })
else
local result = ps.callback(
resourceName .. ':server:addEvidenceItem',
data.caseId,
data.evidence
)
cb(result or { success = false })
end
local result = ps.callback(
resourceName .. ':server:addEvidenceItem',
data.caseId,
data.evidence
)
cb(result or { success = false })
end)

RegisterNUICallback('updateEvidenceItem', function(data, cb)
Expand Down
32 changes: 0 additions & 32 deletions client/backend/citizens.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,6 @@ RegisterNUICallback('getMyProfile', function(data, cb)
cb(result or { success = false })
end)

RegisterNUICallback('getProperty', function(data, cb)
if not MDTOpen then cb({ success = false }) return end
if not data or not data.property_id then
cb({ success = false, message = 'Missing property id' })
return
end
local result = ps.callback(resourceName .. ':server:getProperty', data.property_id)
if not result or not result.success then
cb(result or { success = false, message = 'Property not found' })
return
end
if result.property and result.property.coords then
local coords = result.property.coords
local street1, street2 = GetStreetNameAtCoord(coords.x, coords.y, coords.z, 1.0)
local s1 = street1 and GetStreetNameFromHashKey(street1) or nil
local s2 = street2 and GetStreetNameFromHashKey(street2) or nil
if s1 and s1 ~= '' then
result.property.streetName = (s2 and s2 ~= '') and (s1 .. ' / ' .. s2) or s1
end
end
cb(result)
end)

-- setWaypoint: sets a GPS blip on the map from NUI coords
-- The NUI calls fetchNui('setWaypoint', { x, y }) — no server round-trip needed.
RegisterNUICallback('setWaypoint', function(data, cb)
cb({})
if not data or not data.x or not data.y then return end
SetNewWaypoint(data.x, data.y)
end)


RegisterNUICallback('getCitizens', function(data, cb)
if not MDTOpen then cb({}) return end
if type(data) ~= 'table' then
Expand Down
25 changes: 0 additions & 25 deletions client/backend/collab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,6 @@ RegisterNUICallback('syncReportData', function(data, cb)
TriggerServerEvent(resourceName .. ':server:collabSyncData', data.reportId, data.dataType, data.data)
end)

local awarenessIncomingBuffer = {}

RegisterNUICallback('syncAwareness', function(data, cb)
TriggerServerEvent(resourceName .. ':server:collabSyncAwareness', data.reportId, data.update)
cb({ ok = true })
end)

RegisterNetEvent(resourceName .. ':client:awarenessBatch')
AddEventHandler(resourceName .. ':client:awarenessBatch', function(payload)
if not payload or not payload.updates then return end
for _, u in ipairs(payload.updates) do
awarenessIncomingBuffer[#awarenessIncomingBuffer + 1] = u
end
end)

RegisterNUICallback('pollAwareness', function(data, cb)
if #awarenessIncomingBuffer == 0 then
cb({ updates = {} })
return
end
local batch = awarenessIncomingBuffer
awarenessIncomingBuffer = {}
cb({ updates = batch })
end)

-- Server push events -> forward to NUI
RegisterNetEvent(resourceName .. ':client:reportEditorJoined', function(data)
SendNUI('reportEditorJoined', data)
Expand Down
29 changes: 0 additions & 29 deletions client/backend/dashboard.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ function NUIUpdateAuth()
citizenid = playerData.citizenid,
job = playerData.job,
charinfo = playerData.charinfo,
metadata = type(playerData.metadata) == 'table' and {
callsign = playerData.metadata.callsign or '',
} or nil,
} or nil,
isLEO = isAuthorized,
onDuty = ps.getJobDuty() or false,
Expand Down Expand Up @@ -177,32 +174,6 @@ RegisterNUICallback('deleteBulletin', function(data, cb)
cb(result or { success = false })
end)

RegisterNUICallback('getBulletinCategories', function(_, cb)
local result = ps.callback(resourceName .. ':server:getBulletinCategories', false)
cb(result or {})
end)

RegisterNUICallback('saveBulletinCategories', function(data, cb)
if not data or not data.categories then
cb({ success = false, message = 'Invalid data' })
return
end

for _, cat in ipairs(data.categories) do
if type(cat.value) ~= 'string' or type(cat.label) ~= 'string' or type(cat.icon) ~= 'string' then
cb({ success = false, message = 'Malformed category entry' })
return
end
if #cat.label > 32 or #cat.icon > 48 then
cb({ success = false, message = 'Category label or icon name too long' })
return
end
end

local result = ps.callback('mdt:server:saveBulletinCategories', false, data.categories)
cb(result or { success = false, message = 'Server error' })
end)

-- RECENT REPORTS -------------------------------------

RegisterNUICallback('getRecentReports', function(data, cb)
Expand Down
10 changes: 2 additions & 8 deletions client/backend/officers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,19 @@ RegisterNUICallback('setCallsign', function(data, cb)
cb({ success = false, message = 'MDT is not open' })
return
end

if type(data) ~= 'table' or (not data.cid and not data.citizenid) or (not data.newcallsign and not data.callsign) then
cb({ success = false, message = 'Missing citizen ID or callsign' })
return
end

local result = ps.callback(resourceName .. ':server:setCallsign', {
citizenid = data.cid or data.citizenid,
callsign = data.newcallsign or data.callsign,
})
cb(result or { success = false, message = 'Failed to set callsign' })
end)

RegisterNUICallback('getCallsign', function(data, cb)
if not MDTOpen then cb({ callsign = '' }) return end
local result = ps.callback(resourceName .. ':server:getCallsign', {
citizenid = data.citizenid,
})
cb(result or { callsign = '' })
end)

-- Set Radio Frequency
RegisterNUICallback('setRadio', function(data, cb)
if not MDTOpen then
Expand Down
Loading