# 🎯 Media Simplified — Client Support Hub

A **client-facing support portal** built as a single self-contained HTML page, designed to be embedded inside a GoHighLevel client sub-account as a custom menu page or iframe widget. It gives Media Simplified clients one central place to access every resource they need — from submitting tickets and booking calls, to requesting websites, downloading invoices, and accessing training — all without leaving their GHL dashboard.

---

## 📁 Project Structure

```
support_center/
└── index.html    # Complete single-file support hub — no backend required
```

---

## 🌐 How It Embeds in GHL

The page is designed to run **inside a GHL iframe** (custom menu link or client portal widget). On load it:

1. Reads the **Location ID** from the URL — either from `?location_id=`, `?locationId=`, or `/location/{id}/` in the path
2. Displays the detected Location ID in the top navigation bar (with one-click copy)
3. Appends the Location ID to any action URL that has `appendLocationId: true`
4. Sends `postMessage` commands to the **parent GHL window** for actions like opening a chat widget or launching an iframe overlay

The page works standalone in a browser too — it just won't have a Location ID unless one is passed in the URL.

---

## 📄 Page Structure

```
┌─────────────────────────────────────────┐
│  Top Nav — Logo + Location ID badge     │
├─────────────────────────────────────────┤
│  Hero — Headline + CTA buttons          │
├─────────────────────────────────────────┤
│  Search Bar — Live search across all    │
│               actions                   │
├─────────────────────────────────────────┤
│  Main Content — Accordion Sections      │
│   ├── MS Loyalty Program                │
│   ├── Take Action                       │
│   ├── Request Help                      │
│   ├── Branding / Websites               │
│   ├── Client Support Center             │
│   └── Extras                            │
├─────────────────────────────────────────┤
│  Footer                                 │
└─────────────────────────────────────────┘
```

---

## 🧩 Features

### 1. Location ID Auto-Detection

On `DOMContentLoaded`, the script checks:
1. `?location_id=` query parameter
2. `?locationId=` query parameter
3. `/location/{id}/` in the URL path
4. Same checks against `document.referrer` (for iframe contexts)

The detected ID is shown in the top-right of the nav bar. Clicking it copies it to the clipboard and shows a toast confirmation.

---

### 2. Accordion Sections

The main content area is divided into **6 collapsible sections**, each rendered dynamically from the `SECTIONS` array. Sections default to open or closed based on `defaultOpen`.

| Section | Color | Default State | Purpose |
|---|---|---|---|
| MS Loyalty Program | Blue | Open | Reviews, testimonials, referrals |
| Take Action | Green | Open | Card updates, lead uploads, user management |
| Request Help | Orange | Open | Live chat, tickets, booking, phone, cancel |
| Branding / Websites | Purple | Closed | Website and branding request forms |
| Client Support Center | Cyan | Closed | Training, playbooks, webinars, YouTube |
| Extras | Red | Closed | AI CRM support, video knowledge base |

Each section:
- Has a colored icon, title, and resource count
- Expands/collapses with a smooth CSS max-height transition
- Shows a 2-column grid of action buttons on desktop, 1-column on mobile
- Chevron rotates and turns navy blue when open

---

### 3. Actions System

All interactive items are defined in the `ACTIONS` array. Each action has a `section` ID to determine which accordion it appears in, and a behavior flag:

| Flag | Behavior |
|---|---|
| `openInIframe: true` | Sends `MS_OPEN_IFRAME` postMessage to parent GHL window with the URL |
| `openInNewTab: true` | Opens URL in a new browser tab (`noopener, noreferrer`) |
| `appendLocationId: true` | Appends `?locationId={id}` to the URL before opening |
| `isChat: true` | Sends `openChatWidget` postMessage to parent GHL window |
| `isContact: true` | Shows a toast + redirects to `tel:321-341-5101` |

---

### 4. Complete Action Inventory

#### 🤝 MS Loyalty Program
| Action | Behavior | Destination |
|---|---|---|
| Leave a review | New tab | `mediasimplified.io/review` |
| Record a testimonial vid | iframe + locationId appended | Reputation Hub video collector |
| Send a referral | iframe | `mediasimplified.io/Referralform` |

#### ⚡ Take Action
| Action | Behavior | Destination |
|---|---|---|
| Update / put new card on file | iframe | `mediasimplified.io/payment-update` |
| Upload an aged lead list | iframe | `mediasimplified.io/upload-lead-list` |
| Changing companies | iframe | `mediasimplified.io/change-companies` |
| Add a new user | iframe | `mediasimplified.io/add-user` |
| Add a new Lead source | iframe | GHL survey form |
| Download my invoices | iframe + locationId appended | Invoice Receipt Downloader widget |

#### 🎧 Request Help
| Action | Behavior | Destination |
|---|---|---|
| Live Chat Support | `openChatWidget` postMessage | GHL live chat widget |
| Submit Support Ticket | iframe | GHL support ticket form |
| Book a call with us | iframe | GHL booking widget |
| Contact now | Toast + `tel:` link | 321-341-5101 |
| Pause or cancel account | iframe | `mediasimplified.io/cancel` |

#### 🎨 Branding / Websites
| Action | Behavior | Destination |
|---|---|---|
| Request New Website | iframe | `mediasimplified.io/websiterequestform` |
| Request new Branding Asset | iframe | `mediasimplified.io/BrandingRequest` |

#### 🎓 Client Support Center
| Action | Behavior | Destination |
|---|---|---|
| MS Training | iframe | `mediasimplified.io/launchvideo` |
| Playbooks | iframe | `mediasimplified.io/loanlaunch-playbooks-8131` |
| Attend Weekly Zoom Training | iframe | `mediasimplified.io/client-webinar` |
| Follow us on Youtube | New tab | Media Simplified YouTube channel |

