npm package: @sworkit/sw-workout-player
Description: Sworkit Workout Player
Latest version: 2.2.3

![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square)

# Sworkit Workout Player

This is the gateway npm package for the Sworkit workout player component for playing a standalone workout for our paid partners program. Please reach out to `buildwithus@sworkit.com` if you'd like to use this component. You will need to be approved first, and get API keys in order for this to work correctly. 

## Using the Sworkit Player component

# Installation

This is the Sworkit workout player component for playing a standalone workout for our paid partners program. Please reach out to `buildwithus@sworkit.com` if you'd like to use this component.

You'll need 2 things before this package will be useful to you. 

1. Get a `USERNAME` and `PUBLIC_API_KEY` from your Sworkit contact. This gives you access to our workouts API.
2. Request npm access for all the engineers who will be building your app. Please give us npm usernames or emails and we will invite you. (Again, reach out to your Sworkit contact, or message `buildwithus@sworkit.com` if you're running into issues.) Once you have access, you will be given an `$NPM_TOKEN` as well.
  
The Sworkit Workout Player is a web component that is built using <a href="https://stenciljs.com/">Stencil JS</a>. This means that it can be used in any framework, or without a framework at all! 

### Vanilla JS & HTML

- Put this script tag in the head of your index.html 
```html
<script type="module" src="https://unpkg.com/@sworkit/sw-workout-player@latest/dist/esm/sw-workout-player.js"></script>
<script nomodule src="https://unpkg.com/@sworkit/sw-workout-player@latest/dist/cjs/sw-workout-player.cjs.js"></script> 

``` 
- Then you can use the element anywhere in your template, JSX, html etc
- Add `<sw-workout-player workout-slug="full-body"></sw-workout-player>` to the page.

### In a Stencil JS app/component
- Run `npm install @sworkit/sw-workout-player --save`
- Add an import to the npm packages `import '@sworkit/sw-workout-player'`
- Then you can use the element anywhere in your template, JSX, html etc


### Angular
Using the Sworkit Workout Player web component collection within an Angular CLI project is a three-step process. We need to:
- Run `npm install @sworkit/sw-workout-player`
- Include the CUSTOM_ELEMENTS_SCHEMA
- Call defineCustomElements(window)
- Add the component to a page in your Angular application

#### Including the Custom Elements Schema
Including the CUSTOM_ELEMENTS_SCHEMA in the module allows the use of the web components in the HTML markup without the compiler producing errors. This code should be added into the AppModule AND in every other module that uses your custom elements.
Here is an example of adding it to AppModule:

```ts
import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, FormsModule],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
```
The CUSTOM_ELEMENTS_SCHEMA needs to be included in any module that uses custom elements.


#### Calling defineCustomElements


The Sworkit Workout player is a web component built with Stencil that includes a main function that is used to load the components in the collection. That function is called `defineCustomElements()` and it needs to be called once during the bootstrapping of your application. One convenient place to do this is in main.ts as such:

```ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import { defineCustomElements } from '@sworkit/sw-workout-player/loader';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
defineCustomElements(window);
```

#### Edge and IE11 polyfills
If you want your custom elements to be able to work on older browsers, you should add the applyPolyfills() that surround the defineCustomElements() function.
```ts
import { applyPolyfills, defineCustomElements } from 'test-components/loader';
...
applyPolyfills().then(() => {
  defineCustomElements(window)
})
```

#### Add the component to a page in your Angular application

```ts
import "@sworkit/sw-workout-player";
import { Component } from "@angular/core";
import { ActivatedRoute } from "@angular/router";

@Component({
  selector: "sworkit-player-page",
  template: `
    <sw-workout-player 
    workoutSlug="{{ workoutSlug }}"
    workoutLength="{{ workoutLength }}"
    uuid="{{ uuid }}"
    showLogWarning={{ showLogWarning }}
    public-key="{PUBLIC_API_KEY}">
  </sw-workout-player>`
})
export class SworkitPlayerPage {
  workoutSlug: string;
  workoutLength: string;

  constructor(private activatedRoute: ActivatedRoute) {
    this.workoutSlug = this.activatedRoute.snapshot.paramMap.get("workoutSlug");
    this.workoutLength = this.activatedRoute.snapshot.paramMap.get("workoutLength");
  }

}
```



## Properties

| Property                   | Attribute          | Description                                                                                                                                                                                     | Type                                                                                                             | Default     |
| -------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------- |
| `collectionSlug`           | `collection-slug`  | Collection slug the workout is playing from. e.g. "strength"                                                                                                                                    | `string`                                                                                                         | `undefined` |
| `language`                 | `language`         | Languange string = "en" \| "de" \| "es" \| "esla" \| "fr" \| "hi" \| "it" \| "ja" \| "ko" \| "pt" \| "ru" \| "tr" \| "zh" https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes                 | `"de" \| "en" \| "es" \| "esla" \| "fr" \| "hi" \| "hu" \| "it" \| "ja" \| "ko" \| "pt" \| "ru" \| "tr" \| "zh"` | `undefined` |
| `publicKey` _(required)_   | `public-key`       | Public Key given from Sworkit (required) The Sworkit player will not load without a public key                                                                                                  | `string`                                                                                                         | `undefined` |
| `showLogWarning`           | `show-log-warning` | Defines if a a user should be warned about a workout log saving if they end the workout session early                                                                                           | `boolean`                                                                                                        | `undefined` |
| `uuid`                     | `uuid`             | Unique user id from your app, if not entered, will use a device id which may result in incorrect numbers                                                                                        | `string`                                                                                                         | `undefined` |
| `workoutLength`            | `workout-length`   | Length of the workout (mins) for standard workouts, Or the number of rounds for yoga workouts Note: If no workoutLength is passed in - the time select screen will pop up automatically on load | `number`                                                                                                         | `undefined` |
| `workoutSlug` _(required)_ | `workout-slug`     | Workout Slug to be played (required) e.g. "full-body"                                                                                                                                           | `string`                                                                                                         | `undefined` |


## Events

| Event            | Description                                                | Type                                                               |
| ---------------- | ---------------------------------------------------------- | ------------------------------------------------------------------ |
| `swWorkoutClose` | Emitted when the X in the top left of the player is tapped | `CustomEvent<any>`                                                 |
| `swWorkoutEnd`   | Emitted when workout is finished                           | `CustomEvent<{ log: WorkoutLog; selectedWorkoutLength: number; }>` |


## Data Structure

```ts
interface WorkoutLog {
    activityKey: string;
    appVersion: string;
    platform: 'web';
    calories: number;
    category: string;
    collectionSlug: string;
    deviceType: string;
    minutesCompleted: number;
    name: string;
    slug: string;
    timestampMillis: number;
    type: string;
    utcCreated: string;
}
```

## Using the Sworkit Data Rest Api
To retrieve the data for your CMS system you’ll need to make an API GET request using 2 headers that will return a JSON object.

```
METHOD:             GET
URL:                https://api2.sworkit.com/v1/customers/data
HEADERS: 	
    Api-Username: USERNAME  {provided separately by Sworkit}
	Api-Key:  PUBLIC_API_KEY      {provided separately by Sworkit}
PARAMS:
  locale: Language string = "en" \| "de" \| "es" \| "esla" \| "fr" \| "hi" \| "it" \| "ja" \| "ko" \| "pt" \| "ru" \| "tr" \| "zh" https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes         
```

Making this call will retrieve a JSON object that has the following format:

```ts
{
   "COLLECTION NAME": {
     "image_url": string,
     "workouts": // Array of Workout Objects
       [
         {
           "name": string,
           "slug": string,
           "image_url": string,
           "exercises": // Array of Exercise Objects
             [
               {
                 "slug": string,
                 "name": string,
                 "image_url": string,
               }
             ]
            // additional metadata on workouts, 
            "category": 'strength' | 'cardio' | 'stretching' | 'yoga' | 'pilates' | 'pt' | 'barre',
            "difficulty": number, // 1,2,3
            "focus_area": 'full' | 'upper' | 'lower' | 'pilates' | 'core' | 'back'
            "equipment_types": array,// possible values are 'bodyweight', 'dumbbell', 'kettlebell', 'band', 'loop', 'foamroller',
            "fitness_goal": array,// possible values are 'GOAL_BUILD', 'GOAL_ENDURANCE', 'GOAL_FLEXIBILITY', 'GOAL_LOSE', 'GOAL_INJURY'
            "age_group": 'adult'|'kids'
         }
       ]
   }

   NOTE: may use WorkoutObject Typescript type for workouts. Keys are slightly different

    `fitness_goal` = `goals`
    `focus_area` = `subCategory`
    `age_group` = `classification` => (`standard` instead of `adult`)
    `equipment_types` = `equipmentTypes`
    `image_url` is not represented

```

Here's an example of how to call this from the console:
```
const res = await fetch('https://api2.sworkit.com/v1/customers/data?locale=en', {method: 'GET', headers: {'Content-Type': 'application/json','Api-Username': '<<USERNAME>>', 'Api-Key': '<<PUBLIC_API_KEY>>'}});
await res.json();
```