# Robooking — Documentație API Mobil

> **Stack:** Laravel 12 + Laravel Sanctum v4.3.2  
> **URL de bază (dev):** `http://127.0.0.1:8001/api/v1`  
> **URL de bază (live):** `https://robooking.ro/api/v1`  
> **Autentificare:** Bearer Token (Sanctum)  
> **Format răspuns:** JSON  

---

## Structura răspunsului

### Răspuns simplu (single entity)
```json
{
  "success": true,
  "message": "OK",
  "data": { ... }
}
```

### Răspuns paginat (liste)
```json
{
  "success": true,
  "data": [ ... ],
  "meta": {
    "current_page": 1,
    "last_page": 10,
    "per_page": 12,
    "total": 120
  }
}
```

### Răspuns eroare
```json
{
  "success": false,
  "message": "Descrierea erorii",
  "errors": { ... }
}
```

Toate erorile (404, 422, 401, 403, 405, 429, 500) returnează **întotdeauna** acest format JSON, niciodată HTML. `errors` apare doar la validare (422).

### Coduri de status relevante
| Cod | Semnificație | Acțiune recomandată în app |
|-----|--------------|----------------------------|
| `401` | Token lipsă/invalid/expirat | Redirect la login |
| `403` | Token read-only la operație de scriere / acces interzis | — |
| `404` | Resursă inexistentă | — |
| `422` | Validare eșuată (vezi `errors`) | Afișează erorile pe câmpuri |
| `429` | Rate limit depășit | Retry cu backoff |
| `503` | API dezactivat din admin | Afișează mesaj „mentenanță" |

> **Rate limit:** implicit 60 cereri/minut per utilizator/IP (configurabil din admin). La depășire → `429`.

---

## 1. Autentificare

### POST `/auth/login`
Autentifică un utilizator și returnează un token Bearer cu valabilitate 30 de zile.

**Body:**
```json
{
  "email": "user@example.com",
  "password": "parola123",
  "device_name": "Telefon Android" 
}
```

**Răspuns succes:**
```json
{
  "success": true,
  "data": {
    "token": "1|abc123...",
    "user": {
      "id": 1,
      "name": "Ion Popescu",
      "first_name": "Ion",
      "last_name": "Popescu",
      "email": "user@example.com",
      "phone": "+40712345678",
      "avatar": "https://robooking.ro/storage/avatars/xyz.webp",
      "roles": ["user"],
      "email_verified": true,
      "verification_status": "approved",
      "created_at": "2026-01-15T10:00:00.000000Z"
    }
  }
}
```

**Erori posibile:** `401 Credențiale incorecte`, `403 Cont suspendat`

---

### POST `/auth/register`
Înregistrează un cont nou și returnează token.

**Body:**
```json
{
  "name": "Ion Popescu",
  "email": "user@example.com",
  "password": "parola123",
  "password_confirmation": "parola123",
  "phone": "+40712345678"
}
```

---

### POST `/auth/logout`
Invalidează tokenul curent.  
**Header:** `Authorization: Bearer {token}`

---

### GET `/auth/me`
Returnează datele utilizatorului autentificat.  
**Header:** `Authorization: Bearer {token}`

---

### POST `/auth/refresh`
Generează un token nou (30 zile) și îl invalidează pe cel vechi.  
**Header:** `Authorization: Bearer {token}`

---

### POST `/auth/forgot`
Trimite email de resetare parolă.

**Body:**
```json
{ "email": "user@example.com" }
```

---

## 2. Homepage

### GET `/home`
Returnează datele pentru ecranul principal al aplicației.

**Răspuns:**
```json
{
  "success": true,
  "data": {
    "site_name": "RoBooking",
    "featured_cabins": [ ... ],
    "featured_hotels": [ ... ],
    "featured_tours": [ ... ],
    "featured_activities": [ ... ],
    "destinations": [ ... ]
  }
}
```

