# Quick Start Guide - Shortlink Dashboard

**Version:** 3.0.0
**Setup Time:** 10 minutes

---

## 🚀 Quick Setup (5 Steps)

### Step 1: Rename Folder (Manual)

```bash
# Close all terminals/editors using the folder
# Then rename:
cd E:\.rounting
rename domain-dashboard-final dashboard
```

**Why?** All bootstrap paths updated to use `dashboard/` folder name.

---

### Step 2: Run Database Migrations

```bash
cd E:\.rounting\dashboard

# Migration 008 - Random subdomain
mysql -u your_user -p your_database < database-migrations/008_add_shortlink_subdomain.sql

# Migration 009 - Domain selection
mysql -u your_user -p your_database < database-migrations/009_add_shortlink_domain_id.sql
```

**Verify:**
```sql
-- Check columns added
SHOW COLUMNS FROM shortlinks;
-- Should show: subdomain, domain_id, use_global_domain
```

---

### Step 3: Update Dashboard UI (Add Shortlink Form)

**File:** `dashboard/public/index.php`

**Find the Shortlinks tab section and replace with:**

```php
<!-- Shortlinks Tab -->
<div class="tab-pane fade" id="shortlinks">
    <?php include __DIR__ . '/components/shortlink-form.html'; ?>

    <!-- Existing shortlinks list (if any) -->
    <div class="mt-4">
        <h5>Existing Shortlinks</h5>
        <!-- Your existing shortlinks table here -->
    </div>
</div>
```

**Add CSRF meta tag in `<head>`:**
```html
<meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?? '' ?>">
```

---

### Step 4: Test the Feature

1. **Open Dashboard:**
   ```
   https://admin.yourdomain.com/
   ```

2. **Go to Shortlinks Tab**

3. **Create Test Shortlink:**
   - Destination URL: `https://google.com`
   - Title: `Google Homepage`
   - Domain: Select "Global Domain (Random)"
   - Count: `5`
   - Click "Generate Shortlinks"

4. **Verify Output:**
   ```
   https://xy7k2m.example.com/abc123
   https://de4fg7.example.com/xyz789
   https://mn8pq2.example.com/qwe456
   https://rs9tuv.example.com/def789
   https://wx3yz6.example.com/ghi012
   ```

5. **Click Copy Button** - URLs copied to clipboard!

---

### Step 5: Add Domains (If None Exist)

**Go to Domains Tab:**
1. Click "Add Domain"
2. Enter: `example.com`
3. Cloudflare Zone ID: (optional)
4. Click "Add"

**Repeat for multiple domains:**
- `example01.com`
- `example02.com`
- `example03.com`

**Why?** Domain dropdown needs active domains to display.

---

## ✅ Verification Checklist

After setup, verify:

- [ ] Folder renamed to `dashboard/`
- [ ] Migrations 008 & 009 completed
- [ ] Component included in index.php
- [ ] CSRF meta tag added
- [ ] Bootstrap Icons CSS loaded
- [ ] At least 1 domain added
- [ ] Test shortlink created successfully
- [ ] Copy button works
- [ ] Subdomain format correct: `{random}.{domain}/{slug}`

---

## 📋 Features Overview

### Input Fields

| Field | Required | Description |
|-------|----------|-------------|
| Destination URL | ✅ Yes | Target URL for redirect |
| Title | ❌ Optional | Open Graph title (social media) |
| Description | ❌ Optional | Open Graph description |
| Image URL | ❌ Optional | Open Graph image (1200x630px) |
| Domain | ✅ Yes | Global (random) or specific domain |
| Shim Page | ❌ Optional | Intermediate page with countdown |
| Bulk Count | ✅ Yes | Number of links (1-25) |

### Output

- **Textarea:** All generated URLs (one per line)
- **Copy Button:** Copy all URLs to clipboard
- **Link Count:** Number of links created
- **Success Message:** Confirmation with stats

---

## 🔧 Configuration

### Update Domain URLs in Service (Optional)

**File:** `dashboard/src/Service/ShortlinkService.php`

**Line 312-323:**
```php
private function getDomainForShortlink(array $data): string
{
    // If specific domain selected, get from database
    if (!empty($data['domain_id']) && is_numeric($data['domain_id'])) {
        // Get domain from DomainRepository
        $domainRepo = new \App\Repository\DomainRepository($this->pdo);
        $domain = $domainRepo->findById((int) $data['domain_id']);
        if ($domain) {
            return $domain['domain'];
        }
    }

    // Global domain - get first available
    $domainRepo = new \App\Repository\DomainRepository($this->pdo);
    $domains = $domainRepo->findAll(['status' => 'active', 'limit' => 1]);
    return !empty($domains) ? $domains[0]['domain'] : 'example.com';
}
```

**Why?** This makes URL generation use real domain names from database.

---

## 💡 Usage Examples

### Example 1: Single Link (Global Domain)

**Input:**
```
Destination URL: https://mysite.com/product
Title: Amazing Product
Domain: Global Domain (Random)
Count: 1
```

**Output:**
```
https://xy7k2m.example.com/abc123
```

**Behavior:**
- Each click might use different domain
- Anti-block mechanism active

---

