> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shdevelopment.org/llms.txt
> Use this file to discover all available pages before exploring further.

# sh-citation: Issue Police Citations and Fines in FiveM

> sh-citation lets authorized officers issue in-game citations with a signature canvas UI. Fines deduct from the suspect's bank and log to Discord.

sh-citation gives your law enforcement players a proper citation workflow built on a Vue 3 NUI form. An authorized officer opens the panel with a single command, fills in the suspect's details and charges, draws a freehand signature on an HTML5 canvas, and submits — the fine is deducted from the suspect's bank account automatically and a formatted embed lands in your Discord log channel. Because ACE permissions gate the command, only the groups you authorize can ever open the form.

## Supported Frameworks

| Value        | Framework            |
| ------------ | -------------------- |
| `nd`         | ND\_Core (current)   |
| `ndold`      | ND\_Core v1 (legacy) |
| `nat`        | NAT2K15              |
| `standalone` | No framework         |

<Note>
  QBCore and ESX are **not** supported by sh-citation. If your server runs either of those frameworks, this resource is not compatible.
</Note>

## Dependencies

* **sh-notify** — default notification provider (bundled workflow; swap to `custom` in config if you use another system)
* **ND\_Core** — optional; uncomment the dependency line in `fxmanifest.lua` if you run ND\_Core

## ACE Permissions

sh-citation uses a single ACE node (`sh.citation`) to control who can open the citation UI. Add your law enforcement and admin groups in `server.cfg`:

```cfg server.cfg theme={null}
add_ace group.police sh.citation allow
add_ace group.admin  sh.citation allow
```

<Warning>
  Keep `Config.AcePerm = true` in production. Setting it to `false` removes the permission check and allows **any** player to open the citation form and issue fines.
</Warning>

## Configuration

All settings live in `shared/config.lua`. The values below reflect the defaults shipped with the resource.

```lua shared/config.lua theme={null}
Config.Framework = 'nd'        -- 'nd', 'ndold', 'nat', 'standalone'
Config.Notify    = 'sh'        -- 'sh' or 'custom'
Config.Command   = 'ticket'    -- Command to open the citation UI
Config.AcePerm   = true        -- Keep true for production servers

Config.EmbedOptions = {
    WebHook   = 'https://discord.com/api/webhooks/YOUR_WEBHOOK',
    Thumbnail = 'https://your-thumbnail-url.png',
    Title     = 'Citation Issued',
    Color     = 3093146,  -- Decimal color for the embed
}
```

<Tip>
  `Config.EmbedOptions.Color` expects a decimal integer, not a hex string. Use an online hex-to-decimal converter to get the right value for your preferred embed colour.
</Tip>

## Citation Form Fields

When an officer runs the configured command (default `/ticket`), the Vue 3 NUI form opens full-screen. The officer fills in the following fields before submitting:

| Field        | Description                                     |
| ------------ | ----------------------------------------------- |
| Player ID    | In-game server ID of the suspect                |
| Suspect Name | Full name of the suspect character              |
| Officer Name | Issuing officer's character name                |
| Charges      | Free-text description of the violation(s)       |
| Fine Amount  | Dollar amount to deduct from the suspect's bank |
| Signature    | Freehand signature drawn on an HTML5 canvas     |

Press **ESC** at any time to close the form without submitting. No fine is applied and no Discord log is created unless the officer clicks the submit button.

## Issuing a Citation

<Steps>
  <Step title="Ensure you have permission">
    Confirm your character's group has the `sh.citation` ACE node. If the command produces no response, ask your server admin to check the ACE assignment.
  </Step>

  <Step title="Open the citation form">
    Run the configured command (default `/ticket`) while near the suspect. The Vue 3 NUI panel opens over the game world.
  </Step>

  <Step title="Fill in the citation details">
    Enter the suspect's player ID, both character names, the charges, and the fine amount. All fields are required before submission is allowed.
  </Step>

  <Step title="Draw your signature">
    Use your mouse to draw a freehand signature on the canvas at the bottom of the form. You can clear and redraw as many times as needed.
  </Step>

  <Step title="Submit the citation">
    Click **Submit**. The script deducts the fine from the suspect's bank account and sends the Discord embed to your configured webhook.
  </Step>
</Steps>

## Discord Embed

Every submitted citation creates a Discord embed in the channel attached to your webhook. The embed includes:

* Player ID and suspect name
* Issuing officer's name
* Charges listed
* Fine amount applied
* Your configured thumbnail image

The embed colour is set by `Config.EmbedOptions.Color` in decimal format. The `Title` field appears as the embed header.

## Installation

<Steps>
  <Step title="Add to server.cfg">
    Ensure sh-citation after its dependencies:

    ```cfg server.cfg theme={null}
    ensure sh-notify
    ensure sh-citation
    ```

    If you use ND\_Core, uncomment the ND\_Core dependency line in `fxmanifest.lua` before starting the resource.
  </Step>

  <Step title="Set your framework">
    Open `shared/config.lua` and set `Config.Framework`:

    ```lua theme={null}
    Config.Framework = 'nd'  -- change to 'ndold', 'nat', or 'standalone'
    ```
  </Step>

  <Step title="Add ACE permissions">
    Add the `sh.citation` ACE node to every group that should issue citations:

    ```cfg server.cfg theme={null}
    add_ace group.police sh.citation allow
    ```
  </Step>

  <Step title="Configure the Discord webhook">
    Paste your webhook URL into `Config.EmbedOptions.WebHook` and set a thumbnail URL and embed colour to match your server's branding.
  </Step>

  <Step title="Restart and test">
    Restart the resource, log in as a player in the `police` group, run `/ticket`, and submit a test citation. Confirm the Discord embed arrives and the fine is deducted.
  </Step>
</Steps>

<Accordion title="Using a custom notification system">
  If your server uses a notification resource other than sh-notify, set `Config.Notify = 'custom'` and edit the notification wrapper in the client script to call your own export or event. The `'sh'` value routes all notifications through sh-notify's default export.
</Accordion>
