# Customer Profile Modal Feature for HighLevel

## Overview

This script adds a dynamic **Customer Profile** modal to the HighLevel platform (likely a SaaS or CRM system). It is designed to be injected into the conversation and contact detail pages. When a user clicks a "Profile" button, a detailed modal window displays comprehensive customer information, including personal details, lead generation data, setter/rover assignments, and client-specific notes.

The primary goal is to provide a quick, centralized view of all important customer data without leaving the current page, thereby improving efficiency for sales or support teams.

## Key Features

- **Dynamic Button Injection**: Automatically adds a "Profile" button to the UI on conversation and contact detail pages.
- **Context-Aware Data Fetching**: Detects the current page (conversation or contact detail) and retrieves the correct customer data using the HighLevel API (or internal endpoints).
- **Rich Customer Profile Modal**: Displays a wide range of customer data in a clean, tabular, and card-based layout.
- **Responsive & Resizable Modal**: The modal has a fixed width/height but includes `resize:both`, allowing users to adjust its size.
- **Custom Field Mapping**: Reads data from predefined HighLevel custom fields (e.g., `oXoVNJ0TskE7blWcmpYO` for Company Name) and maps them to UI elements.
- **Date Formatting**: Automatically formats raw date values for better readability.
- **Phone Number Formatting**: Formats phone numbers into a standard readable pattern.
- **Modal Close Functionality**: Provides multiple ways to close the modal (close button, Cancel button, backdrop click? - though backdrop not explicitly shown, the cancel button works).

## How It Works

### 1. Page Detection & Button Injection

- The function `append_1_Client_success_Profile_button()` runs periodically or on route changes.
- It checks if the current URL contains `/contacts/detail/` or `/conversations/`.
- If on an allowed page, it looks for a specific UI element (`#composer-textarea`).
- It then injects a custom "Profile" button just above the text input area, but only for a specific location ID (`ynCWf3Y4AEJ7hfQ4lVWE`).

### 2. Opening the Modal

- Clicking the "Profile" button triggers the `modal_profile()` function.
- This function calls `getClientSuccessData()` to asynchronously load all customer data.
- After data is loaded, it displays the modal (sets `display: block` and adds `.show` class).

### 3. Fetching Customer Data (`getClientSuccessData()`)

The function intelligently identifies the customer:

- **If on a contact detail page**: Extracts `contactId` directly from the URL.
- **If on a conversation page**: Extracts `conversationId`, calls `getConversationDetails()` (likely another helper) to get the associated `contactId`.

Once `contactId` is obtained, it calls `getContactDetails()` to fetch the full contact object, including all standard fields and custom fields.

It then maps custom field values (identified by their unique IDs) to JavaScript variables and updates the modal's HTML elements with formatted data.

### 4. Custom Fields Used

The script relies on several HighLevel custom fields (IDs hardcoded) to populate the modal. Examples include:

| Field ID | Purpose |
|----------|---------|
| `oXoVNJ0TskE7blWcmpYO` | Company Name |
| `RFjE1LqaGUr1oqcc76ja` | Monthly Ad Spend |
| `pX6Zu6ulMsEpUnQauQzp` | Monthly Retainer |
| `5dNdrPgC7DDEQgqjXWD3` | Next Renewal Date |
| `fkidWlwEnLZmQlrya2Zk` | Client Temperament |
| `9NjdITCKxiKbF0yJmH6g` | Assigned Setter |
| `aZQpt0O9XavF5n6R9K08` | Assigned Rover |
| `s7OoLM0FOYm2AgwNNSGJ` | Latest Customer Ticket |
| `ZIPkqG8y3pgBeqfjgd16` | Campaign Note |
| *(and many more)* | |

### 5. Modal Structure

The modal is divided into several sections:

1. **Header**: Customer name, avatar, and contact icons (phone, email, company, location, tier).
2. **Customer Details**: Cards showing launch date, next renewal, monthly retainer, client temperament.
3. **Lead Gen Details**: Cards for monthly ad spend, campaign source, active status, app integration, plus a notes section.
4. **Setter Details**: Assigned setter, last submission date, assigned rover, last rover submission.
5. **Latest Client Ticket**: A plain-text area showing the most recent support ticket or note.
6. **Client Specifics**: A bullet list of client-specific notes or instructions.
7. **Actions**: Cancel and Update Client buttons (Update functionality not shown in snippet).

