# Hero Banners API Documentation

## Overview

The Hero Banners API provides endpoints to manage multiple hero banners for your website. Each banner can have an image, title, subtitle, button text, and button link. Banners can be reordered and toggled active/inactive.

---

## Data Model

### HeroBanner
```json
{
  "id": "uuid",
  "imageUrl": "string",              // Relative path without base URL
  "title": "string (optional)",
  "subtitle": "string (optional)",
  "buttonText": "string (optional)",
  "buttonLink": "string (optional)",
  "displayOrder": "number",           // Order for carousel/display
  "isActive": "boolean",              // Whether banner is shown
  "createdAt": "ISO 8601 DateTime",
  "updatedAt": "ISO 8601 DateTime"
}
```

---

## API Endpoints

### 1. Get All Hero Banners (Admin)
Retrieve all hero banners (active and inactive).

**Endpoint:**
```
GET /api/site-settings/hero-banners/all
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
```

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "All hero banners retrieved successfully",
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "imageUrl": "hero-banner/banner-1715069300000-123456789.jpg",
      "title": "Welcome to Our Website",
      "subtitle": "Discover amazing products and services",
      "buttonText": "Learn More",
      "buttonLink": "https://example.com/learn",
      "displayOrder": 0,
      "isActive": true,
      "createdAt": "2026-05-26T10:00:00Z",
      "updatedAt": "2026-05-26T10:00:00Z"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "imageUrl": "hero-banner/banner-1715069400000-987654321.jpg",
      "title": "Special Offer",
      "subtitle": "Get 50% off this week",
      "buttonText": "Shop Now",
      "buttonLink": "https://example.com/shop",
      "displayOrder": 1,
      "isActive": true,
      "createdAt": "2026-05-26T11:00:00Z",
      "updatedAt": "2026-05-26T11:00:00Z"
    }
  ]
}
```

---

### 2. Get Active Hero Banners (Public)
Retrieve only active hero banners ordered by displayOrder.

**Endpoint:**
```
GET /api/site-settings/hero-banners/active
```

**Authentication:** None required (Public endpoint)

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "Active hero banners retrieved successfully",
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "imageUrl": "hero-banner/banner-1715069300000-123456789.jpg",
      "title": "Welcome to Our Website",
      "subtitle": "Discover amazing products and services",
      "buttonText": "Learn More",
      "buttonLink": "https://example.com/learn",
      "displayOrder": 0,
      "isActive": true,
      "createdAt": "2026-05-26T10:00:00Z",
      "updatedAt": "2026-05-26T10:00:00Z"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "imageUrl": "hero-banner/banner-1715069400000-987654321.jpg",
      "title": "Special Offer",
      "subtitle": "Get 50% off this week",
      "buttonText": "Shop Now",
      "buttonLink": "https://example.com/shop",
      "displayOrder": 1,
      "isActive": true,
      "createdAt": "2026-05-26T11:00:00Z",
      "updatedAt": "2026-05-26T11:00:00Z"
    }
  ]
}
```

---

### 3. Create Hero Banner
Create a new hero banner with image upload.

**Endpoint:**
```
POST /api/site-settings/hero-banners
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
Content-Type: multipart/form-data
```

**Request Body (Form Data):**
- `image` (file, required) - Image file (JPEG, PNG, GIF, WebP). Max 5MB
- `title` (string, optional)
- `subtitle` (string, optional)
- `buttonText` (string, optional)
- `buttonLink` (string, optional)
- `displayOrder` (number, optional) - Display order in carousel
- `isActive` (boolean, optional, default: true)

**cURL Example:**
```bash
curl -X POST http://localhost:5000/api/site-settings/hero-banners \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@/path/to/hero-banner.jpg" \
  -F "title=Welcome to Our Website" \
  -F "subtitle=Discover amazing products" \
  -F "buttonText=Learn More" \
  -F "buttonLink=https://example.com/learn" \
  -F "displayOrder=0" \
  -F "isActive=true"
```