Fiecare element din liste conține: `id`, `type`, `name`, `slug`, `image`, `price`, `currency`, `rating`, `reviews_count`, `url`.

---

## 3. Căutare Globală

### GET `/search?q={termen}`
Caută simultan în: cabane, hoteluri, tururi, activități, zboruri.

**Parametri:**
| Parametru | Tip | Obligatoriu |
|-----------|-----|-------------|
| `q` | string (min 2 caractere) | DA |

**Răspuns:**
```json
{
  "success": true,
  "data": {
    "query": "brasov",
    "total": 11,
    "results": [
      {
        "type": "cabin",
        "label": "Cabană",
        "id": 42,
        "name": "Vila Montana",
        "sub": "Brașov, Brașov",
        "price": 350.00,
        "image": "https://...",
        "url": "https://robooking.ro/cabane/brasov/vila-montana"
      }
    ]
  }
}
```

---

## 4. Descoperă (Hartă Interactivă)

### GET `/descopera`
Returnează toate punctele de pe hartă pentru un tip de conținut. Folosit pentru ecranul hartă interactivă din aplicație.

**Parametri:**
| Parametru | Tip | Valori acceptate | Default |
|-----------|-----|-----------------|---------|
| `tip` | string | `cabane`, `hoteluri`, `tururi`, `activitati`, `sejururi`, `croaziere`, `masini`, `destinatii` | `cabane` |
| `q` | string | text de căutare | — |
| `sort` | string | `recomandat`, `pret_asc`, `pret_desc`, `rating` | `recomandat` |
| `pret_min` | int | preț minim | 0 |
| `pret_max` | int | preț maxim | — |
| `capacitate` | int | număr persoane minim (doar cabane) | 0 |
| `durata` | int | durata minimă în zile (tururi, sejururi) | 0 |
| `cat_masina` | string | categorie mașină (auto/atv/moto/scuter/rulota) | — |
| `bounds` | string | `lat_sw,lng_sw,lat_ne,lng_ne` — filtrare vizuală pe viewport hartă | — |
| `per_page` | int | maxim 200 | 50 |

**Răspuns:**
```json
{
  "success": true,
  "data": {
    "tip": "cabane",
    "total": 89,
    "items": [
      {
        "id": 42,
        "tip": "cabana",
        "titlu": "Vila Montana",
        "lat": 45.6543,
        "lng": 25.3241,
        "fara_harta": false,
        "pret": 350.0,
        "moneda": "RON",
        "imagine": "https://robooking.ro/storage/cabins/xyz.webp",
        "url": "https://robooking.ro/cabane/brasov/vila-montana",
        "rating": 4.8,
        "recenzii": 23,
        "locatie": "Brașov, Brașov",
        "capacitate": 8,
        "featured": false,
        "oferte": null
      }
    ]
  }
}
```

**Note:**
- `fara_harta: true` înseamnă că entitatea nu are coordonate GPS — nu se afișează pe hartă dar apare în listă
- `oferte` este populat doar pentru `tip=destinatii` (numărul total de hoteluri+tururi+activități)
- `capacitate` este populat doar pentru `tip=cabane`
- `featured` este populat pentru cabane și hoteluri
- Mașinile nu au lat/lng în DB — coordonatele sunt aproximate din `pickup_city` (oraș principal)
- Endpoint public — nu necesită autentificare

---

## 5. Cabane

### GET `/cabane`
Listare cabane cu filtre și paginare.

**Parametri de filtrare:**
| Parametru | Tip | Descriere |
|-----------|-----|-----------|
| `q` | string | Căutare după nume / sat / masiv |
| `locatie` | string | Filtrare după sat / județ / masiv |
| `capacitate_min` | integer | Capacitate minimă persoane |
| `pret_min` | float | Preț minim pe noapte (RON) |
| `pret_max` | float | Preț maxim pe noapte (RON) |
| `vacation_card` | string | Tip card vacanță acceptat |
| `facility[]` | integer[] | ID-uri atribute (se trimit multiplu) |
| `sort` | string | `pret_asc` / `pret_desc` / `rating` / `recomandat` |
| `per_page` | integer | Număr rezultate per pagină (default: 12) |