### Example 2: Bulk Links (Specific Domain)

**Input:**
```
Destination URL: https://mysite.com/promo
Title: Limited Offer
Domain: example02.com
Count: 10
```

**Output:**
```
https://ab3def.example02.com/mn7pq2
https://gh4ijk.example02.com/rs8tuv
https://wx5yz6.example02.com/ab9cde
... (10 links total)
```

**Behavior:**
- All links use `example02.com`
- Each has unique subdomain + slug

---

### Example 3: With Shim Page

**Input:**
```
Destination URL: https://mysite.com/offer
Title: Special Deal
Image URL: https://mysite.com/promo.jpg
☑ Enable Shim Page
Domain: Global Domain
Count: 5
```

**Flow:**
1. Click → `https://xy7k2m.example.com/abc123`
2. Redirect → `https://example.com/shim.php?slug=abc123&dest=...`
3. Shim page shows countdown (5s)
4. Final redirect → `https://mysite.com/offer`

**Benefits:**
- Better Facebook/WhatsApp preview
- Analytics tracking
- Branded intermediate page

---

## 🐛 Troubleshooting

### Issue: Form not showing

**Solution:**
```bash
# Check file exists
ls dashboard/public/components/shortlink-form.html

# Check include path in index.php
grep -n "shortlink-form.html" dashboard/public/index.php
```

---

### Issue: "Failed to generate subdomain"

**Cause:** Too many collisions (database full)

**Solution:**
```sql
-- Check collision rate
SELECT
    COUNT(*) as total,
    COUNT(DISTINCT subdomain) as unique_subdomains,
    (1 - COUNT(DISTINCT subdomain)/COUNT(*)) as collision_rate
FROM shortlinks
WHERE subdomain IS NOT NULL;

-- If collision_rate > 0.8, increase length from 6 to 8 chars
```

---

### Issue: Domain dropdown empty

**Cause:** No active domains in database

**Solution:**
```sql
-- Check domains
SELECT * FROM domains WHERE status = 'active';

-- If empty, add domain via dashboard Domains tab
-- Or manually:
INSERT INTO domains (domain, subdomain, document_root, status)
VALUES ('example.com', 'example', '../redirect', 'active');
```

---

### Issue: Copy button not working

**Cause:** Browser clipboard API blocked

**Solution:**
1. Use HTTPS (required for clipboard API)
2. Or use manual select + Ctrl+C

**Fallback code (add to script):**
```javascript
// Fallback for older browsers
if (!navigator.clipboard) {
    textarea.select();
    document.execCommand('copy');
}
```

---

## 🔒 Security Checklist

Before going to production:

- [ ] `.env` file created (copy from `.env.example`)
- [ ] Database credentials secure
- [ ] CSRF tokens enabled (done automatically)
- [ ] HTTPS enabled
- [ ] Security headers active (auto in bootstrap/init.php)
- [ ] File permissions correct (644 for files, 755 for folders)
- [ ] `install.php` deleted (done)
- [ ] Error display OFF in production (`display_errors = Off`)

---

## 📊 Monitoring

### Check Shortlink Stats

```sql
-- Total shortlinks
SELECT COUNT(*) FROM shortlinks;

-- Subdomain collision rate
SELECT (1 - COUNT(DISTINCT subdomain)/COUNT(*)) as collision_rate
FROM shortlinks
WHERE subdomain IS NOT NULL;

-- Links by domain selection
SELECT
    use_global_domain,
    COUNT(*) as count
FROM shortlinks
GROUP BY use_global_domain;

-- Top domains used
SELECT
    d.domain,
    COUNT(s.id) as link_count
FROM shortlinks s
LEFT JOIN domains d ON s.domain_id = d.id
GROUP BY d.domain
ORDER BY link_count DESC;
```

---

## 📚 Next Steps

1. **Add Custom Domains:**
   - Go to Domains tab
   - Add your domains
   - Set up DNS records (wildcard A record)

2. **Configure Shim Page:**
   - Go to System Settings tab
   - Customize shim message
   - Set countdown delay
   - Update button text

3. **Set Up Analytics:**
   - View click stats in dashboard
   - Monitor subdomain collision rate
   - Track domain usage

4. **Integrate with External Tools:**
   - Use API endpoint for automation
   - Export URLs to CSV
   - Bulk import campaigns

---

## 🆘 Support

**Documentation:**
- `SHORTLINK_FEATURES.md` - Complete feature guide
- `DOCROOT_CONFIGURATION.md` - Folder structure guide
- `SYSTEM_SETTINGS_DEPLOYMENT.md` - System settings guide

**Logs:**
```bash
# PHP errors
tail -f /var/log/php/error.log

# Apache errors
tail -f /var/log/apache2/error.log

# Application logs
tail -f dashboard/storage/logs/app.log
```

**Common Files:**
- Service: `dashboard/src/Service/ShortlinkService.php`
- Repository: `dashboard/src/Repository/ShortlinkRepository.php`
- AJAX: `dashboard/public/ajax/create-bulk-shortlinks.php`
- Form: `dashboard/public/components/shortlink-form.html`

---

**Setup complete! Start creating shortlinks! 🎉**

**Last Updated:** 2025-12-26
