# 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()
```

| Parameters |   |
| ---------- | - |
| none       |   |

| 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 |
