1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-03-25 13:09:48 +01:00

add working pro modal n checkout

This commit is contained in:
Kushagra Gour 2024-03-05 13:49:52 +05:30
parent e89c2348e4
commit 4c4dc1f2e0
7 changed files with 112 additions and 23 deletions

@ -133,9 +133,9 @@ export default class Footer extends Component {
</svg>
</a>
<Button
onClick={this.props.getProBtnClickHandler}
onClick={this.props.proBtnClickHandler}
data-event-category="ui"
data-event-action="getProFooterBtnClick"
data-event-action="proFooterBtnClick"
class="footer__link ml-1 hint--rounded hint--top-right hide-on-mobile support-link"
aria-label={i18n._(
t`Be a PRO and get some advanced superpowers!`

35
src/components/Pro.jsx Normal file

@ -0,0 +1,35 @@
import { useEffect, useState } from 'preact/hooks';
import { ProBadge } from './ProBadge';
import { HStack, Stack, VStack } from './Stack';
import Switch from './Switch';
import { alertsService } from '../notifications';
import { A, Button } from './common';
import { useCheckout } from '../hooks/useCheckout';
export function Pro({ user }) {
const hasCheckoutLoaded = useCheckout();
useEffect(() => {
if (hasCheckoutLoaded) {
window.LemonSqueezy.Setup({
eventHandler: e => {
console.log('eventHandler', e);
if (e.event === 'Checkout.Success') {
window.location.reload();
}
}
});
window.LemonSqueezy.Refresh();
}
}, [hasCheckoutLoaded]);
return (
<VStack gap={4} align="stretch">
<A
class="btn lemonsqueezy-button"
href={`https://web-maker.lemonsqueezy.com/checkout/buy/1601bc00-9623-435b-b1de-2a70a2445c13?embed=1&checkout[custom][userId]=${user.uid}`}
>
Go <ProBadge />
</A>
</VStack>
);
}

@ -4,12 +4,15 @@ import { HStack, Stack, VStack } from './Stack';
import Switch from './Switch';
import { itemService } from '../itemService';
import { alertsService } from '../notifications';
import { Button } from './common';
const FREE_PUBLIC_ITEM_COUNT = 1;
const BASE_URL = location.origin;
export function Share({ user, item, onVisibilityChange }) {
const [publicItemCount, setPublicItemCount] = useState(0);
useEffect(() => {
if (!user) return;
window.db.getPublicItemCount(user.uid).then(c => {
setPublicItemCount(c);
console.log(c);
@ -25,7 +28,6 @@ export function Share({ user, item, onVisibilityChange }) {
const res = await fetch(
`http://127.0.0.1:5001/web-maker-app/us-central1/toggleVisibility?token=${token}&itemId=${item.id}`
);
console.log(res.status);
if (res.status >= 200 && res.status < 400) {
setPublicItemCount(publicItemCount + 1);
@ -41,31 +43,45 @@ export function Share({ user, item, onVisibilityChange }) {
alertsService.add('Visiblity set to private');
}
};
const copyUrl = () => {
navigator.clipboard.writeText(`${BASE_URL}/create/${item.id}`);
alertsService.add('URL copied to clipboard');
};
return (
<VStack gap={4} align="stretch">
<VStack gap={1} align="stretch">
<Switch checked={val} onChange={onChange}>
Go public?
<Switch
checked={val}
onChange={onChange}
labels={['Private', 'Public']}
>
Access
</Switch>
{item.isPublic && (
<p>
Public at{' '}
<a href={`https://webmaker.app/create/${item.id}`} target="_blank">
https://webmaker.app/create/{item.id}
</a>
<a href={`${BASE_URL}/create/${item.id}`} target="_blank">
{BASE_URL}/create/{item.id}
</a>{' '}
<Button class="btn btn--dark" onClick={copyUrl}>
Copy
</Button>
</p>
)}
</VStack>
<VStack gap={1} align="stretch">
<p>
You have {FREE_PUBLIC_ITEM_COUNT - publicItemCount}/
{FREE_PUBLIC_ITEM_COUNT} public creations left.
</p>
<p>
For unlimited public creations, upgrade to <ProBadge />
</p>
</VStack>
{!user?.isPro ? (
<VStack gap={1} align="stretch">
<p>
You have {FREE_PUBLIC_ITEM_COUNT - publicItemCount}/
{FREE_PUBLIC_ITEM_COUNT} public creations left.
</p>
<p>
For unlimited public creations, upgrade to <ProBadge />
</p>
</VStack>
) : null}
</VStack>
);
}

@ -71,6 +71,7 @@ import { I18nProvider } from '@lingui/react';
import { Assets } from './Assets.jsx';
import { LocalStorageKeys } from '../constants.js';
import { Share } from './Share.jsx';
import { Pro } from './Pro.jsx';
if (module.hot) {
require('preact/debug');
@ -121,7 +122,8 @@ export default class App extends Component {
isCreateNewModalOpen: false,
isCommandPaletteOpen: false,
isAssetsOpen: false,
isShareModalOpen: false
isShareModalOpen: false,
isProModalOpen: false
};
this.state = {
isSavedItemPaneOpen: false,
@ -1131,6 +1133,10 @@ export default class App extends Component {
trackEvent('ui', 'notificationButtonClick', version);
return false;
}
proBtnClickHandler() {
this.setState({ isProModalOpen: true });
trackEvent('ui', 'proBtnClick');
}
codepenBtnClickHandler(e) {
if (this.state.currentItem.cssMode === CssModes.ACSS) {
alert(
@ -1723,6 +1729,7 @@ export default class App extends Component {
onJs13KDownloadBtnClick={this.js13KDownloadBtnClickHandler.bind(
this
)}
proBtnClickHandler={this.proBtnClickHandler.bind(this)}
hasUnseenChangelog={this.state.hasUnseenChangelog}
codeSize={this.state.codeSize}
/>
@ -1817,6 +1824,12 @@ export default class App extends Component {
}}
/>
</Modal>
<Modal
show={this.state.isProModalOpen}
closeHandler={() => this.setState({ isProModalOpen: false })}
>
<Pro user={this.state.user} />
</Modal>
<HelpModal
show={this.state.isHelpModalOpen}
closeHandler={() => this.setState({ isHelpModalOpen: false })}

@ -4,11 +4,15 @@ import { trackEvent } from '../analytics';
class Clickable extends Component {
handleClick(e) {
const el = e.currentTarget;
trackEvent(
el.getAttribute('data-event-category'),
el.getAttribute('data-event-action')
);
this.props.onClick(e);
if (el.getAttribute('data-event-category')) {
trackEvent(
el.getAttribute('data-event-category'),
el.getAttribute('data-event-action')
);
}
if (this.props.onClick) {
this.props.onClick(e);
}
}
render() {
/* eslint-disable no-unused-vars */

20
src/hooks/useCheckout.js Normal file

@ -0,0 +1,20 @@
import { useState, useEffect } from 'react';
function useCheckout() {
const [hasVendorScriptLoaded, setHasVendorScriptLoaded] = useState();
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://app.lemonsqueezy.com/js/lemon.js';
script.async = 'true';
script.defer = 'true';
script.addEventListener('load', () => {
window.createLemonSqueezy();
setHasVendorScriptLoaded(true);
});
document.body.appendChild(script);
}, []);
return hasVendorScriptLoaded;
}
export { useCheckout };

@ -376,6 +376,7 @@ a > svg {
float: right;
display: flex;
align-items: center;
margin-inline-start: 2rem;
}
.btn {