mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-25 07:51:12 +02:00
fix upgrade ux on extension
This commit is contained in:
@@ -15,7 +15,7 @@ const checkoutIds = {
|
|||||||
annual: 'aae95d78-05c8-46f5-b11e-2d40ddd211d3',
|
annual: 'aae95d78-05c8-46f5-b11e-2d40ddd211d3',
|
||||||
generic: 'd1d2da1a-ae8f-4222-bbaf-6e07da8954bf' //'f8c64e50-7734-438b-a122-3510156f14ed'
|
generic: 'd1d2da1a-ae8f-4222-bbaf-6e07da8954bf' //'f8c64e50-7734-438b-a122-3510156f14ed'
|
||||||
};
|
};
|
||||||
export function Pro({ user, onLoginClick }) {
|
export function Pro({ user, onLoginClick, onBuyFromExtensionClick }) {
|
||||||
const hasCheckoutLoaded = useCheckout();
|
const hasCheckoutLoaded = useCheckout();
|
||||||
const [isAnnual, setIsAnnual] = useState(true);
|
const [isAnnual, setIsAnnual] = useState(true);
|
||||||
|
|
||||||
@@ -38,6 +38,42 @@ export function Pro({ user, onLoginClick }) {
|
|||||||
window.LemonSqueezy.Refresh();
|
window.LemonSqueezy.Refresh();
|
||||||
}
|
}
|
||||||
}, [hasCheckoutLoaded]);
|
}, [hasCheckoutLoaded]);
|
||||||
|
|
||||||
|
let upgradeActionEl;
|
||||||
|
if (window.IS_EXTENSION) {
|
||||||
|
upgradeActionEl = (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn--pro jc-c"
|
||||||
|
onClick={onBuyFromExtensionClick}
|
||||||
|
>
|
||||||
|
Upgrade to PRO
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
} else if (window.user) {
|
||||||
|
upgradeActionEl = (
|
||||||
|
<A
|
||||||
|
class="btn btn--pro lemonsqueezy-button d-f jc-c ai-c"
|
||||||
|
style="gap:0.2rem"
|
||||||
|
href={`https://web-maker.lemonsqueezy.com/checkout/buy/${checkoutIds.generic}?embed=1&checkout[custom][userId]=${user?.uid}`}
|
||||||
|
onClick={() => {
|
||||||
|
trackEvent('ui', 'buyBtnClick');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Go PRO
|
||||||
|
</A>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
upgradeActionEl = (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn--pro jc-c"
|
||||||
|
onClick={onLoginClick}
|
||||||
|
>
|
||||||
|
Login & upgrade to PRO
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<VStack gap={2} align="stretch">
|
<VStack gap={2} align="stretch">
|
||||||
{/* <Stack justify="center">
|
{/* <Stack justify="center">
|
||||||
@@ -66,28 +102,7 @@ export function Pro({ user, onLoginClick }) {
|
|||||||
price={'Starting $6/mo'}
|
price={'Starting $6/mo'}
|
||||||
subTitle="Annual & One-time pricing available"
|
subTitle="Annual & One-time pricing available"
|
||||||
name="Pro"
|
name="Pro"
|
||||||
action={
|
action={upgradeActionEl}
|
||||||
window.user ? (
|
|
||||||
<A
|
|
||||||
class="btn btn--pro lemonsqueezy-button d-f jc-c ai-c"
|
|
||||||
style="gap:0.2rem"
|
|
||||||
href={`https://web-maker.lemonsqueezy.com/checkout/buy/${checkoutIds.generic}?embed=1&checkout[custom][userId]=${user?.uid}`}
|
|
||||||
onClick={() => {
|
|
||||||
trackEvent('ui', 'buyBtnClick');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Go PRO
|
|
||||||
</A>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn--pro jc-c"
|
|
||||||
onClick={onLoginClick}
|
|
||||||
>
|
|
||||||
Login & upgrade to PRO
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
features={[
|
features={[
|
||||||
'Unlimited private creations',
|
'Unlimited private creations',
|
||||||
'Unlimited public creations',
|
'Unlimited public creations',
|
||||||
|
27
src/components/ProOnAppModal.js
Normal file
27
src/components/ProOnAppModal.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import Modal from './Modal';
|
||||||
|
import { Text } from './Text';
|
||||||
|
import { Stack } from './Stack';
|
||||||
|
|
||||||
|
export function ProOnAppModal({ show, closeHandler }) {
|
||||||
|
return (
|
||||||
|
<Modal extraClasses="" show={show} closeHandler={closeHandler}>
|
||||||
|
<div class="ta">
|
||||||
|
<Text appearance="primary" tag="h1" size="4" weight="700">
|
||||||
|
Upgrade on Web app
|
||||||
|
</Text>
|
||||||
|
<p className="para">
|
||||||
|
Upgrading to PRO from the extension is not available yet. You can
|
||||||
|
instead upgrade on the Web app, come back here, refresh and get all
|
||||||
|
the PRO features right here!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Stack justify="center">
|
||||||
|
<a href="https://webmaker.app/create" className="btn btn--pro">
|
||||||
|
Upgrade on Web app
|
||||||
|
</a>
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@@ -77,6 +77,7 @@ import { Pro } from './Pro.jsx';
|
|||||||
import { VStack } from './Stack.jsx';
|
import { VStack } from './Stack.jsx';
|
||||||
import { ProBadge } from './ProBadge.jsx';
|
import { ProBadge } from './ProBadge.jsx';
|
||||||
import { Text } from './Text.jsx';
|
import { Text } from './Text.jsx';
|
||||||
|
import { ProOnAppModal } from './ProOnAppModal.js';
|
||||||
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
@@ -129,7 +130,8 @@ export default class App extends Component {
|
|||||||
isAssetsOpen: false,
|
isAssetsOpen: false,
|
||||||
isShareModalOpen: false,
|
isShareModalOpen: false,
|
||||||
isProModalOpen: false,
|
isProModalOpen: false,
|
||||||
isFilesLimitModalOpen: false
|
isFilesLimitModalOpen: false,
|
||||||
|
isProOnAppModalOpen: false
|
||||||
};
|
};
|
||||||
this.state = {
|
this.state = {
|
||||||
isSavedItemPaneOpen: false,
|
isSavedItemPaneOpen: false,
|
||||||
@@ -227,8 +229,7 @@ export default class App extends Component {
|
|||||||
// not enumerable anymore
|
// not enumerable anymore
|
||||||
newUser = {
|
newUser = {
|
||||||
...newUser,
|
...newUser,
|
||||||
isPro: false,
|
isPro: false
|
||||||
...customUser
|
|
||||||
};
|
};
|
||||||
window.user = newUser;
|
window.user = newUser;
|
||||||
this.setState({ user: newUser, prefs }, this.updateSetting);
|
this.setState({ user: newUser, prefs }, this.updateSetting);
|
||||||
@@ -1803,7 +1804,6 @@ export default class App extends Component {
|
|||||||
codeSize={this.state.codeSize}
|
codeSize={this.state.codeSize}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SavedItemPane
|
<SavedItemPane
|
||||||
itemsMap={this.state.savedItems}
|
itemsMap={this.state.savedItems}
|
||||||
isOpen={this.state.isSavedItemPaneOpen}
|
isOpen={this.state.isSavedItemPaneOpen}
|
||||||
@@ -1814,9 +1814,7 @@ export default class App extends Component {
|
|||||||
onExport={this.exportBtnClickHandler.bind(this)}
|
onExport={this.exportBtnClickHandler.bind(this)}
|
||||||
mergeImportedItems={this.mergeImportedItems.bind(this)}
|
mergeImportedItems={this.mergeImportedItems.bind(this)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Alerts />
|
<Alerts />
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
show={this.state.isAddLibraryModalOpen}
|
show={this.state.isAddLibraryModalOpen}
|
||||||
closeHandler={() => this.setState({ isAddLibraryModalOpen: false })}
|
closeHandler={() => this.setState({ isAddLibraryModalOpen: false })}
|
||||||
@@ -1835,7 +1833,6 @@ export default class App extends Component {
|
|||||||
onChange={this.onExternalLibChange.bind(this)}
|
onChange={this.onExternalLibChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
show={this.state.isNotificationsModalOpen}
|
show={this.state.isNotificationsModalOpen}
|
||||||
closeHandler={() =>
|
closeHandler={() =>
|
||||||
@@ -1856,7 +1853,6 @@ export default class App extends Component {
|
|||||||
onChange={this.updateSetting.bind(this)}
|
onChange={this.updateSetting.bind(this)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
show={this.state.isProfileModalOpen}
|
show={this.state.isProfileModalOpen}
|
||||||
closeHandler={() => this.setState({ isProfileModalOpen: false })}
|
closeHandler={() => this.setState({ isProfileModalOpen: false })}
|
||||||
@@ -1916,9 +1912,13 @@ export default class App extends Component {
|
|||||||
this.closeAllOverlays();
|
this.closeAllOverlays();
|
||||||
this.loginBtnClickHandler();
|
this.loginBtnClickHandler();
|
||||||
}}
|
}}
|
||||||
|
onBuyFromExtensionClick={() => {
|
||||||
|
console.log('open modal');
|
||||||
|
this.closeAllOverlays();
|
||||||
|
this.setState({ isProOnAppModalOpen: true });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
{/* Login modal is intentionally kept here after assets & share modal because
|
{/* Login modal is intentionally kept here after assets & share modal because
|
||||||
they trigger this modal and if order isn't maintainer, the modal overlay doesn't
|
they trigger this modal and if order isn't maintainer, the modal overlay doesn't
|
||||||
show properly */}
|
show properly */}
|
||||||
@@ -1929,7 +1929,6 @@ export default class App extends Component {
|
|||||||
>
|
>
|
||||||
<Login />
|
<Login />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<HelpModal
|
<HelpModal
|
||||||
show={this.state.isHelpModalOpen}
|
show={this.state.isHelpModalOpen}
|
||||||
closeHandler={() => this.setState({ isHelpModalOpen: false })}
|
closeHandler={() => this.setState({ isHelpModalOpen: false })}
|
||||||
@@ -1959,17 +1958,14 @@ export default class App extends Component {
|
|||||||
)}
|
)}
|
||||||
dontAskBtnClickHandler={this.dontAskToImportAnymore.bind(this)}
|
dontAskBtnClickHandler={this.dontAskToImportAnymore.bind(this)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OnboardingModal
|
<OnboardingModal
|
||||||
show={this.state.isOnboardModalOpen}
|
show={this.state.isOnboardModalOpen}
|
||||||
closeHandler={() => this.setState({ isOnboardModalOpen: false })}
|
closeHandler={() => this.setState({ isOnboardModalOpen: false })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Js13KModal
|
<Js13KModal
|
||||||
show={this.state.isJs13KModalOpen}
|
show={this.state.isJs13KModalOpen}
|
||||||
closeHandler={() => this.setState({ isJs13KModalOpen: false })}
|
closeHandler={() => this.setState({ isJs13KModalOpen: false })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CreateNewModal
|
<CreateNewModal
|
||||||
show={this.state.isCreateNewModalOpen}
|
show={this.state.isCreateNewModalOpen}
|
||||||
closeHandler={() => this.setState({ isCreateNewModalOpen: false })}
|
closeHandler={() => this.setState({ isCreateNewModalOpen: false })}
|
||||||
@@ -1982,7 +1978,10 @@ export default class App extends Component {
|
|||||||
this
|
this
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<ProOnAppModal
|
||||||
|
show={this.state.isProOnAppModalOpen}
|
||||||
|
closeHandler={() => this.setState({ isProOnAppModalOpen: false })}
|
||||||
|
/>
|
||||||
<Modal
|
<Modal
|
||||||
extraClasses=""
|
extraClasses=""
|
||||||
show={this.state.isFilesLimitModalOpen}
|
show={this.state.isFilesLimitModalOpen}
|
||||||
@@ -1999,21 +1998,18 @@ export default class App extends Component {
|
|||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<CommandPalette
|
<CommandPalette
|
||||||
show={this.state.isCommandPaletteOpen}
|
show={this.state.isCommandPaletteOpen}
|
||||||
files={linearizeFiles(this.state.currentItem.files || [])}
|
files={linearizeFiles(this.state.currentItem.files || [])}
|
||||||
isCommandMode={this.state.isCommandPaletteInCommandMode}
|
isCommandMode={this.state.isCommandPaletteInCommandMode}
|
||||||
closeHandler={() => this.setState({ isCommandPaletteOpen: false })}
|
closeHandler={() => this.setState({ isCommandPaletteOpen: false })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Portal into="#portal">
|
<Portal into="#portal">
|
||||||
<div
|
<div
|
||||||
class="modal-overlay"
|
class="modal-overlay"
|
||||||
onClick={this.modalOverlayClickHandler.bind(this)}
|
onClick={this.modalOverlayClickHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|
||||||
<Icons />
|
<Icons />
|
||||||
<form
|
<form
|
||||||
style="display:none;"
|
style="display:none;"
|
||||||
|
@@ -233,6 +233,10 @@ button {
|
|||||||
color: #f7ae2d;
|
color: #f7ae2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.para {
|
||||||
|
max-width: 60ch;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
.block--mobile {
|
.block--mobile {
|
||||||
display: block;
|
display: block;
|
||||||
|
Reference in New Issue
Block a user