# Client Exports

## 0R SmartTab — Client Exports Reference

Complete reference for every client-side export available in **0r-smarttab**.

```lua
-- Usage from any other client script
exports['0r-smarttab']:ExportName(...)
```

> All exports below run on the **client** and apply to the **local player** unless stated otherwise.

***

### Table of Contents

| #  | Export                      | Category       | Async          |
| -- | --------------------------- | -------------- | -------------- |
| 1  | IsTabletOpen                | Tablet State   | No             |
| 2  | OpenTabletWithApp           | Tablet Control | No             |
| 3  | SendNotification            | Notifications  | No             |
| 4  | SetAppBadge                 | Notifications  | No             |
| 5  | GetPlayerByTabletSerial     | Tablet Lookup  | Yes (callback) |
| 6  | GetPlayerInvoiceList        | Billing        | Yes (callback) |
| 7  | GetPlayerInvoiceCount       | Billing        | Yes (callback) |
| 8  | GetPlayerUnpaidInvoiceCount | Billing        | Yes (callback) |
| 9  | GetPlayerTotalDebt          | Billing        | Yes (callback) |
| 10 | GetMugShotBase64            | Utility        | Yes (yields)   |

***

### Tablet State

#### 1. IsTabletOpen

Check if the local player's tablet is currently open.

```lua
local isOpen = exports['0r-smarttab']:IsTabletOpen()
```

| Returns | Type    | Description                     |
| ------- | ------- | ------------------------------- |
| isOpen  | boolean | `true` if the tablet UI is open |

**Example:**

```lua
if exports['0r-smarttab']:IsTabletOpen() then
    print("Tablet is open right now")
else
    print("Tablet is closed")
end
```

***

### Tablet Control

#### 2. OpenTabletWithApp

Open the tablet and navigate directly to a specific app. The player must have a tablet item in their inventory (and satisfy metadata checks if enabled).

```lua
exports['0r-smarttab']:OpenTabletWithApp(appId)
```

| Parameter | Type   | Description                                      |
| --------- | ------ | ------------------------------------------------ |
| `appId`   | string | App **id** or **action** from `server/apps.json` |

| Returns |   |
| ------- | - |
| nothing |   |

**Example:**

```lua
-- Open the Mail app
exports['0r-smarttab']:OpenTabletWithApp("app-mail")

-- Open the Police MDT
exports['0r-smarttab']:OpenTabletWithApp("app-police")

-- Open the EMS app
exports['0r-smarttab']:OpenTabletWithApp("app-ems")

-- Open Settings
exports['0r-smarttab']:OpenTabletWithApp("settings")

-- Open a custom iframe app
exports['0r-smarttab']:OpenTabletWithApp("customapp")
```

> **Tip:** You can find valid app IDs in `server/apps.json`. Each app has an `id` and/or `action` field — either one works.

***

### Notifications

#### 3. SendNotification

Push a notification to the local player's tablet. If the tablet is open, it appears immediately as an in-app notification. If the tablet is closed, it queues and plays a peek animation on screen.

```lua
exports['0r-smarttab']:SendNotification(data)
```

| Parameter | Type  | Description          |
| --------- | ----- | -------------------- |
| `data`    | table | Notification payload |

**Payload fields:**

| Field      | Type   | Required | Default | Description                        |
| ---------- | ------ | -------- | ------- | ---------------------------------- |
| `title`    | string | yes      | —       | Notification title                 |
| `message`  | string | yes      | —       | Body text                          |
| `app`      | string | no       | nil     | App ID — determines the icon shown |
| `icon`     | string | no       | nil     | Custom icon override               |
| `duration` | number | no       | 4000    | How long to show (ms)              |
| `type`     | string | no       | nil     | Optional type tag                  |
| `category` | string | no       | nil     | Optional category tag              |

| Returns |   |
| ------- | - |
| nothing |   |

**Example:**

```lua
exports['0r-smarttab']:SendNotification({
    title    = "New Order",
    message  = "You have a delivery waiting at the warehouse.",
    app      = "app-mail",
    duration = 5000
})
```

***

#### 4. SetAppBadge

Set a numeric badge on an app's home-screen icon. Useful for showing unread counts.

```lua
exports['0r-smarttab']:SetAppBadge(appId, count)
```

| Parameter | Type   | Description                      |
| --------- | ------ | -------------------------------- |
| `appId`   | string | App ID (e.g. `"app-mail"`)       |
| `count`   | number | Badge number — pass `0` to clear |

| Returns |   |
| ------- | - |
| nothing |   |

**Example:**

```lua
-- Show a badge of 5 on the mail app
exports['0r-smarttab']:SetAppBadge("app-mail", 5)

-- Clear the badge
exports['0r-smarttab']:SetAppBadge("app-mail", 0)
```

***

### Tablet Lookup

#### 5. GetPlayerByTabletSerial

Find the owner of a tablet by its serial number. Sends a request to the server and returns the result via callback. The owner must be **online** to be found.

```lua
exports['0r-smarttab']:GetPlayerByTabletSerial(serial, callback)
```

| Parameter  | Type     | Description                               |
| ---------- | -------- | ----------------------------------------- |
| `serial`   | string   | Tablet serial number (e.g. `"0R-A1B2C3"`) |
| `callback` | function | Called with the result table              |

**Callback result:**

