# STAX Sales Progress Widget for GHL Dashboard

A JavaScript widget that displays real-time sales progress trackers on a GoHighLevel (GHL) dashboard, showing total revenue and new client revenue against configured goals with visual progress indicators.

## Overview

This script injects interactive progress widgets into a GHL dashboard page for specific location IDs. It fetches sales data from an API and displays two circular progress trackers showing:
- **Total Revenue** progress against goal
- **New Client Revenue** progress against goal

The widgets feature segmented circular progress indicators, bar progress trackers, and formatted currency displays.

## Features

- 📊 **Dual Progress Trackers** - Total Revenue and New Client Revenue
- 🎨 **Segmented Circular Progress** - Visual conic-gradient progress with segments
- 📈 **Bar Progress Indicator** - 10-segment bar showing completion level
- 💰 **Formatted Currency** - Auto-formatted USD values with thousand separators
- 📱 **Responsive Design** - Mobile-friendly layout with adaptive sizing
- 🔄 **Route Change Detection** - Re-initializes on SPA navigation events
- 🎯 **Location-Specific** - Only activates for configured location ID
- ⏱️ **Delayed Initialization** - Waits for dashboard to fully load (15 seconds)

## How It Works

### Data Flow Diagram

```
┌─────────────────────────────────────────────────────────────┐
│                    GHL Dashboard Page                        │
│  URL: /location/[LOCATION_ID]/...                           │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│              STAX Widget Script Initialization               │
│  1. Check Location ID matches "Yjkpt82b8Vqjm10Ir9tD"        │
│  2. Wait 15 seconds for dashboard to load                   │
│  3. Inject styles and DOM elements                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    API Request                               │
│  POST → https://kangaroo.growsimple.io/api.php              │
│  Data: { action: "get_stax_details" }                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Response Parsing                          │
│  {                                                          │
│    goal_sale: "150,000",           // Total revenue goal   │
│    total_sale: 38200,              // Current total revenue│
│    new_client_goal_sale: "150,000",// New client goal      │
│    new_client_sale: 85000          // Current new client   │
│  }                                                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                  Widget Rendering                            │
│  • Circular progress with segments                          │
│  • Percentage display                                       │
│  • Bar progress (10 segments)                               │
│  • Goal vs current comparison                               │
│  • Remaining amount calculation                             │
└─────────────────────────────────────────────────────────────┘
```
### Target Location ID

The widget only activates for this specific location:
```javascript
locationId === "Yjkpt82b8Vqjm10Ir9tD"
```

To target different locations, modify the condition:
```javascript
const targetLocations = ["Yjkpt82b8Vqjm10Ir9tD", "another-location-id"];
if (targetLocations.includes(locationId)) {
  // Execute widget
}
```

### API Endpoint

The script calls:
```
URL: https://kangaroo.growsimple.io/api.php
Method: POST
Data: { action: "get_stax_details" }
```

### Expected API Response Format

```json
{
  "goal_sale": "153,000",
  "total_sale": 38200,
  "new_client_goal_sale": "153,000",
  "new_client_sale": 85000
}
```

## DOM Structure Requirements

The widget looks for this element to position itself:
```html
<div class="dashboard-divider"></div>
```

The widget is inserted immediately after this element.

## Visual Components

### Progress Container Structure

```html
<div class="progress-wrapper">
  <!-- Total Revenue Widget -->
  <div class="progress-container">
    <div class="progress-circle">
      <span>25%</span>
    </div>
    <div class="heading-text">Total Revenue</div>
    <div class="progress-text">$38,200 of $153,000 Goal</div>
    <div class="progress-bar">
      <div class="filled"></div>
      <div class="filled"></div>
      <div class="filled"></div>
      <div></div>
      <!-- ... 10 segments total ... -->
    </div>
    <div class="remaining-text">$114,800 to go!</div>
  </div>
  
  <!-- New Client Revenue Widget -->
  <!-- Same structure -->
</div>
```

### Progress Indicators

