# Cloudinary Setup Guide for Hopenity

## Complete Integration Guide

This guide will help you set up Cloudinary for media management across Hopenity Admin Panel and Mobile App.

## Table of Contents
1. [Getting Started](#getting-started)
2. [Admin Panel Setup](#admin-panel-setup)
3. [Backend API Integration](#backend-api-integration)
4. [Mobile App Integration](#mobile-app-integration)
5. [Features](#features)
6. [API Endpoints](#api-endpoints)
7. [Troubleshooting](#troubleshooting)

---

## Getting Started

### Step 1: Create Cloudinary Account

1. Visit [Cloudinary.com](https://cloudinary.com)
2. Sign up for a free account
3. Verify your email address
4. Login to your dashboard

### Step 2: Get Your Credentials

1. Go to Dashboard → **Settings**
2. Scroll down to find your credentials:
   - **Cloud Name** - Your unique cloud identifier
   - **API Key** - Your public API key
   - **API Secret** - Your private API secret (keep this secure!)

### Step 3: Create Upload Preset (Optional but Recommended)

1. Go to **Upload** → **Upload Presets**
2. Click **Add upload preset**
3. Configure:
   - **Upload preset name**: `hopenity-unsigned`
   - **Signing mode**: Unsigned
   - **Folder**: `/hopenity/images`
4. Save the preset

---

## Admin Panel Setup

### Accessing Cloudinary Settings

1. Login to Hopenity Admin Panel
2. Navigate to **Settings** → **Cloudinary Configuration**
3. Or visit `/admin-panel/public/settings-cloudinary.php`

### Configuration Steps

1. **Cloud Name**
   - Copy from your Cloudinary dashboard
   - Example: `your-account-name`

2. **API Key**
   - Copy from dashboard Settings
   - Example: `123456789012345`

3. **API Secret**
   - Copy from dashboard Settings
   - ⚠️ Keep this secure - never commit to git

4. **Upload Preset** (Optional)
   - Name of your unsigned upload preset
   - Allows uploads without backend authentication

### Test Connection

Click "Test API Connection" to verify credentials are correct.

### Media Manager

Access the Media Manager at `/admin-panel/public/media-manager.php`:

- **Upload Images**: JPG, PNG, GIF, WebP (Max 50MB)
- **Upload Videos**: MP4, MOV, AVI, WebM (Max 500MB)
- **View Gallery**: Browse all uploaded media
- **Manage Files**: Copy URLs, delete unwanted files
- **Drag & Drop**: Easy drag-and-drop uploads

---

## Backend API Integration

### Environment Variables

Add to your `.env` file:

```env
CLOUDINARY_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
CLOUDINARY_UPLOAD_PRESET=hopenity-unsigned
```

### API Endpoints

#### Upload File

```bash
POST /api/upload
Content-Type: multipart/form-data

Parameters:
- file: [binary file]
- type: "image" or "video"
```

**Response:**
```json
{
  "success": true,
  "data": {
    "public_id": "hopenity/images/abc123",
    "url": "https://res.cloudinary.com/.../abc123.jpg",
    "size": 204800,
    "type": "image"
  }
}
```

#### Delete File

```bash
POST /api/upload/delete
Content-Type: application/json

{
  "public_id": "hopenity/images/abc123"
}
```

#### Get Upload Signature

```bash
GET /api/upload/signature
```

**Response:**
```json
{
  "signature": "abc123def456",
  "timestamp": 1234567890,
  "api_key": "your-api-key",
  "cloud_name": "your-cloud-name",
  "folder": "hopenity/images"
}
```

### Direct API Calls from Backend

```php
<?php
require_once 'CloudinaryUpload.php';

$uploader = new CloudinaryUpload(
    env('CLOUDINARY_NAME'),
    env('CLOUDINARY_API_KEY'),
    env('CLOUDINARY_API_SECRET')
);

// Upload image
$result = $uploader->upload($filePath, 'image');

// Delete file
$uploader->delete($publicId);

// Get usage stats
$stats = $uploader->getStats();
?>
```

---

## Mobile App Integration

### Kotlin/Android Implementation

#### 1. Add Retrofit Interceptor

```kotlin
class CloudinaryUploadInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        
        if (request.method == "POST" && request.url.toString().contains("cloudinary")) {
            // Add Cloudinary authentication if needed
        }
        
        return chain.proceed(request)
    }
}
```

#### 2. Upload Image/Video

```kotlin
// In PostViewModel.kt
fun uploadMedia(file: File, type: String) {
    viewModelScope.launch {
        try {
            val body = MultipartBody.Part.createFormData(
                "file",
                file.name,
                file.asRequestBody()
            )
            val typeBody = type.toRequestBody()
            
            val response = apiService.uploadMedia(body, typeBody)
            
            if (response.success) {
                postContent.value = response.data.url
                isLoading.value = false
            }
        } catch (e: Exception) {
            error.value = e.message
            isLoading.value = false
        }
    }
}
```

#### 3. Display Images

```kotlin
// Using Coil for image loading
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data(cloudinaryUrl)
        .crossfade(true)
        .build(),
    contentDescription = "Post Image",
    modifier = Modifier
        .fillMaxWidth()
        .height(300.dp)
        .clip(RoundedCornerShape(12.dp)),
    contentScale = ContentScale.Crop
)
```

#### 4. Play Videos

```kotlin
// Using ExoPlayer
val player = ExoPlayer.Builder(context).build()
player.setMediaItem(
    MediaItem.fromUri(videoUrl)
)
player.prepare()
```

---

## Features

### Image Optimization
- Automatic resizing and compression
- Format conversion (WEBP, AVIF)
- Responsive delivery

### Video Support
- HLS streaming
- MP4 transcoding
- Adaptive bitrate delivery

### Advanced Transformations

```
Resize: /w_400,h_300,c_crop/
Quality: /q_auto,f_auto/
Filter: /e_grayscale/
Overlay: /l_text:Arial_40:HelloWorld/
```

Example:
```
https://res.cloudinary.com/your-cloud/image/upload/w_400,h_300,c_crop/v1234567890/hopenity/images/photo.jpg
```

### CDN Integration
- Global CDN for fast delivery
- Automatic cache management
- No additional costs

### Storage Management
- 25GB free storage
- Bandwidth management
- Usage analytics

---

## Admin Panel API Endpoints

### Settings
- `POST /admin-panel/api/admin.php?action=save_settings`
- `GET /admin-panel/api/admin.php?action=get_settings`

### Cloudinary Management
- `GET /admin-panel/api/cloudinary.php?action=test` - Test connection
- `POST /admin-panel/api/cloudinary.php?action=upload` - Upload file
- `POST /admin-panel/api/cloudinary.php?action=delete` - Delete file
- `GET /admin-panel/api/cloudinary.php?action=list` - List files
- `GET /admin-panel/api/cloudinary.php?action=stats` - Get usage stats

---

## Security Best Practices

1. **Never commit API Secret**
   - Use environment variables
   - Add `.env` to `.gitignore`

2. **Use Upload Presets**
   - Enable unsigned uploads from mobile
   - Restrict file types and sizes

3. **Implement Rate Limiting**
   - Limit uploads per user
   - Monitor suspicious activity

4. **Validate on Backend**
   - Check file types
   - Verify file sizes
   - Scan for malware (premium feature)

5. **Use HTTPS Only**
   - Ensure secure connections
   - Enable SSL/TLS

---

## Troubleshooting

### Connection Failed
- Check credentials are correct
- Verify Cloud Name is valid
- Ensure API Key and Secret haven't expired

### Upload Errors
- Check file size limits (50MB images, 500MB videos)
- Verify file MIME types
- Ensure folder path is writable

### Slow Performance
- Use responsive images with transformations
- Enable CDN caching
- Optimize image formats

### API Rate Limiting
- Implement request queuing
- Add exponential backoff
- Check Cloudinary usage limits

---

## Support

- **Cloudinary Docs**: https://cloudinary.com/documentation
- **API Reference**: https://cloudinary.com/documentation/cloudinary_api
- **Pricing**: https://cloudinary.com/pricing
- **Status Page**: https://status.cloudinary.com

---

## Changelog

### v1.0 - Initial Release
- Cloudinary API integration
- Admin panel media manager
- Upload/delete functionality
- Image and video support
- Mobile app integration

---

**Last Updated**: 2026-05-11
**Version**: 1.0.0
