# Personalized Plan View

AI-Generated Personalized Workout Plans.

- **Personalized**: Tailored to height, weight, age, gender, activity level, and fitness assessment results
- **Goal-Oriented**: Supports strength, flexibility, and wellness goals
- **Seamless Experience**: From recommendations to real-time feedback
- **Customizable**: Brand-aligned app design
- **Quick Integration**: Easy setup for advanced fitness solutions

**Personalized Plan Integration**

_Swift (iOS)_
```swift
kinestex.createPersonalizedPlanView(
    user: nil, // OPTIONAL: provide user details
    isLoading: $isLoading,
    customParams: ["style": "dark"], // dark or light theme (customizable in admin portal)
    onMessageReceived: { message in
        switch message {
        case .exit_kinestex(_):
            showKinesteX = false // dismiss the view
        default:
            print("Received \(message)")
            break
        }
    }
)
```

_Kotlin (Android)_
```kotlin
KinesteXSDK.createPersonalizedPlanView(
    context = this,
    user = userDetails, // optional user details
    customParams = mutableMapOf("style" to "dark"), // customizable in admin portal
    isLoading = viewModel.isLoading,
    onMessageReceived = { message ->
        when (message) {
            is WebViewMessage.ExitKinestex -> finish()
            else -> println("Received: $message")
        }
    },
    permissionHandler = this
)
```

_React Native_
```jsx
// postData structure
const postData: IPostData = {
  key: 'YOUR_API_KEY',
  userId: 'YOUR_USER_ID',
  company: 'YOUR_COMPANY_NAME',
  style: {
    style: 'dark',
  },
};

<KinestexSDK
  data={postData}
  integrationOption={IntegrationOption.PERSONALIZED_PLAN}
  handleMessage={handleMessage}
/>
```

_Flutter_
```dart
KinesteXAIFramework.createPersonalizedPlanView(
  isShowKinestex: showKinesteX,
  customParams: {"style": "dark"},
  isLoading: ValueNotifier<bool>(false),
  onMessageReceived: (message) {
    handleWebViewMessage(message);
  },
)
```

_HTML / JavaScript_
```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>KinesteX: Personalized Plan</title>
  </head>
  <body>
    <button id="startKinesteX">Start Personalized Plan</button>
    <div id="webViewContainer" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: none;">
      <iframe id="webView" frameborder="0" allow="camera; autoplay; accelerometer; gyroscope; magnetometer" sandbox="allow-same-origin allow-scripts" style="width: 100%; height: 100%"></iframe>
    </div>
    <script>
      // Get references to iframe and container at the top
      const webView = document.getElementById("webView");
      const webViewContainer = document.getElementById("webViewContainer");

      // Configuration data - replace with your actual credentials
      const postData = {
        userId: "YOUR_USER_ID",    // Unique identifier for the user
        company: "YOUR_COMPANY",   // Your company name from KinesteX
        key: "YOUR_API_KEY",       // Your API key from KinesteX
        style: "dark",             // Theme: "dark" or "light"
      };

      // IMPORTANT: This is the URL for the Personalized Plan integration
      // The personalized-plan endpoint handles user surveys, assessments, and AI-generated workout plans
      const srcURL = "https://ai.kinestex.com/personalized-plan";

      // Send configuration data to the iframe via postMessage
      // Includes retry logic for Apple Safari compatibility
      function sendMessage() {
        if (webView.contentWindow) {
          webView.contentWindow.postMessage(postData, srcURL);
        } else {
          setTimeout(() => {
            try {
              webView.contentWindow.postMessage(postData, srcURL);
            } catch {
              webView.contentWindow.postMessage(postData, srcURL);
            }
          }, 100);
        }
      }

      // Launch the KinesteX experience when button is clicked
      document.getElementById("startKinesteX").addEventListener("click", function () {
        webViewContainer.style.display = "block";
        // Set the iframe source to load the KinesteX personalized plan
        webView.src = srcURL;
        // Send configuration data once the iframe loads
        webView.onload = sendMessage;
      });

      // Listen for messages from the KinesteX iframe
      window.addEventListener("message", function (event) {
        // SECURITY: Always validate the origin of incoming messages
        if (event.origin !== "https://ai.kinestex.com") return;

        // Parse the message data from the iframe
        const message = JSON.parse(event.data);

        switch (message.type) {
          case "kinestex_launched":
            console.log("KinesteX is launched");
            break;
          case "kinestex_loaded":
            sendMessage();
            break;
          case "exit_kinestex":
            // User requested to exit - hide the iframe container
            webViewContainer.style.display = "none";
            console.log("User exited the KinesteX view");
            break;
          // Handle other message types as needed...
        }
      });
    </script>
  </body>
</html>
```

_React (TypeScript)_
```tsx
import { IntegrationOption, KinesteXSDK, type IPostData } from 'kinestex-sdk-react-ts';

// postData structure
const postData: IPostData = {
  key: 'YOUR_API_KEY',
  userId: 'YOUR_USER_ID',
  company: 'YOUR_COMPANY_NAME',
  style: {
    style: 'dark',
  },
};

<KinesteXSDK
  data={postData}
  integrationOption={IntegrationOption.PERSONALIZED_PLAN}
  handleMessage={handleMessage}
/>
```

---
Source: https://www.kinestex.com/docs/integration/personalized-plan-view · Index: https://www.kinestex.com/llms.txt
