# Admin panel

The admin panel is built into the inventory. Everything you change there is saved in the database and applied live for every player — no restart.

## Opening it

- Type `/invadmin` (the command name is `admin.command` in `data/koja/admin.lua`).
- Or click the **Admin panel** tab in the inventory. The tab is only shown to staff.
- Optional keybind: set `admin.key` (for example `'F10'`).

`/invadmin` takes an optional page: `/invadmin items`, `/invadmin shops`, `/invadmin createItem`... and deep links such as `/invadmin item:water`, `shop:General`, `stash:police`, `bench:workshop`, `player:12`, `rarity:rare` or `track:<serial or item>`.

:::hint{type="info" title="Who can open it"}
The command itself is open to everyone, but the panel only opens for staff, and every action is checked again on the server.
Staff = players with the `admin.superAce` ace (default `group.admin`, every page), or players with a role from `data/koja/staff.lua` or the **Permissions** page.
:::

## Home

### Home

Live server stats: online players, loaded and open inventories, item definitions (file + admin), registered shops and stashes, actions logged today and security reports. **Quick links** jump to the most used tools (create item, shop or stash, inspect players, history, security, locales, permissions).

### Addon Management

Switch every feature on or off for all players: clothing as items, backpacks, mini stashes, throwing, weight effects, plate armour, item discovery, trading, hover & give, 3D shop interaction, weapon 3D attachments, multi-select, rename & describe and inventory history. Disabled features fall back to stock ox_inventory behaviour.

**Ped preview mode** switches the ped in **Your clothes** between **Clone ped** and **Pause menu ped**.

### World containers

| Section | What it does |
| --- | --- |
| **Dumpster loot** | Loot table of dumpsters: item, min, max, chance %. Empty = dumpsters stay empty |
| **Vehicle loot** | Loot of the trunks and gloveboxes of vehicles nobody owns, filled the first time they are opened |
| **Search animation** | Players rummage in the dumpster / at the trunk while its inventory is open |
| **ox_target options** | "Search dumpster", "Open trunk", stashes and evidence on ox_target (servers without `inventory:target`) |

Each search rolls up to 3 rows; a row drops with its chance and a random amount between min and max. Dumpsters already searched keep their contents until the server restarts.

## Items

### Create Item / Edit Item

The item list has search, filters (rarity, source: `data/items.lua` or admin created), column picker, and actions **Edit**, **Duplicate**, **Track item** and **Delete** (admin created items only).

The editor:

| Section | Fields |
| --- | --- |
| **Identity** | Item name (cannot be renamed later), display label, description (Markdown in the tooltip), image (filename, HTTPS URL or `nui://` path), rarity |
| **Inventory rules** | Weight, stackable, close inventory on use, unique, consume, degrade (minutes), durability, decay, hidden / disabled |
| **Use experience** | Use time, animation and prop preset (key or JSON), status change (hunger, thirst, stress), success notification, cancelable, block movement / vehicle / combat, usable while armed |
| **Special behaviour** | Throwable, world prop, mini stash (slots, max weight, whitelist), backpack (extra slots, extra weight), plate armour |
| **Weapon definition** | Runtime fields of weapons from `data/weapons.lua` (read only where it applies) |

Saving updates loaded inventories immediately. Custom Lua functions in `data/items.lua` stay untouched. **Hidden / disabled** keeps the definition but blocks creating and using the item.

### Edit Rarity

Name, label, colour, **Discovery time** (seconds an item stays "Discovering..." in other inventories) and **Enable reveal timer** (countdown on the slot). Deleting a rarity makes its items `common`.

### Crafting benches

A list of every bench (from `data/crafting.lua` or created in the panel) and an editor:

| Section | Fields |
| --- | --- |
| **Basic properties** | Bench id (cannot be changed later), display name |
| **Access** | Optional job / group restriction with a minimum grade |
| **Recipes** | Result item, count, max count (random amount), duration (ms), metadata (JSON), ingredients. Ingredients below 1 are tools that lose that fraction of durability |
| **Locations** | Points with a marker and **[E]**. **Add my position** fills your coords |
| **Target zones** | ox_target box zones (size, rotation, distance). Empty = one zone at every location |
| **Map blip** | Sprite, colour, scale |

Saved benches apply live (recipes, markers, zones, blip). A bench from the file is overridden by the saved version; **Restore file version** brings the file definition back. Deleted file benches stay deleted after restarts until restored.

## Players

A live list of online players (search by name, identifier or server id, auto refresh) and their inventory. Select an item to:

- see and **edit the instance** — its metadata as JSON (label, description, durability, serial, ammo, components...),
- **remove** it (with an amount),
- **track** it in the history.

**Inspect in game** opens the player's inventory read-only in your own inventory window.

