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

# Campos Personalizados

> Aprenda como configurar campos personalizados dentro do Tablet Policial

Com os campos personalizados você pode exibir praticamente qualquer informação que desejar dentro do Tablet Policial, por exemplo, carteira de motorista, licença de caça ou outras informações que um policial possa querer saber sobre o jogador.

Nessa documentação, iremos utilizar como exemplo **Carteira de Motorista**.

## Exemplo de Campo Personalizado

```lua config.lua theme={null}
["driver"] = {
    ---@type string O título do campo dentro do tablet
    title = "Carteira de Motorista",
    
    ---@type string O nome do botão dentro do tablet
    actionName = "Alternar status",
    
    ---@type string | [string, string]
    confirmationMessage = {
        "Deseja criar uma carteira de motorista para <b>{name}</b>?",
        "Você tem certeza que deseja invalidar a carteira de motorista de <b>{name}</b>?"
    },
    
    ---@type string | [string, string]
    successMessage = {
        "A carteira de motorista de <b>{name}</b> foi criada com sucesso!",
        "A carteira de motorista de <b>{name}</b> foi invalidada com sucesso!"
    },
    
    ---@param value any O valor atual do campo. O exato valor retornado pela função `Functions.getDriverLicense`
    ---@return string displayValue O texto que será mostrado dentro do tablet
    parseValue = function(value)
        return value and "Sim" or "Não"
    end,
    
    ---@param value any O valor atual do campo. O exato valor retornado pela função `Functions.getDriverLicense`
    ---@return boolean visible Se for true, um botão será exibido para editar, se for false, o botão será ocultado.
    buttonCondition = function(value)
        -- Neste caso, o botão só será exibido caso o usuário tenha a carteira de motorista.
        -- Ou seja, seria um botão para revogar.
        return value
    end,
}
```

### Parâmetros de Configuração do Campo

<Note>
  O identificador `"driver"` é apenas um exemplo e pode ser substituído por qualquer identificador de sua escolha para representar diferentes campos personalizados.
</Note>

| Parâmetro             | Tipo                           | Descrição                                                                                                                                   |
| --------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                  | string                         | Um identificador único para a licença.<br />No exemplo acima, utilizamos `driver`.                                                          |
| `title`               | string                         | Define o título que será exibido no campo dentro do tablet.<br />No exemplo acima, utilizamos `Carteira de Motorista`.                      |
| `actionName`          | string                         | Define o texto que será exibido no botão de ação.<br />No exemplo acima, utilizamos `Alterar status`.                                       |
| `confirmationMessage` | string ou array\[2] de strings | Mensagens de confirmação antes de realizar a ação. Se for um array, a primeira mensagem é para criação e a segunda para invalidação.        |
| `successMessage`      | string ou array\[2] de strings | Mensagens exibidas após a conclusão bem-sucedida da ação. Se for um array, a primeira mensagem é para criação e a segunda para invalidação. |
| `parseValue`          | function                       | Função que formata o valor para exibição no tablet.<br />No exemplo acima, retornamos **Sim** para `true` e **Não** para `false`.           |
| `buttonCondition`     | function                       | Função que determina se o botão de ação deve ser exibido ou não.<br />No exemplo acima, mostramos o botão apenas se `value` for `true`.     |

## Funções Necessárias

Para o correto funcionamento deste campo de licença, é necessário implementar as seguintes funções nos arquivos indicados.

O nome das funções é o ID com a primeira letra maiúscula. No exemplo, nosso ID é driver, então o nome das funções são `getDriverLicense`,`updateDriverLicense` e `onUpdateDriverLicense`.

### functions.lua

#### `Functions.getDriverLicense(userID)`

Esta função deve verificar se um usuário possui carteira de motorista válida.

```lua functions.lua theme={null}
---@param userID number ID do usuário a ser verificado
---@return any status Retorna o status da carteira de motorista
function Functions.getDriverLicense(userID)
	return Functions.getUData(userID, "driverLicense") == "true"
end
```

#### `Functions.updateDriverLicense(userID)`