**Exemplu request:**
```
GET /cabane?locatie=brasov&capacitate_min=4&pret_max=500&sort=rating&per_page=12
```

**Structura unui element din listă:**
```json
{
  "id": 42,
  "name": "Vila Montana",
  "slug": "vila-montana",
  "price_per_night": 350.00,
  "currency": "RON",
  "rating": 4.8,
  "reviews_count": 23,
  "capacity": 8,
  "bedrooms": 3,
  "image": "https://robooking.ro/storage/...",
  "location": "Poiana Brașov, Brașov",
  "latitude": 45.5936,
  "longitude": 25.5519,
  "is_featured": true,
  "url": "https://robooking.ro/cabane/poiana-brasov/vila-montana"
}
```

---

### GET `/cabane/{slug}`
Detalii complete cabană.

**Răspuns include:** toate câmpurile din listing plus:
- `description`, `short_desc`, `address`, `village`, `county`, `mountain_range`, `altitude`
- `bedrooms`, `bathrooms`, `min_nights`
- `vacation_cards` (array: tipuri de card vacanță acceptate)
- `phone`
- `gallery` (array URL-uri imagini)
- `location` (obiect: `id`, `name`)
- `owner` (obiect: `id`, `name`, `avatar`)
- `attributes` (grupate pe categorii: `category`, `items[]` cu `id`, `name`, `icon`)
- `price_rules` (reguli de preț: weekend, sezon, etc.)
- `url`, `booking_url`

---

### GET `/cabane/{slug}/disponibilitate`
Returnează datele blocate (indisponibile) pentru o perioadă.

**Parametri:**
| Parametru | Tip | Default |
|-----------|-----|---------|
| `from` | date (Y-m-d) | Prima zi a lunii curente |
| `to` | date (Y-m-d) | Ultima zi a lunii +3 |

**Răspuns:**
```json
{
  "success": true,
  "data": {
    "cabin_id": 42,
    "from": "2026-06-01",
    "to": "2026-09-30",
    "blocked_dates": ["2026-06-15", "2026-06-16", "2026-07-20"]
  }
}
```

---

### GET `/cabane/atribute`
Returnează toate categoriile de atribute active cu sub-atributele lor.  
Folosit pentru a construi sidebar-ul de filtre.

