# Admin Ticket System - Frontend Integration Guide

**Base URL:** `/api/admin/tickets`
**Auth:** Bearer token (Sanctum) — requires `superadministrator` role
**Header:** `Authorization: Bearer {token}`

---

## 1. Endpoints Overview

| Method   | Endpoint                      | Description                |
|----------|-------------------------------|----------------------------|
| `GET`    | `/tickets/stats`              | Dashboard statistics       |
| `GET`    | `/tickets/categories`         | List ticket categories     |
| `GET`    | `/tickets/options/statuses`   | Available status values    |
| `GET`    | `/tickets/options/priorities` | Available priority values  |
| `GET`    | `/tickets`                    | List tickets (paginated)   |
| `GET`    | `/tickets/{id}`               | Ticket details             |
| `PUT`    | `/tickets/{id}`               | Update ticket              |
| `DELETE` | `/tickets/{id}`               | Delete ticket (soft)       |

---

## 2. Stats

```
GET /api/admin/tickets/stats
```

**Response:**

```json
{
  "success": true,
  "message": "Tickets stats",
  "data": {
    "total": 142,
    "open": 38,
    "in_progress": 25,
    "resolved": 47,
    "closed": 32,
    "critical": 5,
    "high": 12,
    "new_last_30_days": 19
  }
}
```

---

## 3. Categories

```
GET /api/admin/tickets/categories
```

**Response:**

```json
{
  "success": true,
  "message": "Ticket categories",
  "data": [
    { "id": 1, "label": "Problème technique", "label_en": "Technical issue" },
    { "id": 2, "label": "Demande d'information", "label_en": "Information request" },
    { "id": 3, "label": "Réclamation", "label_en": "Complaint" },
    { "id": 4, "label": "Suggestion", "label_en": "Suggestion" },
    { "id": 5, "label": "Autre", "label_en": "Other" }
  ]
}
```

---

## 4. Status Options

```
GET /api/admin/tickets/options/statuses
```

**Response:**

```json
{
  "success": true,
  "message": "Status options",
  "data": [
    { "value": "Open",        "label": "Ouvert",   "label_en": "Open" },
    { "value": "In Progress", "label": "En cours",  "label_en": "In Progress" },
    { "value": "Resolved",    "label": "Résolu",    "label_en": "Resolved" },
    { "value": "Closed",      "label": "Fermé",     "label_en": "Closed" }
  ]
}
```

---

## 5. Priority Options

```
GET /api/admin/tickets/options/priorities
```

**Response:**

```json
{
  "success": true,
  "message": "Priority options",
  "data": [
    { "value": "No Priority", "label": "Aucune priorité", "label_en": "No Priority" },
    { "value": "Low",         "label": "Basse",            "label_en": "Low" },
    { "value": "Medium",      "label": "Moyenne",          "label_en": "Medium" },
    { "value": "High",        "label": "Haute",            "label_en": "High" },
    { "value": "Critical",    "label": "Critique",         "label_en": "Critical" }
  ]
}
```

---

## 6. List Tickets

```
GET /api/admin/tickets
```

**Query Parameters:**

| Param         | Type     | Default      | Description                                |
|---------------|----------|--------------|--------------------------------------------|
| `search`      | string   | —            | Search in title and description             |
| `status`      | string   | —            | Filter by status (`Open`, `In Progress`, `Resolved`, `Closed`) |
| `priority`    | string   | —            | Filter by priority (`No Priority`, `Low`, `Medium`, `High`, `Critical`) |
| `category_id` | integer  | —            | Filter by category ID                      |
| `company_id`  | integer  | —            | Filter by company ID                       |
| `order_by`    | string   | `created_at` | Sort field                                 |
| `order`       | string   | `DESC`       | Sort direction (`ASC` / `DESC`)            |
| `per_page`    | integer  | `15`         | Items per page                             |
| `page`        | integer  | `1`          | Page number                                |

**Response:**