### 6. Utility Functions

- `formatPhoneNumber()`: Formats the raw phone string (not shown in snippet but referenced).
- `formatDate()`: Converts a raw date string into a readable format (e.g., "August 27, 2025").
- `close_profile_modal()`: Hides the modal and removes the `.show` class.
- `accordion()`: (Placeholder) Shows an alert on click – likely intended for expanding/collapsing sections but not fully implemented.

## Integration Notes

- The script assumes the existence of global helper functions like `getConversationDetails()`, `getContactDetails()`, `getLocationId()`, and `formatPhoneNumber()`.
- It listens for a custom `routeChangeEvent` to re-run the button injection after page navigation (SPA behavior).
- The modal is injected into `#app` element only once (`setTimeout` check).
- The injection only happens for a specific `locationId` (`ynCWf3Y4AEJ7hfQ4lVWE`), making it tenant-specific.
- The modal uses **FontAwesome** icons (assumed available) and custom SVGs.

## Dependencies

- jQuery (for DOM manipulation and events)
- FontAwesome (for icons like `fa-phone`, `fa-envelope`, etc.)
- HighLevel’s internal API or service functions (`getContactDetails`, `getConversationDetails`)
- A parent element with ID `#app` in the DOM

## Possible Improvements

- Move custom field IDs to a configuration object for easier maintenance.
- Implement the "Update Client" button to save changes back to HighLevel.
- Add loading state while fetching data.
- Trap focus inside modal for accessibility.
- Replace inline styles with external CSS for cleaner code.
- Add error handling for missing custom fields or failed API calls.

## Conclusion

This feature greatly enhances the user experience for CRM users by providing instant access to enriched customer profiles directly within conversation and contact views. It reduces context switching and ensures that all team members have the same, up‑to‑date client information at their fingertips.# Customer Profile Modal Feature for HighLevel

## Overview

This script adds a dynamic **Customer Profile** modal to the HighLevel platform (likely a SaaS or CRM system). It is designed to be injected into the conversation and contact detail pages. When a user clicks a "Profile" button, a detailed modal window displays comprehensive customer information, including personal details, lead generation data, setter/rover assignments, and client-specific notes.

The primary goal is to provide a quick, centralized view of all important customer data without leaving the current page, thereby improving efficiency for sales or support teams.

## Key Features

- **Dynamic Button Injection**: Automatically adds a "Profile" button to the UI on conversation and contact detail pages.
- **Context-Aware Data Fetching**: Detects the current page (conversation or contact detail) and retrieves the correct customer data using the HighLevel API (or internal endpoints).
- **Rich Customer Profile Modal**: Displays a wide range of customer data in a clean, tabular, and card-based layout.
- **Responsive & Resizable Modal**: The modal has a fixed width/height but includes `resize:both`, allowing users to adjust its size.
- **Custom Field Mapping**: Reads data from predefined HighLevel custom fields (e.g., `oXoVNJ0TskE7blWcmpYO` for Company Name) and maps them to UI elements.
- **Date Formatting**: Automatically formats raw date values for better readability.
- **Phone Number Formatting**: Formats phone numbers into a standard readable pattern.
- **Modal Close Functionality**: Provides multiple ways to close the modal (close button, Cancel button, backdrop click? - though backdrop not explicitly shown, the cancel button works).

## How It Works

### 1. Page Detection & Button Injection

- The function `append_1_Client_success_Profile_button()` runs periodically or on route changes.
- It checks if the current URL contains `/contacts/detail/` or `/conversations/`.
- If on an allowed page, it looks for a specific UI element (`#composer-textarea`).
- It then injects a custom "Profile" button just above the text input area, but only for a specific location ID (`ynCWf3Y4AEJ7hfQ4lVWE`).

### 2. Opening the Modal