## History

The audit log of every inventory action, stored in SQL, so it survives restarts.

- Filters: action, free search (player, identifier, item, serial, inventory) and paging.
- Actions: transfer / move, give, drop, pickup, purchase, craft, use, trade, throw, rename, clothing, stash, open, close and admin add / edit / remove.
- **Track item**: enter a serial number or an item name to see **Live locations** (where it is now in loaded inventories) and its recorded movement.

Rows older than `history.retentionDays` (30) are removed automatically.

## Security

| Section | What it shows |
| --- | --- |
| Stats | Online players, loaded / open inventories, drops, blocked, critical and warnings |
| **Reports** | Rejected or flagged inventory operations, filterable by kind |
| **Events** | Net events the inventory exposes |
| **Hooks** | `exports.ox_inventory:registerHook` callbacks registered by other resources |
| Startup convars | Weapon mismatch, suppress pickups, disable weapons, network dumpsters, target — read only |

**Settings** (applied live and saved):

| Setting | What it does |
| --- | --- |
| **Emergency inventory lock** | Blocks every new inventory open. Not saved after a restart |
| **Auto-kick severe violations** | Drops players triggering malformed or exploit-looking requests |
| **Distance validation** | Rejects opens and drops from too far away |
| **Log hook rejections** | Prints registered hook rejections to the console |
| **Trim vehicle plates** | Normalises plates before resolving trunk and glovebox ids |
| **Log level** | `0` disables transfer logs; higher levels add detail |
| Evidence grade | Minimum police grade for evidence lockers |
| **Event retention** | Recent security events kept in memory |
| **Allowed remote image hosts** | Hosts accepted for metadata image URLs |

## Clothing

| Setting | What it does |
| --- | --- |
| **Enable clothing inventory** | Players undress into items and wear items from the inventory |
| **Image resource** | Resource exporting `getClothingImage` (illenium-appearance / Koja Appearance). Empty = generic icons only |
| **Generic slot icons fallback** | Items without `metadata.imageurl` fall back to `web/images/clothing_<slot>.png` or an icon |
| **Hidden slots** | Slots tracked as worn but not shown in **Your clothes** |

## Shops

### Create Shop / Edit Shop

| Section | Fields |
| --- | --- |
| **Basic properties** | Shop type key (used with `exports.ox_inventory:openInventory('shop', { type = key })`), display name, label |
| **Payment methods** | Cash (inventory money) and / or Card (bank account) |
| **Access** | Optional job / group restriction with a minimum grade |
| **Products** | Item, price, currency (`money` or any item), stock count (empty = unlimited, shared by every player), licence, minimum grade, metadata (JSON) |
| **Locations** | World points (markers / 3D prompt). **Use my position** fills your coords |
| **Built-in interaction** | Floating key prompt at every point: on / off, distance, key, optional label |
| **Target zones** | ox_target box zones and the interaction icon |
| **Map blip** | Sprite, colour, scale |

Changes apply live. Shops from `data/shops.lua` are overridden by the saved definition; deleting one restores the file version after a restart.

## Stashes

### Create Stash / Edit Stash

| Field | What it does |
| --- | --- |
| **Stash id** | Unique, cannot be changed later |
| **Display label**, **Slots**, **Max weight** | As in `RegisterStash` |
| **Ownership** | Shared, one copy per player, or a fixed owner identifier |
| **Access groups** | Jobs / groups with a minimum grade |
| **World location** | Optional point; **Built-in interaction** shows a floating key prompt there |

Stashes are registered live with `exports.ox_inventory:RegisterStash`. Players who have the stash open keep their view until they reopen it. Deleting a stash keeps its items in the database.

## Permissions

**Roles** have a checkbox per section: View Home, Manage Addons, Items, Rarities, Players, History, Security, Clothing, Shops, Stashes, Permissions and Locales (plus Attachments for weapon marker offsets). **Grant all** / **Revoke all** set every box.

The default roles (`owner`, `admin`, `moderator`, `support`) come from `data/koja/admin.lua` on first start.

**Staff** lists identifiers with a role. Add one with an identifier (`license:...`, `discord:...`, `fivem:...`) or the server id of an online player. The ace `group.admin` always has full access.

:::hint{type="warning" title="Permissions grants full control"}
A role with the **Permissions** section can give itself every other section. Give it only to owners.
:::

## Locales

Edit every string of the inventory and the admin panel live, per language.

- Search keys or text, show **Only changed**, **Reset to default** per key.
- **Add language** starts as a copy of the defaults; save to create it.
- **Import JSON** / **Export JSON** with a flat `{ "key": "text" }` object.
- Saved strings are pushed to all players at once and stored in `koja_inv_locales`.

See [Translations](/new/inventory/translations).