**Răspuns:**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Facilități de bază",
      "icon": "fa-home",
      "attributes": [
        { "id": 10, "name": "Șemineu", "icon": "fa-fire" },
        { "id": 11, "name": "Wi-Fi", "icon": "fa-wifi" }
      ]
    }
  ]
}
```

---

### GET `/cabane/locatii?q={termen}`
Autocomplete locații cabane.

---

## 5. Cazare (Hoteluri)

### GET `/cazare`
Listare hoteluri cu filtre.

**Parametri de filtrare:**
| Parametru | Tip | Descriere |
|-----------|-----|-----------|
| `q` | string | Căutare după nume / oraș |
| `oras` | string | Filtrare după oraș |
| `stele` | integer | 1-5 stele |
| `tip` | string | Tipul unității (hotel, pensiune, etc.) |
| `pret_min` | float | Preț minim de la (RON) |
| `pret_max` | float | Preț maxim de la (RON) |
| `vacation_card` | string | Tip card vacanță acceptat |
| `sort` | string | `pret_asc` / `pret_desc` / `rating` / `stele` / `recomandat` |

**Structura element:**
```json
{
  "id": 5,
  "name": "Hotel Panoramic",
  "slug": "hotel-panoramic",
  "stars": 4,
  "hotel_type": "hotel",
  "price_from": 250.00,
  "currency": "RON",
  "rating": 4.5,
  "reviews_count": 87,
  "city": "Sinaia",
  "country": "România",
  "image": "https://...",
  "is_featured": true,
  "url": "https://robooking.ro/cazare/hotel/sinaia/hotel-panoramic"
}
```

---

### GET `/cazare/{slug}`
Detalii complete hotel, inclusiv lista de camere.

**Detalii extra față de listing:**
- `description`, `short_desc`, `address`, `latitude`, `longitude`
- `check_in_time`, `check_out_time`, `min_nights`
- `gallery` (array URL-uri)
- `amenities` (array facilități)
- `vacation_cards` (array)
- `destination` (obiect: `id`, `name`, `slug`)
- `rooms[]` (camere: `id`, `name`, `slug`, `capacity`, `price_per_night`, `image`)

---

### GET `/cazare/{hotelSlug}/camere`
Lista completă de camere ale unui hotel.

**Fiecare cameră include:** `id`, `name`, `slug`, `capacity`, `price_per_night`, `description`, `amenities[]`, `gallery[]`

---

### GET `/cazare/{hotelSlug}/camere/{roomSlug}`
Detalii complete o cameră, plus referință la hotel.

---

## 6. Tururi

### GET `/tururi`
**Filtre disponibile:** `q`, `destinatie`, `pret_min`, `pret_max`, `durata` (zile), `sort`

**Structura element:**
```json
{
  "id": 3,
  "name": "Tur Dracula",
  "slug": "tur-dracula",
  "price_per_person": 199.00,
  "currency": "RON",
  "rating": 4.7,
  "reviews_count": 45,
  "duration_days": 3,
  "destination": "Brașov",
  "image": "https://...",
  "is_featured": false,
  "url": "https://robooking.ro/tururi/brasov/tur-dracula"
}
```

---

### GET `/tururi/{slug}`
Detalii complete tur: `description`, `original_price`, `max_group_size`, `category`, `destination`, `gallery[]`, `includes[]`, `excludes[]`, `itinerary[]`

---

## 7. Activități

### GET `/activitati`
**Filtre:** `q`, `categorie`, `pret_min`, `pret_max`, `sort`

**Structura element:** `id`, `name`, `slug`, `price_per_person`, `currency`, `rating`, `reviews_count`, `category`, `duration`, `destination`, `image`, `is_featured`, `url`

---

### GET `/activitati/{slug}`
Detalii complete: `description`, `max_participants`, `meeting_point`, `what_to_bring`, `gallery[]`, `includes[]`

---

## 8. Zboruri

### GET `/zboruri`
**Filtre:** `q`, `plecare` (oraș/aeroport), `sosire`, `clasa`, `pret_min`, `pret_max`

**Structura element:**
```json
{
  "id": 12,
  "flight_number": "RO123",
  "airline": "TAROM",
  "airline_logo": "https://...",
  "from_city": "București",
  "from_code": "OTP",
  "from_airport": "Henri Coandă",
  "to_city": "Barcelona",
  "to_code": "BCN",
  "to_airport": "El Prat",
  "departure_time": "2026-07-15 08:30:00",
  "arrival_time": "2026-07-15 11:45:00",
  "duration": "3h 15m",
  "stops": 0,
  "class": "economy",
  "price": 299.00,
  "currency": "RON",
  "available_seats": 45,
  "cabin_baggage": "10kg",
  "checked_baggage": "23kg",
  "is_refundable": false,
  "url": "https://robooking.ro/zboruri/tarom/bucuresti-barcelona/ro123"
}
```

---

### GET `/zboruri/{flight_number}`
Detalii complete zbor, plus `stop_cities`.

---

## 9. Sejururi

### GET `/sejururi`
**Filtre:** `q`, `destinatie`, `masa` (room_only/breakfast/half_board/full_board/all_inclusive), `transport` (avion/autocar/tren/propriu), `pret_min`, `pret_max`, `sort`

**Structura element include:** `nights`, `destination_city`, `destination_country`, `meal_plan`, `meal_plan_label`, `transport_type`, `transport_label`, `accommodation_stars`, `original_price`

---

### GET `/sejururi/{slug}`
Detalii complete: `departure_date`, `return_date`, `airline`, `accommodation_name`, `includes[]`, `excludes[]`, `gallery[]`

---

## 10. Croaziere

### GET `/croaziere`
**Filtre:** `q`, `port`, `pret_min`, `pret_max`

**Structura element:** `id`, `name`, `slug`, `price_per_person`, `currency`, `rating`, `reviews_count`, `departure_port`, `duration_nights`, `ship_name`, `cruise_line`, `all_inclusive`, `image`, `is_featured`, `url`

---

### GET `/croaziere/{slug}`
Detalii complete: `ports[]`, `cabin_types`, `itinerary[]`, `includes[]`, `gallery[]`

---

## 11. Închirieri Auto

### GET `/inchirieri`
**Filtre:** `q`, `categorie`, `tip`, `oras`, `pret_min`, `pret_max`, `sort`

**Structura element:**
```json
{
  "id": 8,
  "name": "Dacia Duster",
  "slug": "dacia-duster",
  "make": "Dacia",
  "model": "Duster",
  "year": 2024,
  "category": "suv",
  "type": "auto",
  "price_per_day": 150.00,
  "currency": "RON",
  "rating": 4.6,
  "reviews_count": 12,
  "pickup_city": "Cluj-Napoca",
  "seats": 5,
  "transmission": "manual",
  "fuel_type": "diesel",
  "image": "https://...",
  "is_featured": false,
  "url": "https://robooking.ro/inchirieri/suv/cluj-napoca/dacia-duster"
}
```

---

### GET `/inchirieri/{slug}`
Detalii complete: `doors`, `luggage_large`, `luggage_small`, `unlimited_mileage`, `insurance_included`, `pickup_location`, `features[]`, `gallery[]`

---

## 12. Recenzii

### GET `/recenzii?type={tip}&id={id}`
Listare recenzii aprobate pentru o entitate.

**Parametri obligatorii:** `type` (cabin/hotel/tour/activity/car/cruise/flight/sejur), `id`

**Parametru opțional:** `per_page` (default: 10)

**Structura element:**
```json
{
  "id": 55,
  "rating": 5,
  "title": "Experiență minunată",
  "comment": "Ne-am simțit excelent, recomandăm cu căldură!",
  "user": {
    "name": "Maria P.",
    "avatar": "https://..."
  },
  "is_verified_booking": true,
  "created_at": "2026-05-20T14:30:00.000000Z"
}
```

---

### POST `/recenzii` *(autentificat)*
Trimite o recenzie nouă (status inițial: `pending`, apare după aprobare admin).

**Body:**
```json
{
  "type": "cabin",
  "id": 42,
  "rating": 5,
  "title": "Loc de vis",
  "comment": "Cabana a depășit așteptările noastre..."
}
```

---

## 13. Rezervări *(autentificat)*

### GET `/rezervari`
Lista rezervărilor utilizatorului curent, paginată (10 per pagină).

**Structura element:**
```json
{
  "id": 101,
  "booking_number": "RB-20260615-ABC",
  "type": "Cabin",
  "title": "Vila Montana",
  "image": "https://...",
  "start_date": "2026-07-10",
  "end_date": "2026-07-15",
  "guests": 4,
  "total": 1750.00,
  "currency": "RON",
  "status": "confirmed",
  "payment_status": "paid",
  "created_at": "2026-06-13T12:00:00.000000Z"
}
```

**Statusuri posibile:** `pending`, `confirmed`, `cancelled`, `completed`  
**Statusuri plată:** `unpaid`, `paid`, `refunded`

---

### GET `/rezervari/{id}`
Detalii complete rezervare, include și `guest_name`, `guest_email`, `guest_phone`, `special_requests`, `subtotal`, `tax`, `coupon_code`, `discount_amount`, `payment_method`, `source`.

---

### POST `/rezervari`
Creează o rezervare nouă.

**Body:**
```json
{
  "type": "cabin",
  "bookable_id": 42,
  "start_date": "2026-07-10",
  "end_date": "2026-07-15",
  "guests": 4,
  "guest_name": "Ion Popescu",
  "guest_email": "ion@example.com",
  "guest_phone": "+40712345678",
  "special_requests": "Dorim șemineu aprins la sosire",
  "coupon_code": "VARA2026"
}
```

**Tipuri acceptate pentru `type`:** `cabin`, `hotel`, `tour`, `activity`, `flight`, `sejur`, `cruise`, `car`

**Prețul este calculat automat:**
- Cabane, hoteluri, mașini: `preț_bază × număr_nopți/zile`
- Restul: `preț_per_persoană` (1 unitate)
- Cuponul (dacă valid) se aplică și se înregistrează automat

**Răspuns:** detalii complete rezervare, status 201

---

### POST `/rezervari/{id}/anuleaza`
Anulează o rezervare (doar dacă are status `pending` sau `confirmed`).

---

## 14. Favorite (Wishlist) *(autentificat)*

### GET `/favorite`
Lista articolelor favorite ale utilizatorului.

**Structura element:**
```json
{
  "id": 33,
  "type": "Cabin",
  "item_id": 42,
  "name": "Vila Montana",
  "image": "https://...",
  "price": 350.00,
  "currency": "RON",
  "added_at": "2026-06-10T08:00:00.000000Z"
}
```

---

### POST `/favorite/toggle`
Adaugă sau elimină din favorite (toggle).

**Body:**
```json
{
  "type": "cabin",
  "id": 42
}
```

**Răspuns:**
```json
{
  "success": true,
  "data": { "wishlisted": true },
  "message": "Adăugat la favorite."
}
```

**Tipuri acceptate:** `cabin`, `hotel`, `tour`, `activity`, `car`, `cruise`, `flight`, `sejur`

---

## 15. Profil *(autentificat)*

### GET `/profil`
Datele complete ale profilului, plus statistici.

**Răspuns include:**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "Ion Popescu",
    "email": "ion@example.com",
    "phone": "+40712345678",
    "avatar": "https://...",
    "bio": "Pasionat de drumeții...",
    "city": "Cluj-Napoca",
    "country": "România",
    "roles": ["user"],
    "email_verified": true,
    "verification_status": "approved",
    "stats": {
      "bookings": 12,
      "active": 3,
      "favorites": 27
    }
  }
}
```