| Component | Description |
|-----------|-------------|
| **Circular Progress** | Segmented circle showing percentage (2% segments with 1% gaps) |
| **Percentage Text** | Centered number showing completion % |
| **Bar Progress** | 10 horizontal segments, colored when filled |
| **Goal Text** | Display of current vs goal amount |
| **Remaining Text** | Amount left to reach goal |

## Styling Specifications

### Colors
- **Primary Color**: `#2196F3` (Blue) - Progress fill
- **Empty Segments**: `#545353` (Dark Gray)
- **Gap Color**: `#FFFFFF` (White)
- **Text Colors**: 
  - Headings: `#2196F3`
  - Remaining amount: `#2196F3`
  - "to go!" text: `#000000`

### Dimensions
| Element | Desktop | Mobile |
|---------|---------|--------|
| Circle Diameter | 200px | 150px |
| Inner Circle | 140px | 100px |
| Segment Size | 2% | 2% |
| Gap Size | 1% | 1% |
| Bar Segments | 30x30px | - |

## Core Functions

### `addStaxSaleWidget()`
Main function that:
- Injects styles
- Validates location ID
- Fetches API data
- Creates and renders widgets
- Updates progress displays

### `updateProgress(elementId, raised, goal)`
Updates a specific progress widget with:
- Percentage calculation
- Circular progress gradient
- Bar segment fills
- Text updates (goal, remaining)

### `createSegmentedProgress(percentage)`
Generates a conic-gradient string for segmented circular progress:
- Creates 2% segments
- Adds 1% gaps between segments
- Colors segments based on percentage
- Returns valid CSS `conic-gradient()` value

## Progress Calculation Logic

### Percentage Calculation
```javascript
percentage = (raised / goal) * 100
```

### Bar Segments
```javascript
barCount = 10
filledCount = Math.round((raised / goal) * barCount)
// Example: 38% → 4 filled segments
```

### Circular Segments
```javascript
segmentSize = 2%  // Each colored block
gapSize = 1%      // Space between blocks
// Total cycle = 3% per segment-gap pair
// 100% / 3% ≈ 33 segments maximum
```

## Event Handling

### Route Change Detection
```javascript
window.addEventListener("routeChangeEvent", function (e) {
  setTimeout(() => {
    addStaxSaleWidget()
  }, 15000);
});
```
- Listens for SPA navigation events
- Re-initializes widget after route change
- 15-second delay ensures dashboard loads

### Dependencies
- **jQuery** - Required for AJAX requests
- **Modern Browser** - ES6 features used

## Error Handling

The script includes error handling for:

| Error Scenario | Handling |
|----------------|----------|
| Missing location ID | Console error, function exits |
| Wrong location ID | Silent exit, no widget added |
| Missing dashboard-divider | Console error, no insertion |
| API request fails | Console error with status |
| Invalid response format | Console error |
| Missing required fields | Graceful degradation |

### Change Colors

Modify the gradient colors in `createSegmentedProgress`:
```javascript
// Change to green theme
`#4CAF50 ${i}% ${i + segmentSize}%`  // Filled
`#e0e0e0 ${i}% ${i + segmentSize}%`   // Empty
```

### Adjust Delay Time

Change the initialization delay:
```javascript
setTimeout(() => {
  addStaxSaleWidget()
}, 5000);  // 5 seconds instead of 15
```

### Add More Trackers

Duplicate the progress container and modify:
```javascript
const html = `
  <div class="progress-wrapper">
    <!-- Existing trackers -->
    <div class="progress-container" id="progress-container-3">
      <!-- New tracker content -->
    </div>
  </div>
`;
```

## Usage Examples

### Manual Trigger

Trigger the widget from console:
```javascript
addStaxSaleWidget();
```

### Force Refresh

Refresh widget data:
```javascript
// Remove existing widgets first
document.querySelectorAll(".progress-container").forEach(el => el.remove());
// Re-initialize
addStaxSaleWidget();
```

### Modify Goal Formatting

Change currency display:
```javascript
// In updateProgress function, change:
document.querySelector(`#${elementId} .progress-text`).innerHTML =
  `€${raised.toLocaleString()} of €${goal.toLocaleString()} Goal`; // Euro
```