```json
{
  "success": true,
  "message": "Tickets list",
  "data": {
    "total": 142,
    "count": 15,
    "per_page": 15,
    "current_page": 1,
    "last_page": 10,
    "previous_page_url": null,
    "next_page_url": "...?page=2",
    "items": [
      {
        "id": 1,
        "title": "Problème de connexion GPS",
        "category": {
          "id": 1,
          "label": "Problème technique",
          "label_en": "Technical issue"
        },
        "priority": {
          "label": "Haute",
          "label_en": "High",
          "key": "High"
        },
        "status": {
          "label": "Ouvert",
          "label_en": "Open",
          "key": "Open"
        },
        "description": "Le GPS du véhicule AB-123-CD ne se connecte plus...",
        "company": {
          "id": 5,
          "name": "Transport Express"
        },
        "created_by": {
          "id": 12,
          "name": "Jean Dupont"
        },
        "created_at": "2026-04-05 14:30"
      }
    ]
  }
}
```

---

## 7. Ticket Details

```
GET /api/admin/tickets/{id}
```

Returns the same structure as a list item, plus:

```json
{
  "success": true,
  "message": "Ticket details",
  "data": {
    "id": 1,
    "title": "...",
    "category": { "id": 1, "label": "...", "label_en": "..." },
    "priority": { "label": "...", "label_en": "...", "key": "High" },
    "status": { "label": "...", "label_en": "...", "key": "Open" },
    "description": "...",
    "company": { "id": 5, "name": "Transport Express" },
    "created_by": { "id": 12, "name": "Jean Dupont" },
    "created_at": "2026-04-05 14:30",
    "updated_at": "2026-04-05 16:45",
    "documents": [
      {
        "id": 1,
        "file_path": "tickets/1/screenshot.png",
        "uploaded_file_name": "screenshot.png",
        "file_size": 245120,
        "created_at": "2026-04-05 14:30"
      }
    ]
  }
}
```

---

## 8. Update Ticket

```
PUT /api/admin/tickets/{id}
```

**Body (JSON) — all fields optional:**

| Field         | Type    | Validation                                                       |
|---------------|---------|------------------------------------------------------------------|
| `status`      | string  | `Open`, `In Progress`, `Resolved`, `Closed`                      |
| `priority`    | string  | `No Priority`, `Low`, `Medium`, `High`, `Critical`               |
| `category_id` | integer | Must exist in `ticket_categories` table (nullable)               |
| `title`       | string  | Max 255 characters                                               |
| `description` | string  | Nullable                                                         |

**Example — change status:**

```json
{
  "status": "In Progress"
}
```

**Example — change priority and status:**

```json
{
  "status": "Resolved",
  "priority": "Low"
}
```

**Response:** Returns full ticket details (same shape as `GET /tickets/{id}`).

**Error (422):** Validation error message string.

---

## 9. Delete Ticket

```
DELETE /api/admin/tickets/{id}
```

**Response:**

```json
{
  "success": true,
  "message": "Ticket deleted successfully",
  "data": null
}
```

---

## 10. Frontend Integration Notes

### Suggested pages

1. **Tickets Dashboard** — stats cards + tickets table with filters
2. **Ticket Detail** — full info, documents viewer, status/priority update form

### Data loading sequence

```
// On page mount — load in parallel:
GET /tickets/stats
GET /tickets/categories
GET /tickets/options/statuses
GET /tickets/options/priorities
GET /tickets?page=1

// Categories, statuses, priorities can be cached client-side
```

### Filter bar

Use query params to build the filter bar:
- Status dropdown → populated from `/options/statuses`
- Priority dropdown → populated from `/options/priorities`
- Category dropdown → populated from `/categories`
- Company dropdown → use existing `/api/admin/companies` endpoint
- Search input → debounced `search` param

### Status badge colors (suggested)

| Status        | Color   |
|---------------|---------|
| `Open`        | blue    |
| `In Progress` | orange  |
| `Resolved`    | green   |
| `Closed`      | gray    |

### Priority badge colors (suggested)

| Priority      | Color   |
|---------------|---------|
| `No Priority` | gray    |
| `Low`         | blue    |
| `Medium`      | yellow  |
| `High`        | orange  |
| `Critical`    | red     |

### Inline status/priority update

For quick updates from the table (e.g., dropdown change), send:

```js
await api.put(`/admin/tickets/${id}`, { status: 'In Progress' })
// Response includes full updated ticket — replace in local state
```

### Error handling

| HTTP Code | Meaning              |
|-----------|----------------------|
| 200       | Success              |
| 404       | Ticket not found     |
| 422       | Validation error     |
| 500       | Server error         |