---

### PUT `/profil`
Actualizează datele profilului.

**Câmpuri acceptate:** `name`, `first_name`, `last_name`, `phone`, `company`, `birthdate`, `address`, `city`, `county`, `country`, `postal_code`, `bio`

---

### POST `/profil/avatar`
Uploadează un avatar nou (multipart/form-data).

**Body:** `avatar` (fișier imagine, max 5MB)

**Răspuns:** `{ "avatar": "https://..." }`

---

### PUT `/profil/parola`
Schimbă parola. Invalidează toate tokenele celorlalte sesiuni.

**Body:**
```json
{
  "current_password": "parola_veche",
  "password": "parola_noua",
  "password_confirmation": "parola_noua"
}
```

---

### DELETE `/profil/cont`
Șterge contul definitiv. Necesită parola pentru confirmare.

**Body:** `{ "password": "parola" }`

---

### POST `/profil/device-token`
Înregistrează (sau actualizează) token-ul FCM al dispozitivului pentru notificări push. Se apelează după login și la fiecare refresh al token-ului FCM de la Firebase.

**Body:**
```json
{
  "token": "fcm_device_token_de_la_firebase",
  "platform": "android",
  "device_name": "Samsung Galaxy S23"
}
```
- `platform` (opțional): `android` | `ios` | `web`
- `device_name` (opțional): nume dispozitiv