**Response:**
```json
{
  "statusCode": 201,
  "success": true,
  "message": "Hero banner created successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "imageUrl": "hero-banner/banner-1715069300000-123456789.jpg",
    "title": "Welcome to Our Website",
    "subtitle": "Discover amazing products",
    "buttonText": "Learn More",
    "buttonLink": "https://example.com/learn",
    "displayOrder": 0,
    "isActive": true,
    "createdAt": "2026-05-26T10:00:00Z",
    "updatedAt": "2026-05-26T10:00:00Z"
  }
}
```

---

### 4. Update Hero Banner
Update an existing hero banner (with optional new image).

**Endpoint:**
```
PATCH /api/site-settings/hero-banners/{id}
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
Content-Type: multipart/form-data
```

**URL Parameters:**
- `id` (string, uuid) - The ID of the hero banner to update

**Request Body (Form Data):**
- `image` (file, optional) - New image file to replace current image
- `title` (string, optional)
- `subtitle` (string, optional)
- `buttonText` (string, optional)
- `buttonLink` (string, optional)
- `displayOrder` (number, optional)
- `isActive` (boolean, optional)

**cURL Example:**
```bash
curl -X PATCH http://localhost:5000/api/site-settings/hero-banners/550e8400-e29b-41d4-a716-446655440001 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@/path/to/new-image.jpg" \
  -F "title=Updated Title" \
  -F "subtitle=Updated Subtitle" \
  -F "isActive=true"
```

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "Hero banner updated successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "imageUrl": "hero-banner/banner-1715069500000-111111111.jpg",
    "title": "Updated Title",
    "subtitle": "Updated Subtitle",
    "buttonText": "Learn More",
    "buttonLink": "https://example.com/learn",
    "displayOrder": 0,
    "isActive": true,
    "createdAt": "2026-05-26T10:00:00Z",
    "updatedAt": "2026-05-26T15:30:00Z"
  }
}
```

---

### 5. Remove Hero Banner
Delete a hero banner by ID.

**Endpoint:**
```
DELETE /api/site-settings/hero-banners/{id}
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
```

**URL Parameters:**
- `id` (string, uuid) - The ID of the hero banner to delete

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "Hero banner removed successfully",
  "data": null
}
```

---

### 6. Reorder Hero Banners
Update the display order of multiple hero banners at once.

**Endpoint:**
```
POST /api/site-settings/hero-banners/reorder
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
Content-Type: application/json
```

**Request Body:**
```json
{
  "bannerIds": [
    "550e8400-e29b-41d4-a716-446655440001",
    "550e8400-e29b-41d4-a716-446655440002",
    "550e8400-e29b-41d4-a716-446655440003"
  ]
}
```

**cURL Example:**
```bash
curl -X POST http://localhost:5000/api/site-settings/hero-banners/reorder \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bannerIds": [
      "550e8400-e29b-41d4-a716-446655440001",
      "550e8400-e29b-41d4-a716-446655440002"
    ]
  }'
```

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "Hero banners reordered successfully",
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "displayOrder": 0,
      "...other fields..."
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "displayOrder": 1,
      "...other fields..."
    }
  ]
}
```

---

### 7. Toggle Hero Banner Status
Activate or deactivate a hero banner.

**Endpoint:**
```
PATCH /api/site-settings/hero-banners/{id}/toggle
```

**Authentication:** Required (ADMIN role)

**Headers:**
```
Authorization: Bearer <access_token>
Content-Type: application/json
```

**URL Parameters:**
- `id` (string, uuid) - The ID of the hero banner

**Request Body:**
```json
{
  "isActive": true
}
```

**cURL Example:**
```bash
curl -X PATCH http://localhost:5000/api/site-settings/hero-banners/550e8400-e29b-41d4-a716-446655440001/toggle \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": false
  }'
