Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions custom-products-catalog/template/package.json.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ to: package.json
"name": "<%= packageName %>",
"version": "1.0.0",
"dependencies": {
"@wix/app-management": "^1.0.44",
"@wix/dashboard-react": "^1.0.4",
"@wix/design-system": "^1.111.0",
"@wix/essentials": "^0.1.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { FloatingHelper } from '@wix/design-system'
import { useFreeTrialAvailable, useIsFree, useNavigateToPricingPage } from '../hooks/instance';

interface PremiumFeatureProps {
children: React.ReactNode;
}

export function PremiumFeature({ children }: PremiumFeatureProps) {
const isFree = useIsFree();
const isFreeTrialAvailable = useFreeTrialAvailable();
const navigateToPricingPage = useNavigateToPricingPage();

if (isFree && isFreeTrialAvailable) {
return (
<FloatingHelper
placement="bottom-end"
appearance="light"
initiallyOpened={false}
target={children}
content={
<FloatingHelper.Content
title="Start your free trial"
body="You need a premium subscription to access this feature. Start your free trial now."
actionText="Start Free Trial"
actionTheme="premium"
onActionClick={navigateToPricingPage}
/>
}
/>
);
}

return <>{children}</>;
}
55 changes: 55 additions & 0 deletions custom-products-catalog/template/src/dashboard/hooks/instance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { createContext, useContext, useCallback, useEffect, useState } from 'react';
import { appInstances } from '@wix/app-management';

/*
This is the URL to the pricing page of the app.
This url looks like this:
https://www.wix.com/apps/upgrade/APPIDHERE?appInstanceId=INSTANCEIDHERE

You can find more information about this here:
https://dev.wix.com/docs/build-apps/launch-your-app/pricing-and-billing/set-up-a-freemium-business-model#step-4--create-an-upgrade-entry-point-to-your-pricing-page
*/
const getPricingPage = (instanceId: string) => `https://www.wix.com/apps/upgrade/<%= devCenter.appId %>?appInstanceId=${instanceId}`

const AppInstanceContext = createContext<appInstances.AppInstance | undefined>(undefined);

export function AppInstanceProvider({ children }: { children: React.ReactNode }) {
const [appInstance, setAppInstance] = useState<appInstances.AppInstance>();

useEffect(() => {
if (!appInstance) {
appInstances.getAppInstance()
.then((appInstance) => setAppInstance(appInstance.instance))
}
}, [appInstance, setAppInstance]);

return (
<AppInstanceContext.Provider value={appInstance}>
{children}
</AppInstanceContext.Provider>
)
}

export function useAppInstance(): appInstances.AppInstance | undefined {
return useContext(AppInstanceContext);
}

export function useIsFree(): boolean {
const appInstance = useAppInstance();
return appInstance?.isFree ?? true;
}

export function useFreeTrialAvailable(): boolean {
const appInstance = useAppInstance();
return appInstance?.freeTrialAvailable ?? false;
}

export function useNavigateToPricingPage(): () => void {
const appInstance = useAppInstance();

return useCallback(() => {
if (appInstance?.instanceId) {
window.open(getPricingPage(appInstance?.instanceId), '_blank');
}
}, [appInstance?.instanceId]);
}
14 changes: 10 additions & 4 deletions custom-products-catalog/template/src/dashboard/pages/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import '@wix/design-system/styles.global.css';
import { products } from '@wix/stores';
import { withProviders } from '../withProviders';
import { useCreateProduct, useDeleteProducts } from '../hooks/stores';
import { useIsFree } from '../hooks/instance';
import { CreateProductModal } from '../components/create-product';
import { PremiumFeature } from '../components/premium-feature';
import { CollectionPage } from '@wix/patterns/page';
import {
useTableCollection,
Expand Down Expand Up @@ -46,6 +48,7 @@ const productTypeToDisplayName: { [key in products.ProductType]: string | undefi

function Products() {
const [shown, setShown] = useState(false);
const isFree = useIsFree();

const tableState = useTableCollection<products.Product, TableFilters>({
queryName: 'products-catalog',
Expand Down Expand Up @@ -160,10 +163,13 @@ function Products() {
/>
}
primaryAction={
<PrimaryPageButton
text="Add Product"
onClick={() => setShown(!shown)}
/>
<PremiumFeature>
<PrimaryPageButton
disabled={isFree}
text="Add Product"
onClick={() => setShown(!shown)}
/>
</PremiumFeature>
}
/>
<CollectionPage.Content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { WixDesignSystemProvider } from '@wix/design-system';
import { withDashboard } from '@wix/dashboard-react';
import { WixPatternsProvider } from '@wix/patterns/provider';
import { i18n } from '@wix/essentials';
import { AppInstanceProvider } from './hooks/instance';

export function withProviders<P extends {} = {}>(Component: React.FC<P>) {
return withDashboard(function DashboardProviders(props: P) {
const locale = i18n.getLocale();
return (
<WixDesignSystemProvider locale={locale} features={{ newColorsBranding: true }}>
<WixPatternsProvider>
<Component {...props} />
<AppInstanceProvider>
<Component {...props} />
</AppInstanceProvider>
</WixPatternsProvider>
</WixDesignSystemProvider>
);
Expand Down
1 change: 1 addition & 0 deletions mixpanel-analytics/template/package.json.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ to: package.json
"version": "1.0.0",
"dependencies": {
"@tanstack/react-query": "^4.36.1",
"@wix/app-management": "^1.0.44",
"@wix/app-management": "^1.0.0",
"@wix/design-system": "^1.111.0",
"@wix/essentials": "^0.1.4",
Expand Down
42 changes: 42 additions & 0 deletions mixpanel-analytics/template/src/dashboard/components/Paywall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { Modal, AnnouncementModalLayout, Text, AnnouncementModalLayoutProps } from '@wix/design-system';
import { useFreeTrialAvailable, useIsFree, useNavigateToPricingPage } from '../hooks/instance';

export default function Paywall() {
const isFree = useIsFree();
const isFreeTrialAvailable = useFreeTrialAvailable();
const navigateToPricingPage = useNavigateToPricingPage();

const freeTrialModal: AnnouncementModalLayoutProps = {
title: 'Start your free trial',
primaryButtonText: 'Start Free Trial',
primaryButtonOnClick: navigateToPricingPage,
linkText: 'See all plans',
linkOnClick: navigateToPricingPage,
onCloseButtonClick: navigateToPricingPage,
};

const planRequiredModal: AnnouncementModalLayoutProps = {
title: 'You need a premium subscription',
primaryButtonText: 'Select your plan',
primaryButtonOnClick: navigateToPricingPage,
onCloseButtonClick: navigateToPricingPage,
};

if (isFree) {
return (
<Modal isOpen>
<AnnouncementModalLayout
theme="premium"
{...isFreeTrialAvailable ? freeTrialModal : planRequiredModal}
>
<Text>
You need a premium subscription to access this page.
</Text>
</AnnouncementModalLayout>
</Modal>
);
}

return null;
}
55 changes: 55 additions & 0 deletions mixpanel-analytics/template/src/dashboard/hooks/instance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { createContext, useContext, useCallback, useEffect, useState } from 'react';
import { appInstances } from '@wix/app-management';

/*
This is the URL to the pricing page of the app.
This url looks like this:
https://www.wix.com/apps/upgrade/APPIDHERE?appInstanceId=INSTANCEIDHERE

You can find more information about this here:
https://dev.wix.com/docs/build-apps/launch-your-app/pricing-and-billing/set-up-a-freemium-business-model#step-4--create-an-upgrade-entry-point-to-your-pricing-page
*/
const getPricingPage = (instanceId: string) => `https://www.wix.com/apps/upgrade/<%= devCenter.appId %>?appInstanceId=${instanceId}`

const AppInstanceContext = createContext<appInstances.AppInstance | undefined>(undefined);

export function AppInstanceProvider({ children }: { children: React.ReactNode }) {
const [appInstance, setAppInstance] = useState<appInstances.AppInstance>();

useEffect(() => {
if (!appInstance) {
appInstances.getAppInstance()
.then((appInstance) => setAppInstance(appInstance.instance))
}
}, [appInstance, setAppInstance]);

return (
<AppInstanceContext.Provider value={appInstance}>
{children}
</AppInstanceContext.Provider>
)
}

export function useAppInstance(): appInstances.AppInstance | undefined {
return useContext(AppInstanceContext);
}

export function useIsFree(): boolean {
const appInstance = useAppInstance();
return appInstance?.isFree ?? true;
}

export function useFreeTrialAvailable(): boolean {
const appInstance = useAppInstance();
return appInstance?.freeTrialAvailable ?? false;
}

export function useNavigateToPricingPage(): () => void {
const appInstance = useAppInstance();

return useCallback(() => {
if (appInstance?.instanceId) {
window.open(getPricingPage(appInstance?.instanceId), '_blank');
}
}, [appInstance?.instanceId]);
}
2 changes: 2 additions & 0 deletions mixpanel-analytics/template/src/dashboard/pages/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Page, Card, Box, Text, TextButton } from '@wix/design-system';
import '@wix/design-system/styles.global.css';
import { withProviders } from '../withProviders';
import ProjectToken from '../components/ProjectToken.js';
import Paywall from '../components/Paywall.js';

function MixpanelAnalytics() {
return (
Expand Down Expand Up @@ -31,6 +32,7 @@ function MixpanelAnalytics() {
</Box>
</Card.Content>
</Card>
<Paywall />
</Page.Content>
</Page>
);
Expand Down
5 changes: 4 additions & 1 deletion mixpanel-analytics/template/src/dashboard/withProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { WixDesignSystemProvider } from '@wix/design-system';
import { i18n } from '@wix/essentials';
import { AppInstanceProvider } from './hooks/instance';

const queryClient = new QueryClient();

Expand All @@ -11,7 +12,9 @@ export function withProviders<P extends {} = {}>(Component: React.FC<P>) {
return (
<WixDesignSystemProvider locale={locale} features={{ newColorsBranding: true }}>
<QueryClientProvider client={queryClient}>
<Component {...props} />
<AppInstanceProvider>
<Component {...props} />
</AppInstanceProvider>
</QueryClientProvider>
</WixDesignSystemProvider>
);
Expand Down