**Răspuns:** `{ "success": true, "message": "Dispozitiv înregistrat pentru notificări push." }`

> Push-urile sunt trimise automat la evenimente (rezervare nouă/confirmată/anulată, reminder check-in) dacă adminul a activat canalul Push App pentru rolul respectiv.

---

### DELETE `/profil/device-token`
Elimină token-ul FCM (la logout sau dezactivare notificări).

**Body:** `{ "token": "fcm_device_token" }`

---

## 16. Admin *(autentificat + rol admin)*

### GET `/admin/stats`
Dashboard statistici.

```json
{
  "rezervari": {
    "total": 1250,
    "azi": 8,
    "luna": 143,
    "pending": 23,
    "confirmed": 820
  },
  "venituri": {
    "total": 458000.00,
    "luna": 38500.00
  },
  "utilizatori": {
    "total": 3400,
    "noi_luna": 87
  },
  "unitati": {
    "cabane": 180,
    "hoteluri": 25
  }
}
```

---

### GET `/admin/rezervari`
Toate rezervările (paginat, 20/pagină).

**Filtre:** `status`, `tip` (tipul entității), `user_id`  
**Câmpuri extra față de `/rezervari`:** `user` (obiect), `booking_number`, `source`

---

### PUT `/admin/rezervari/{id}`
Actualizează statusul unei rezervări.