#### ✨ Extras
| Action | Behavior | Destination |
|---|---|---|
| AI CRM Support | iframe | `mediasimplified.io/ai-helpwidget` |
| Video Knowledge Base | iframe | `mediasimplified.io/support-home` |

---

### 5. Live Search

The search bar at the top filters across all actions in real time:
- Matches against both `title` and `desc` fields (case-insensitive)
- Displays results in a dropdown below the search bar
- Clicking a result executes the action and clears the search
- A clear (✕) button appears when text is entered
- Clicking outside the search area closes the dropdown
- Lucide icons are re-initialized after each render to ensure new icons display

---

### 6. Parent Frame Communication (`postMessage`)

Since the hub runs inside a GHL iframe, it cannot directly control the parent window's DOM. Instead it uses `window.parent.postMessage()` for two scenarios:

```javascript
// Open a URL in GHL's own iframe overlay
window.parent.postMessage({ action: "MS_OPEN_IFRAME", iframeUrl: url }, "*");

// Toggle GHL's built-in live chat widget
window.parent.postMessage({ action: "openChatWidget" }, "*");
```

The parent GHL extension or wrapper listens for these messages and takes the appropriate action.

---

### 7. Incoming `postMessage` Listener — Remote Accordion Control

The hub also **receives** `postMessage` events from the parent frame. This allows external scripts (such as Chrome Extension content scripts) to remotely highlight or expand specific sections of the hub.

#### Supported Message Types

**`OPEN_ACCORDIAN_AND_HIGHLIGHT`**
- Finds the "Client Support Center" accordion section
- Expands it if not already open (scrolls into view first, then clicks after 300ms)
- After 600ms, finds the **"MS Training"** action button
- Applies a blue highlight border (`border: 3px solid #0ea5e9`) to it for 10 seconds
- Shows a toast: *"🎓 Click MS Training to open the full training library!"*
- If the element is not found: shows a fallback blue tip panel (fixed, right side) with instructions and a dismiss button

**`OPEN_ACCORDIAN_AND_HIGHLIGHT_ATTEND_WEEKLY`**
- Same accordion expansion logic as above
- After 600ms, finds the **"Attend Weekly Zoom Training"** action button
- Applies the same blue highlight border for 10 seconds
- Shows a toast: *"📅 Click 'Attend Weekly Zoom Training' to join the live sessions!"*
- If not found: fallback tip panel with instructions

Both handlers use a guard check — if the target element is already visible on screen, the accordion click is skipped (no double-toggle).

---

### 8. Toast Notification System

A slide-up toast appears at the bottom center of the screen for brief feedback:
- Triggered by `showToast(message)`
- Auto-dismisses after 3 seconds
- Used for: Location ID copy confirmation, phone number display, chat widget toggle status, postMessage highlights

---

## 🎨 Design System

| Token | Value | Usage |
|---|---|---|
| `primary` | `#0F2B5B` | Nav background, headings, focus rings |
| `secondary` | `#2563EB` | Active states, links |
| `accent` | `#06B6D4` | Highlight accents |
| `background` | `#F1F5F9` | Page background |
| `success` | `#10B981` | Success indicators |
| Font (body) | DM Sans | All body text |
| Font (headings) | Fraunces | Hero headline |

**UI patterns used:**
- Glass morphism (hero section overlays: `backdrop-filter: blur`)
- Smooth accordion transitions (CSS `max-height` + `opacity`)
- Lucide icon set (loaded from unpkg CDN)
- Tailwind CSS utility classes (loaded from CDN — no build step)
- Custom scrollbar styling
- `animate-fade-in` keyframe on hero elements

---

## 🔧 Adding or Editing Actions

All actions are defined in the `ACTIONS` array in the `<script>` block. To add a new action:

```javascript
{
  id: "unique-id",           // Unique string ID
  section: "help",           // Must match a SECTIONS id value
  title: "Action Label",     // Shown as button text
  desc: "Short description", // Shown as button subtitle
  icon: "lucide-icon-name",  // Any icon from lucide.dev
  url: "https://...",        // Target URL (or null for special actions)
  openInIframe: true,        // Send MS_OPEN_IFRAME postMessage to parent
  // OR
  openInNewTab: true,        // Open in new browser tab
  // OR
  appendLocationId: true,    // Append ?locationId=... to URL, then iframe
  // OR
  isChat: true,              // Send openChatWidget postMessage to parent
  // OR
  isContact: true,           // Show toast + dial phone number
}
```

To add a new **section**, add an entry to the `SECTIONS` array and define a color entry in `SECTION_COLORS`.

---

## 📦 Dependencies

All loaded from CDN — no npm, no build step required:

| Dependency | Source | Purpose |
|---|---|---|
| Tailwind CSS | `cdn.tailwindcss.com` | Utility-first styling |
| Lucide Icons | `unpkg.com/lucide@latest` | Icon set |
| Google Fonts (DM Sans + Fraunces) | `fonts.googleapis.com` | Typography |

---

## 🛡️ Notes

- The `*` origin in `postMessage` calls means any parent frame can receive these messages. In production this should be scoped to the GHL domain (`https://app.gohighlevel.com`) for security.
- The Location ID shown in the nav bar is purely informational — it is never sent to any backend.
- Several blocks of code are commented out — these are earlier versions of the accordion highlight logic (fixed overlay divs, pulse animations) that were replaced by the simpler inline border approach currently in use.
- The `isGhlChatOpen` flag tracks chat toggle state locally but resets on page reload since there is no persistent state.