| Field       | Type          | Description                                     |
| ----------- | ------------- | ----------------------------------------------- |
| `source`    | number \| nil | Player server ID (`nil` if offline / not found) |
| `citizenid` | string \| nil | Owner citizen ID / identifier                   |
| `name`      | string \| nil | Player character name                           |

**Example:**

```lua
exports['0r-smarttab']:GetPlayerByTabletSerial("0R-A1B2C3", function(result)
    if result.source then
        print("Owner: " .. result.name .. " (ID: " .. result.source .. ")")
    else
        print("No online player found for this serial")
    end
end)
```

***

### Billing

All billing exports fetch data from the server asynchronously. They return data for the **local player** only.

#### 6. GetPlayerInvoiceList

Get the full list of invoices (paid + unpaid) for the local player.

```lua
exports['0r-smarttab']:GetPlayerInvoiceList(callback)
```

| Parameter  | Type     | Description                   |
| ---------- | -------- | ----------------------------- |
| `callback` | function | Called with the invoice array |

**Each invoice object:**

| Field            | Type            | Description                               |
| ---------------- | --------------- | ----------------------------------------- |
| `id`             | number / string | Invoice ID                                |
| `title`          | string          | Invoice label                             |
| `sender`         | string          | Sender name or society                    |
| `amount`         | number          | Total amount (with interest if overdue)   |
| `baseAmount`     | number          | Original amount before interest           |
| `interestAmount` | number          | Accrued interest (0 if not overdue)       |
| `status`         | string          | `"unpaid"` / `"overdue"` / `"paid"`       |
| `dueDate`        | string          | Formatted due date                        |
| `daysOverdue`    | number          | Days past the due date (0 if not overdue) |

**Example:**

```lua
exports['0r-smarttab']:GetPlayerInvoiceList(function(invoices)
    print("You have " .. #invoices .. " invoice(s)")
    for _, inv in ipairs(invoices) do
        print((" - %s | $%d | %s"):format(inv.title, inv.amount, inv.status))
    end
end)
```

***

#### 7. GetPlayerInvoiceCount

Get the total number of invoices (paid + unpaid).

```lua
exports['0r-smarttab']:GetPlayerInvoiceCount(callback)
```

| Parameter  | Type                    |
| ---------- | ----------------------- |
| `callback` | function(count: number) |

**Example:**

```lua
exports['0r-smarttab']:GetPlayerInvoiceCount(function(count)
    print("Total invoices: " .. count)
end)
```

***

#### 8. GetPlayerUnpaidInvoiceCount

Get the number of unpaid and overdue invoices only.

```lua
exports['0r-smarttab']:GetPlayerUnpaidInvoiceCount(callback)
```

| Parameter  | Type                    |
| ---------- | ----------------------- |
| `callback` | function(count: number) |

**Example:**

```lua
exports['0r-smarttab']:GetPlayerUnpaidInvoiceCount(function(count)
    if count > 0 then
        print("You have " .. count .. " unpaid bill(s)!")
    end
end)
```

***

#### 9. GetPlayerTotalDebt

Get the total debt amount across all unpaid / overdue invoices (interest included).

```lua
exports['0r-smarttab']:GetPlayerTotalDebt(callback)
```

| Parameter  | Type                        |
| ---------- | --------------------------- |
| `callback` | function(totalDebt: number) |

**Example:**

```lua
exports['0r-smarttab']:GetPlayerTotalDebt(function(debt)
    if debt > 0 then
        print("Total debt: $" .. debt)
    else
        print("No outstanding debt")
    end
end)
```

***

### Utility

#### 10. GetMugShotBase64

Capture a ped's headshot and return it as a base64 image string. This is a **yielding** call — it blocks the current thread until the headshot is ready (up to \~2 seconds).

```lua
local base64 = exports['0r-smarttab']:GetMugShotBase64(ped, transparent)
```

| Parameter     | Type    | Description                                            |
| ------------- | ------- | ------------------------------------------------------ |
| `ped`         | number  | Ped entity handle                                      |
| `transparent` | boolean | `true` for transparent background, `false` for default |

| Returns | Type   | Description                                            |
| ------- | ------ | ------------------------------------------------------ |
| base64  | string | Base64-encoded image data (or empty string on failure) |

**Example:**

```lua
local ped = PlayerPedId()
local photo = exports['0r-smarttab']:GetMugShotBase64(ped, false)

if photo and photo ~= "" then
    print("Headshot captured, length: " .. #photo)
end
```

> **Note:** This function yields (uses `Citizen.Await` internally). Call it from a `CreateThread` or async context — do not call it from a synchronous NUI callback handler.

***

### Quick Reference

| Export                                | Returns      | Sync?    |
| ------------------------------------- | ------------ | -------- |
| `IsTabletOpen()`                      | boolean      | Sync     |
| `OpenTabletWithApp(appId)`            | —            | Sync     |
| `SendNotification(data)`              | —            | Sync     |
| `SetAppBadge(appId, count)`           | —            | Sync     |
| `GetPlayerByTabletSerial(serial, cb)` | via callback | Async    |
| `GetPlayerInvoiceList(cb)`            | via callback | Async    |
| `GetPlayerInvoiceCount(cb)`           | via callback | Async    |
| `GetPlayerUnpaidInvoiceCount(cb)`     | via callback | Async    |
| `GetPlayerTotalDebt(cb)`              | via callback | Async    |
| `GetMugShotBase64(ped, transparent)`  | string       | Yielding |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.0resmon.org/0resmon/0r-resources/0r-smarttab/exports/client-exports.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