**Body:** `{ "status": "confirmed", "payment_status": "paid" }`

---

### GET `/admin/utilizatori`
Lista tuturor utilizatorilor (paginat).

**Filtre:** `q` (nume/email), `rol`, `status`

---

### GET `/admin/cabane`
Toate cabanele inclusiv cele șterse (soft delete).

**Filtre:** `q`, `status`

---

### PUT `/admin/cabane/{id}`
Actualizează rapid o cabană din admin.

**Body:** `{ "status": "active", "is_featured": true }`

---

### GET `/admin/notificari`
Ultimele notificări admin.

**Parametru opțional:** `limit` (default: 20)

---

## Gestionarea tokenelor în Flutter

```dart
// Salvare token după login
const storage = FlutterSecureStorage();
await storage.write(key: 'api_token', value: data['token']);

// Citire token și adăugare header
final token = await storage.read(key: 'api_token');
final response = await http.get(
  Uri.parse('$baseUrl/profil'),
  headers: {
    'Authorization': 'Bearer $token',
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
);

// Dacă primești 401 → redirect la login
if (response.statusCode == 401) {
  await storage.delete(key: 'api_token');
  // navigare la ecran login
}
```

---

## Coduri HTTP de răspuns

| Cod | Semnificație |
|-----|--------------|
| 200 | Succes |
| 201 | Creat cu succes |
| 400 | Cerere invalidă |
| 401 | Neautentificat (token lipsă / expirat) |
| 403 | Acces interzis (permisiuni insuficiente) |
| 404 | Resursa nu există |
| 422 | Eroare validare date |
| 500 | Eroare server |

---

## Istoricul modificărilor API

### v1.0.0 — 2026-06-13
- Implementare inițială API REST complet
- Instalat Laravel Sanctum v4.3.2
- **Endpoint-uri publice:** home, search, cabane, cazare, tururi, activitati, zboruri, sejururi, croaziere, inchirieri, recenzii
- **Endpoint-uri autentificate:** auth (login/register/logout/me/refresh/forgot), rezervari, favorite, profil
- **Endpoint-uri admin:** stats, rezervari, utilizatori, cabane, notificari
- Filtrare, sortare și paginare pe toate modulele
- Structură răspuns uniformă `{success, data, meta}`
- Calculul automat al prețului la rezervare (nopți × tarif)
- Integrare cupoane la rezervare (validare + înregistrare utilizare)
- Trimitere automată email confirmare rezervare