```

**Response:**
```json
{
  "statusCode": 200,
  "success": true,
  "message": "Hero banner deactivated successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "imageUrl": "hero-banner/banner-1715069300000-123456789.jpg",
    "title": "Welcome to Our Website",
    "subtitle": "Discover amazing products",
    "buttonText": "Learn More",
    "buttonLink": "https://example.com/learn",
    "displayOrder": 0,
    "isActive": false,
    "createdAt": "2026-05-26T10:00:00Z",
    "updatedAt": "2026-05-26T16:00:00Z"
  }
}
```

---

### 8. Get Hero Image
Download/view the hero banner image.

**Endpoint:**
```
GET /api/site-settings/hero-image/{filename}
```

**Authentication:** None required (Public endpoint)

**URL Parameters:**
- `filename` (string) - The filename from the imageUrl

**Example URL:**
```
http://localhost:5000/api/site-settings/hero-image/banner-1715069300000-123456789.jpg
```

**Response:**
- File download (image/jpeg, image/png, etc.)

---

## Complete Workflow Example

### Step 1: Create First Banner
```bash
curl -X POST http://localhost:5000/api/site-settings/hero-banners \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@banner1.jpg" \
  -F "title=Welcome" \
  -F "subtitle=First Banner" \
  -F "buttonText=Get Started" \
  -F "buttonLink=https://example.com/start" \
  -F "displayOrder=0" \
  -F "isActive=true"
```

### Step 2: Create Second Banner
```bash
curl -X POST http://localhost:5000/api/site-settings/hero-banners \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@banner2.jpg" \
  -F "title=Special Offer" \
  -F "subtitle=Limited Time" \
  -F "buttonText=Shop Now" \
  -F "buttonLink=https://example.com/shop" \
  -F "displayOrder=1" \
  -F "isActive=true"
```

### Step 3: Get All Active Banners (Frontend)
```bash
curl -X GET http://localhost:5000/api/site-settings/hero-banners/active
```

### Step 4: Update Banner
```bash
curl -X PATCH http://localhost:5000/api/site-settings/hero-banners/{id} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "title=Updated Title" \
  -F "subtitle=Updated Subtitle"
```

### Step 5: Reorder Banners
```bash
curl -X POST http://localhost:5000/api/site-settings/hero-banners/reorder \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bannerIds": ["id2", "id1"]
  }'
```

### Step 6: Display Banners (Frontend Implementation)
```javascript
// Fetch active banners
const response = await fetch('/api/site-settings/hero-banners/active');
const { data: banners } = await response.json();

// Display in carousel
banners.forEach(banner => {
  const imageUrl = `/api/site-settings/hero-image/${banner.imageUrl.split('/')[1]}`;
  console.log(`
    Image: ${imageUrl}
    Title: ${banner.title}
    Subtitle: ${banner.subtitle}
    Button: ${banner.buttonText} -> ${banner.buttonLink}
  `);
});
```

---

## Features

✅ **Multiple Banners** - Create and manage unlimited hero banners
✅ **Display Order** - Control the order of banners in carousel
✅ **Active/Inactive** - Toggle banners on/off without deleting
✅ **Image Upload** - Upload images via multipart/form-data
✅ **Button Support** - Each banner can have a call-to-action button
✅ **Flexible Fields** - Optional title, subtitle, button text/link
✅ **Public API** - Frontend can fetch active banners without authentication
✅ **Admin Control** - Only admins can create, update, delete, or reorder

---

## File Specifications

**Image Upload:**
- Formats: JPEG, PNG, GIF, WebP
- Max Size: 5MB
- Storage: `uploads/hero-banner/` directory
- Filename Pattern: `{name}-{timestamp}-{random}.{ext}`

**Image URL:**
- Stored as relative path: `hero-banner/banner-1715069300000-123456789.jpg`
- Access via: `/api/site-settings/hero-image/{filename}`

---

## Error Responses

**400 Bad Request - Missing Image:**
```json
{
  "statusCode": 400,
  "success": false,
  "message": "Image file is required",
  "data": null
}
```

**400 Bad Request - Invalid File Type:**
```json
{
  "statusCode": 400,
  "success": false,
  "message": "Only image files are allowed",
  "data": null
}
```

**400 Bad Request - Invalid Input:**
```json
{
  "statusCode": 400,
  "success": false,
  "message": "bannerIds array is required",
  "data": null
}
```

**401 Unauthorized:**
```json
{
  "statusCode": 401,
  "success": false,
  "message": "Authorization token is missing"
}
```

**403 Forbidden:**
```json
{
  "statusCode": 403,
  "success": false,
  "message": "You do not have permission to perform this action"
}
```

**404 Not Found:**
```json
{
  "statusCode": 404,
  "success": false,
  "message": "Hero banner not found"
}
```

---

## Version

API Version: 1.0.0  
Last Updated: 2026-05-26