Esta função deve alternar o status da carteira de motorista de um usuário (criar ou invalidar).

```lua functions.lua theme={null}
---@param userID number ID do usuário cuja carteira será atualizada
---@return boolean success Retorna true se a operação foi bem-sucedida, false caso contrário
function Functions.updateDriverLicense(userID)
    local value = Functions.getDriverLicense(userID)
    Functions.setUData(userID, "driverLicense", tostring(not value))
    return true
end
```

### webhooks.lua

#### `Webhooks.onUpdateDriverLicense(userID, officerID)`

Esta função de webhook é chamada quando um policial altera o status da carteira de motorista de um cidadão. Pode ser utilizada para logging, notificações ou integrações externas.

````lua webhooks.lua [expandable] theme={null}
---@param userID number ID do usuário cuja carteira foi atualizada
---@param officerID number ID do policial que realizou a ação
function Webhooks.onUpdateDriverLicense(userID, officerID)
	local officerIdentity = Functions.getUserIdentity(officerID)
	local officerName = officerIdentity.name .. " " ..  officerIdentity.surname
	
	local targetIdentity = Functions.getUserIdentity(userID)
	local targetName = targetIdentity.name .. " " ..  targetIdentity.surname

	local status = Functions.getDriverLicense(userID)

	PerformHttpRequest(webhookURLs.licenses, function(err, text, headers) end, "POST", json.encode({
		embeds = {
			{
				author = {
					name = (status and "Carteira de motorista criada" or "Carteira de motorista invalidada"),
					icon_url = "https://cdn-icons-png.flaticon.com/512/2689/2689886.png"
				},
				fields = {
					{
						name = "Oficial",
						value = "```ini\n[" .. officerID .. "] " .. officerName .. "\n```",
					},
					{
						name = "Jogador",
						value = "```ini\n[" .. userID .. "] " .. targetName .. "\n```",
						inline = true,
					},
				},
				color = (status and 3042892 or 9317187)
			}
		}
	}), {["Content-Type"] = "application/json"})
end
````

## Fluxo de Funcionamento

1. Quando um policial acessa os detalhes de um jogador no tablet, o sistema chama a função ***get*** (por exemplo, `Functions.getDriverLicense(userID)`) para obter o status atual da licença.
2. O valor retornado é formatado pela função `parseValue` para exibição, por lá, você pode retornar o valor que você quiser (no exemplo, "Sim" ou "Não").
3. A função `buttonCondition` determina se o botão de ação deve ser exibido (no exemplo, só é exibido se o cidadão já possui a licença).
4. Quando o policial clica no botão **"Alternar status"**:
   * É exibido uma confirmação para o policial;
   * Se confirmado, a função de ***update*** (por exemplo, `Functions.updateDriverLicense(userID)`) é chamada;
   * Em seguida, o webhook correspondente (por exemplo, `Webhooks.onUpdateDriverLicense(userID, officerID)`) é acionado.

## Criando Diferentes Tipos de Campos

O mesmo padrão de configuração pode ser usado para implementar qualquer campo personalizado, bastando alterar o identificador do campo e as funções correspondentes. Por exemplo:

```lua config.lua theme={null}
["hunting"] = {
    title = "Licença de Caça",
    actionName = "Alternar status",
    confirmationMessage = {
        "Deseja conceder uma licença de caça para <b>{name}</b>?",
        "Você tem certeza que deseja revogar a licença de caça de <b>{name}</b>?"
    },
    -- Resto da configuração segue o mesmo padrão...
}
```

Você precisaria então implementar as funções correspondentes:

* `Functions.getHuntingLicense(userID)`
* `Functions.updateHuntingLicense(userID)`
* `Webhooks.onUpdateHuntingLicense(userID, officerID)`

## Notas de Implementação

* Esta configuração utiliza a tag de substituição `{name}` nas mensagens, que deve ser substituída pelo nome do cidadão antes de exibir.
* A lógica implementada em `buttonCondition` pode ser personalizada conforme a necessidade (no exemplo, só permite invalidar licenças existentes).
