@preply/marketing-personas-wizard

This package contains components for Marketing Personas Wizard.

Usage no npm install needed!

<script type="module">
  import preplyMarketingPersonasWizard from 'https://cdn.skypack.dev/@preply/marketing-personas-wizard';
</script>

README

Overview

This package contains components for Marketing Personas Wizard.

Build & run

Docker mode

Build

docker-compose run --rm main yarn build

:warning: This doesn't work from docker so far. Propbably need to try storybook-docker or smth

Start storybook

docker-compose up

Dev mode

Install dependencies

yarn

Start storybook

yarn storybook

To test as different user types, you have to perform an auth on STORYBOOK_API_HOST (default - stage40.preply.org)

To test with monolith:

  1. Build

    yarn dev
    
  2. Install or link the local version of @preply/marketing-personas-wizard in the monolith:

    • Locall installation - use npm pack
    • Linking - use yarn link/npm link; altho mixing of npm and yarn may work unstable, so the recommended way for convenience is to use yalc

Go to http://localhost:9001

Monitoring / Alerting

Errors from this service are reported to Sentry under client-pkgs project.

To filter errors that are only related to this service use source tag.

Staging

By commenting dynamic on a PR that changes this package, a beta version of the module will be created and installed on staging environment.

To verify the package version on node-ssr - go to https://stage40.preply.org/.ssr-release (replace your stage number on link) and on the rest of FE apps type window.__PREPLY_DEPS in console.

Release

Follow this readme

Usage

yarn add @preply/marketing-personas-wizard -E

Examples

Every Wizard instance needs to be wrapped by <WizardConfig>, which provides the main context to the component.

Each step can be added to the Wizard as a child component, in the order that they will be shown.

Search Wizard

Stories for Search Wizard

// Search Wizard
import { Header, ModalWizard, WizardConfig } from `@preply/marketing-personas-wizard`
<WizardConfig
    id="tutors_search_wizard"
    language={language}
    subject={subject}
    currentUserId={currentUserId}
    source={StudentGoalSourceEnum.Search}
>
    <ModalWizard {...{ isOpen, onRequestClose, onComplete }}>
        <CurrentLevel />
        <Budget
            currency={currency}
            priceFilterLimits={PRICE_FILTER_LIMITS}
            priceFilterSteps={PRICE_FILTER_STEP}
        />
        <StudentAvailability />
        <NativeSpeakerTutor />
    </ModalWizard>
</WizardConfig>

Persona Wizard

// Persona Wizard
import { Header, ModalWizard, WizardConfig } from `@preply/marketing-personas-wizard`
<WizardConfig id="persona_wizard" language={language} subject={subject} source={source}>
    <ModalWizard
        {...{ isOpen, onRequestClose, onComplete, OnCompleteScreen: <ThankYou /> }}
    >
        <StudentGoals />
        <StudentGoalReason />
    </ModalWizard>
</WizardConfig>

Props

WizardConfig

id: string - unique id of the Wizard instance
language: string - current page language
subject: WizardSubject | null - subject associated to the student intent
currentUserId: number (optional) - current user id
source: StudentGoalSourceEnum (optional) - source according to whom is using the Wizard

ModalWizard

The ModalWizard component extends Wizard, wrapping the content into a pop-up.

isOpen: boolean - flag to control whether modal Wizard is open or not
onComplete: (clientIntent: Maybe) => void - callback for when user completes the Wizard. Parameter clientIntent contains the user's answers.
onRequestClose: (clientIntent?: Maybe) => void - callback for when user requests to close the modal. Parameter clientIntent is optional.
OnCompleteScreen: JSX.Element (optional) - component to be shown once Wizard is completed.
preventClosing: boolean (optional) - if true prevents any manner of closing the modal, such as hitting the ESC key or clicking outside of the modal, also hides the cross x button that closes the modal.

WizardSubject

Prop Types
    {
      "id": number,                # subject id
      "alias": "string",            # subject alias
      "translatedAlias": "string",  # subject translated alias
      "translatedName": "string",   # subject translated name
      "languageCode": "string",     # subject language code
    }
Example
{
    "id": 1,
    "alias": "english",
    "translatedAlias": "angliyskogo",
    "translatedName": "Английский язык",
    "languageCode": "en"
}

StepConfigValues

Props
```javascript
    interface StepConfigValues {
        clientIntent?: Maybe<ClientIntentNode>;
        clientIntentData?: Maybe<ClientIntentNode>;
        clientIntentId?: number;
        currentStepIndex?: number;
        totalStepsCount?: number;
        studentGoal?: Maybe<StudentGoal>;
        allowSkip?: boolean;
        isEditMode?: boolean;
        autoSubmit?: boolean;
        hideNavigation?: boolean;
        required?: boolean;
        hideIfPropertyExists?: string;
        wizardLayout?: WizardLayout;
        preventClosing?: boolean;
        onNext?(clientIntent?: ClientIntentNode): void;
        onPrevious?(clientIntent?: ClientIntentNode): void;
        onCancelEdit?(clientIntent?: ClientIntentNode): void;
        onConfirmEdit?(clientIntent?: ClientIntentNode): void;
        onRequestClose?(stepId: string, timeOnStep: number): void;
        onRequestSkip?(stepId: string, timeOnStep: number): void;
    }
```

Steps

PersonalisedCurrentLevel
    {
        "stepName": "CurrentLevel",
        "showNeedHelpButton": boolean,
        "onNeedHelpClick": (e: React.MouseEvent) => {},
        ...StepConfigValues
    }

Example

<PersonalisedCurrentLevel
    hideIfPropertyExists="currentLevel"
    stepName="CurrentLevel"
    showNeedHelpButton
    onNeedHelpClick={(e: React.MouseEvent) => {
        // Callback action body
    }}
/>

Styles

This package uses LESS to create stylesheets, in order to allow compatibility with server-side rendering.

i18n

  1. Navigate to TransMaster
  2. Execute Rebuild Last
  3. Navigate to Preply space in Crowdin and filter by the ticket number, e.g. CRMP-123

TODO

  • Do not use global API_HOST
  • Full-screen Wizard - this code was implemented to support both modal and full-screen formats of the Wizard, but since we are currently only using the modal version, full-screen layout has not been implemented yet.