Repository: PostHog/posthog
Pull request: Explain premium feature in upgrade modal
## Changes

An enhancement of the upgrade modal. Resolves #3148.

<img width="538" alt="Screen Shot 2021-03-10 at 15 57 23" src="https://user-images.githubusercontent.com/4550621/110653709-cb077e00-81bd-11eb-87a0-c97fb2efa427.png">
<img width="541" alt="Screen Shot 2021-03-10 at 15 57 16" src="https://user-images.githubusercontent.com/4550621/110653699-c93dba80-81bd-11eb-8a19-b81afbd156bb.png">



Problem statement:
Explain benefits of the paid feature in the upgrade modal
## Is your feature request related to a problem?

Currently the upgrade modal says what the feature is, but it doesn't explain how beneficial it is (e.g. that multiple projects allow you to track multiple product within one organization).

## Describe the solution you'd like

Make it possible to display benefits in some way in the upgrade modal.

## Additional context

Talked with a user who was confused by the upgrade modal due to this.

#### *Thank you* for your feature request – we love each and every one!

Hints from issue discussion:
For what is worth, I think this will be less important with usage-based pricing as the incentive to upgrade will be a lot more straightforward. You upgrade to get more than the 10k event limit (you only have to pay for what you use), and you get a bunch of premium features (which will be more than just multiple projects). 

To be clear, I think this is definitely worth doing, just adding some context that it may not be as urgent.

Commit message: Fix typing