- Clicking the "Profile" button triggers the `modal_profile()` function.
- This function calls `getClientSuccessData()` to asynchronously load all customer data.
- After data is loaded, it displays the modal (sets `display: block` and adds `.show` class).

### 3. Fetching Customer Data (`getClientSuccessData()`)

The function intelligently identifies the customer:

- **If on a contact detail page**: Extracts `contactId` directly from the URL.
- **If on a conversation page**: Extracts `conversationId`, calls `getConversationDetails()` (likely another helper) to get the associated `contactId`.

Once `contactId` is obtained, it calls `getContactDetails()` to fetch the full contact object, including all standard fields and custom fields.

It then maps custom field values (identified by their unique IDs) to JavaScript variables and updates the modal's HTML elements with formatted data.

### 4. Custom Fields Used

The script relies on several HighLevel custom fields (IDs hardcoded) to populate the modal. Examples include:

| Field ID | Purpose |
|----------|---------|
| `oXoVNJ0TskE7blWcmpYO` | Company Name |
| `RFjE1LqaGUr1oqcc76ja` | Monthly Ad Spend |
| `pX6Zu6ulMsEpUnQauQzp` | Monthly Retainer |
| `5dNdrPgC7DDEQgqjXWD3` | Next Renewal Date |
| `fkidWlwEnLZmQlrya2Zk` | Client Temperament |
| `9NjdITCKxiKbF0yJmH6g` | Assigned Setter |
| `aZQpt0O9XavF5n6R9K08` | Assigned Rover |
| `s7OoLM0FOYm2AgwNNSGJ` | Latest Customer Ticket |
| `ZIPkqG8y3pgBeqfjgd16` | Campaign Note |
| *(and many more)* | |

### 5. Modal Structure

The modal is divided into several sections:

1. **Header**: Customer name, avatar, and contact icons (phone, email, company, location, tier).
2. **Customer Details**: Cards showing launch date, next renewal, monthly retainer, client temperament.
3. **Lead Gen Details**: Cards for monthly ad spend, campaign source, active status, app integration, plus a notes section.
4. **Setter Details**: Assigned setter, last submission date, assigned rover, last rover submission.
5. **Latest Client Ticket**: A plain-text area showing the most recent support ticket or note.
6. **Client Specifics**: A bullet list of client-specific notes or instructions.
7. **Actions**: Cancel and Update Client buttons (Update functionality not shown in snippet).

### 6. Utility Functions

- `formatPhoneNumber()`: Formats the raw phone string (not shown in snippet but referenced).
- `formatDate()`: Converts a raw date string into a readable format (e.g., "August 27, 2025").
- `close_profile_modal()`: Hides the modal and removes the `.show` class.
- `accordion()`: (Placeholder) Shows an alert on click – likely intended for expanding/collapsing sections but not fully implemented.

## Integration Notes

- The script assumes the existence of global helper functions like `getConversationDetails()`, `getContactDetails()`, `getLocationId()`, and `formatPhoneNumber()`.
- It listens for a custom `routeChangeEvent` to re-run the button injection after page navigation (SPA behavior).
- The modal is injected into `#app` element only once (`setTimeout` check).
- The injection only happens for a specific `locationId` (`ynCWf3Y4AEJ7hfQ4lVWE`), making it tenant-specific.
- The modal uses **FontAwesome** icons (assumed available) and custom SVGs.

## Dependencies

- jQuery (for DOM manipulation and events)
- FontAwesome (for icons like `fa-phone`, `fa-envelope`, etc.)
- HighLevel’s internal API or service functions (`getContactDetails`, `getConversationDetails`)
- A parent element with ID `#app` in the DOM

## Possible Improvements

- Move custom field IDs to a configuration object for easier maintenance.
- Implement the "Update Client" button to save changes back to HighLevel.
- Add loading state while fetching data.
- Trap focus inside modal for accessibility.
- Replace inline styles with external CSS for cleaner code.
- Add error handling for missing custom fields or failed API calls.

## Conclusion

This feature greatly enhances the user experience for CRM users by providing instant access to enriched customer profiles directly within conversation and contact views. It reduces context switching and ensures that all team members have the same, up‑to‑date client information at their fingertips.