Interface medicale NUI pour FiveM, pensee comme un template configurable.
Le but du projet est simple:
- personnaliser rapidement le branding et les couleurs
- brancher facilement l'UI sur n'importe quel script EMS / medical
- garder un contrat NUI clair pour envoyer les donnees et recuperer les actions
- FiveM / NUI
- React 18
- Vite
- JavaScript / JSX
- TailwindCSS v4
EMS_UI/
|-- fxmanifest.lua
|-- README.md
|-- screens/
`-- ui/
|-- package.json
|-- src/
| |-- App.jsx
| |-- MedicalUI.jsx
| |-- components/
| |-- config/
| | |-- boneMap.js
| | `-- config.js
| `-- utils/
`-- dist/- Place la ressource dans le dossier
resourcesde ton serveur. - Installe les dependances front:
cd ui
npm install- Build la NUI:
npm run build- Ajoute la ressource dans ton
server.cfg:
ensure <nom-de-ton-dossier>Le fichier principal a modifier est:
ui/src/config/config.js
Tu peux y changer:
- le nom du serveur
- le nom du service EMS
- le titre de la fenetre
- toutes les couleurs de l'interface
- les labels affiches
- les boutons de soin
- les noms des events NUI
- le mode
showcasepour tester l'UI sans FiveM
Exemple:
export const templateConfig = {
branding: {
serverName: "Mon Serveur",
serviceName: "SAMS",
panelTitle: "Examen medical",
},
theme: {
colors: {
primary: "#F97316",
accent: "#DC2626",
success: "#22C55E",
bgPrimary: "rgba(17, 24, 39, 0.96)",
},
},
};Apres modification de la config:
cd ui
npm run buildTu peux aussi envoyer une config partielle au moment de l'ouverture de l'UI avec uiConfig.
Cette config est fusionnee avec celle du fichier ui/src/config/config.js.
Exemple:
SendNUIMessage({
action = "openUI",
uiConfig = {
branding = {
serverName = "Mon Serveur",
serviceName = "EMS",
panelTitle = "Diagnostic medical"
},
theme = {
colors = {
primary = "#0EA5E9",
accent = "#EF4444"
}
}
}
})Par defaut, l'interface ecoute ces actions:
openUIupdateInjuriescloseUI
Les noms peuvent etre modifies dans ui/src/config/config.js via nui.incomingActions.
SetNuiFocus(true, true)
SendNUIMessage({
action = "openUI",
targetId = 27,
gender = "male",
injuries = {
{
boneName = "tete",
type = "Contusion",
severity = "Legere",
description = "Choc frontal",
bleeding = false
},
{
boneName = "bras gauche",
type = "Fracture",
severity = "Grave",
description = "Suspicion de fracture du radius",
bleeding = true
},
{
boneName = "abdomen",
type = "Hemorragie",
severity = "Critique",
description = "Saignement interne suspecte",
bleeding = true
}
}
})Champs utiles:
action: nom de l'action NUItargetId: id du joueur examinegender:maleoufemaleinjuries: liste simple de blessuresbodyParts: format avance si tu veux envoyer l'etat deja groupe par zoneselectedPart: zone a preselectionneruiConfig: override runtime optionnel
SendNUIMessage({
action = "updateInjuries",
injuries = {
{
boneName = "jambe droite",
type = "Brulure",
severity = "Moyenne",
description = "Brulure du mollet",
bleeding = false
}
}
})SetNuiFocus(false, false)
SendNUIMessage({
action = "closeUI"
})Le format recommande est une liste simple:
injuries = {
{
boneName = "bras gauche",
type = "Fracture",
severity = "Grave",
description = "Fracture ouverte",
bleeding = true
}
}Champs supportes:
boneName: nom de la zone envoyee depuis ton scripttype: nom de la blessureseverity: gravite affichee dans l'UIdescription: detail librebleeding:trueoufalse
Le mapping des zones est gere dans:
ui/src/config/boneMap.js
Exemples de noms reconnus:
teteabdomenbras gauchebras droitjambe gauchejambe droitecorps entier
Si besoin, ajoute simplement tes propres alias dans boneMap.js.
Si ton script possede deja les donnees groupees par zone, tu peux envoyer directement bodyParts:
SendNUIMessage({
action = "openUI",
bodyParts = {
head = {
name = "Tete",
injuries = {
{
type = "Contusion",
severity = "Legere",
description = "Choc temporal",
bleeding = false
}
}
},
leftArm = {
name = "Bras gauche",
injuries = {
{
type = "Fracture",
severity = "Grave",
description = "Radius touche",
bleeding = true
}
}
}
}
})Cles supportees:
fullBodyheadchestabdomenleftArmrightArmleftLegrightLeg
Par defaut, la NUI renvoie ces callbacks:
nuiReadycloseUIuseCare
Les noms peuvent etre modifies dans ui/src/config/config.js via nui.callbacks.
Envoye au chargement initial de l'UI.
Payload:
{ "ready": true }Envoye quand le joueur ferme l'interface depuis le bouton ou Escape.
Payload:
{}Envoye quand le joueur clique sur un soin.
Payload exemple:
{
"careId": "bandage",
"careLabel": "Bandage",
"targetId": 27,
"bodyPart": "leftArm",
"injuryIndex": 1,
"injury": {
"type": "Fracture",
"severity": "Grave",
"description": "Suspicion de fracture du radius",
"bleeding": true,
"sourceLabel": "bras gauche"
}
}Exemple Lua:
RegisterNUICallback("nuiReady", function(data, cb)
cb({ ok = true })
end)
RegisterNUICallback("closeUI", function(data, cb)
SetNuiFocus(false, false)
cb({ ok = true })
end)
RegisterNUICallback("useCare", function(data, cb)
print(("Soin demande: %s sur %s"):format(data.careId, data.bodyPart))
-- data.targetId
-- data.injuryIndex
-- data.injury.type
-- data.injury.severity
-- data.injury.description
-- data.injury.bleeding
cb({ ok = true })
end)Pour lancer l'interface en local:
cd ui
npm run devPour afficher l'UI sans FiveM:
- active
showcase.enabled = truedansui/src/config/config.js - lance
npm run dev
Verification utile avant publication:
cd ui
npm run lint
npm run buildui/distest genere par Vite: ne pas le modifier a la main.fxmanifest.luachargeui/dist/index.htmlcomme page NUI.- L'UI est volontairement orientee template: la logique medicale et les validations doivent rester dans ton script Lua.
- Auteur: NRW