Patch to review:
diff --git a/frontend/src/layout/navigation/TopNavigation.tsx b/frontend/src/layout/navigation/TopNavigation.tsx
index f9f017ca79fff..38eed64d0deb4 100644
--- a/frontend/src/layout/navigation/TopNavigation.tsx
+++ b/frontend/src/layout/navigation/TopNavigation.tsx
@@ -166,6 +166,7 @@ export function _TopNavigation(): JSX.Element {
                             showUpgradeModal,
                             'organizations_projects',
                             'multiple organizations',
+                            'Organizations gather people building products together and are made up of projects.',
                             () => {
                                 setOrganizationModalShown(true)
                             },
@@ -223,6 +224,7 @@ export function _TopNavigation(): JSX.Element {
                             showUpgradeModal,
                             'organizations_projects',
                             'multiple projects',
+                            'Projects allow you to separate data and configuration for multiple products or deployments.',
                             () => {
                                 setProjectModalShown(true)
                             }
diff --git a/frontend/src/scenes/UpgradeModal.tsx b/frontend/src/scenes/UpgradeModal.tsx
index e7ed66f76c55a..b9200a5a4c9fb 100644
--- a/frontend/src/scenes/UpgradeModal.tsx
+++ b/frontend/src/scenes/UpgradeModal.tsx
@@ -6,7 +6,7 @@ import { UserType } from '~/types'
 import { sceneLogic } from './sceneLogic'
 
 export function UpgradeModal(): JSX.Element {
-    const { upgradeModalFeatureName } = useValues(sceneLogic)
+    const { upgradeModalFeatureNameBenefit } = useValues(sceneLogic)
     const { hideUpgradeModal, takeToPricing } = useActions(sceneLogic)
 
     return (
@@ -16,19 +16,24 @@ export function UpgradeModal(): JSX.Element {
             cancelText="Maybe Later"
             onOk={takeToPricing}
             onCancel={hideUpgradeModal}
-            visible={!!upgradeModalFeatureName}
+            visible={!!upgradeModalFeatureNameBenefit}
         >
-            <b>{upgradeModalFeatureName && capitalizeFirstLetter(upgradeModalFeatureName)}</b> is an advanced PostHog
-            feature. Upgrade now and get access to this, as well as to other powerful enhancements.
+            <p>
+                <b>{upgradeModalFeatureNameBenefit && capitalizeFirstLetter(upgradeModalFeatureNameBenefit[0])}</b> is
+                an advanced PostHog feature.
+            </p>
+            <p>{upgradeModalFeatureNameBenefit && upgradeModalFeatureNameBenefit[1]}</p>
+            <p>Upgrade now and get access to this, as well as to other powerful enhancements.</p>
         </Modal>
     )
 }
 
 export function guardPremiumFeature(
     user: UserType | null,
-    showUpgradeModal: (featureName: string) => void,
+    showUpgradeModal: (featureName: string, featurBenefit: string) => void,
     key: string,
     name: string,
+    benefit: string,
     featureAvailableCallback?: () => void,
     guardOn: {
         cloud: boolean
@@ -52,7 +57,7 @@ export function guardPremiumFeature(
     if (featureAvailable) {
         featureAvailableCallback?.()
     } else {
-        showUpgradeModal(name)
+        showUpgradeModal(name, benefit)
     }
 
     return !featureAvailable
diff --git a/frontend/src/scenes/sceneLogic.ts b/frontend/src/scenes/sceneLogic.ts
index c7404544b6859..e803ffe63fc83 100644
--- a/frontend/src/scenes/sceneLogic.ts
+++ b/frontend/src/scenes/sceneLogic.ts
@@ -175,7 +175,9 @@ export const sceneLogic = kea<sceneLogicType>({
         loadScene: (scene: Scene, params: Params) => ({ scene, params }),
         setScene: (scene: Scene, params: Params) => ({ scene, params }),
         setLoadedScene: (scene: Scene, loadedScene: LoadedScene) => ({ scene, loadedScene }),
-        showUpgradeModal: (featureName: string) => ({ featureName }),
+        showUpgradeModal: (featureName: string, featureBenefit: string) => ({
+            featureNameBenefit: [featureName, featureBenefit] as [string, string],
+        }),
         hideUpgradeModal: true,
         takeToPricing: true,
     },
@@ -212,10 +214,10 @@ export const sceneLogic = kea<sceneLogicType>({
                 setScene: () => null,
             },
         ],
-        upgradeModalFeatureName: [
-            null as string | null,
+        upgradeModalFeatureNameBenefit: [
+            null as [string, string] | null,
             {
-                showUpgradeModal: (_, { featureName }) => featureName,
+                showUpgradeModal: (_, { featureNameBenefit }) => featureNameBenefit as [string, string],
                 hideUpgradeModal: () => null,
                 takeToPricing: () => null,
             },
@@ -249,8 +251,8 @@ export const sceneLogic = kea<sceneLogicType>({
         return mapping
     },
     listeners: ({ values, actions }) => ({
-        showUpgradeModal: ({ featureName }) => {
-            posthog.capture('upgrade modal shown', { featureName })
+        showUpgradeModal: ({ featureNameBenefit }) => {
+            posthog.capture('upgrade modal shown', { featureNameBenefit })
         },
         hideUpgradeModal: () => {
             posthog.capture('upgrade modal cancellation')


Code review comments:
diff_hunk: @@ -249,8 +251,8 @@ export const sceneLogic = kea<sceneLogicType>({
         return mapping
     },
     listeners: ({ values, actions }) => ({
-        showUpgradeModal: ({ featureName }) => {
-            posthog.capture('upgrade modal shown', { featureName })
+        showUpgradeModal: ({ featureNameBenefit }) => {
+            posthog.capture('upgrade modal shown', { featureNameBenefit })
path: frontend/src/scenes/sceneLogic.ts
text: @user1:
Even though this event reporting is quite simple, I would still move it to eventUsageLogic so we keep all that information centralized. I would definitely send the featureName too, actually might be more useful than the benefit, and it ensure backwards-compatibility too.

diff_hunk: @@ -175,7 +175,9 @@ export const sceneLogic = kea<sceneLogicType>({
         loadScene: (scene: Scene, params: Params) => ({ scene, params }),
         setScene: (scene: Scene, params: Params) => ({ scene, params }),
         setLoadedScene: (scene: Scene, loadedScene: LoadedScene) => ({ scene, loadedScene }),
-        showUpgradeModal: (featureName: string) => ({ featureName }),
+        showUpgradeModal: (featureName: string, featureBenefit: string) => ({
+            featureNameBenefit: [featureName, featureBenefit] as [string, string],
path: frontend/src/scenes/sceneLogic.ts
text: @user1:
`featureNameBenefit` is confusing, you're sending both the name and benefit in here, I would change this to something more clear.

diff_hunk: @@ -16,19 +16,24 @@ export function UpgradeModal(): JSX.Element {
             cancelText="Maybe Later"
             onOk={takeToPricing}
             onCancel={hideUpgradeModal}
-            visible={!!upgradeModalFeatureName}
+            visible={!!upgradeModalFeatureNameBenefit}
         >
-            <b>{upgradeModalFeatureName && capitalizeFirstLetter(upgradeModalFeatureName)}</b> is an advanced PostHog
-            feature. Upgrade now and get access to this, as well as to other powerful enhancements.
+            <p>
+                <b>{upgradeModalFeatureNameBenefit && capitalizeFirstLetter(upgradeModalFeatureNameBenefit[0])}</b> is
+                an advanced PostHog feature.
+            </p>
+            <p>{upgradeModalFeatureNameBenefit && upgradeModalFeatureNameBenefit[1]}</p>
+            <p>Upgrade now and get access to this, as well as to other powerful enhancements.</p>
         </Modal>
     )
 }
 
 export function guardPremiumFeature(
     user: UserType | null,
-    showUpgradeModal: (featureName: string) => void,
+    showUpgradeModal: (featureName: string, featurBenefit: string) => void,
     key: string,
     name: string,
+    benefit: string,
path: frontend/src/scenes/UpgradeModal.tsx
text: @user1:
Nit: I would call this something like `caption`, as `benefit` seems to narrow the scope of what we can do with this.