mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-26 08:11:17 +02:00
get checkout ready
This commit is contained in:
15
package-lock.json
generated
15
package-lock.json
generated
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emmetio/codemirror-plugin": "^0.5.4",
|
"@emmetio/codemirror-plugin": "^0.5.4",
|
||||||
"@lingui/react": "^2.8.3",
|
"@lingui/react": "^2.8.3",
|
||||||
|
"canvas-confetti": "^1.9.2",
|
||||||
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
|
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
|
||||||
"codemirror": "^5.37.0",
|
"codemirror": "^5.37.0",
|
||||||
"copy-webpack-plugin": "^4.5.1",
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
@@ -7095,6 +7096,15 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/canvas-confetti": {
|
||||||
|
"version": "1.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.2.tgz",
|
||||||
|
"integrity": "sha512-6Xi7aHHzKwxZsem4mCKoqP6YwUG3HamaHHAlz1hTNQPCqXhARFpSXnkC9TWlahHY5CG6hSL5XexNjxK8irVErg==",
|
||||||
|
"funding": {
|
||||||
|
"type": "donate",
|
||||||
|
"url": "https://www.paypal.me/kirilvatev"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/capture-exit": {
|
"node_modules/capture-exit": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
||||||
@@ -34038,6 +34048,11 @@
|
|||||||
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
|
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"canvas-confetti": {
|
||||||
|
"version": "1.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.2.tgz",
|
||||||
|
"integrity": "sha512-6Xi7aHHzKwxZsem4mCKoqP6YwUG3HamaHHAlz1hTNQPCqXhARFpSXnkC9TWlahHY5CG6hSL5XexNjxK8irVErg=="
|
||||||
|
},
|
||||||
"capture-exit": {
|
"capture-exit": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
||||||
|
@@ -71,6 +71,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emmetio/codemirror-plugin": "^0.5.4",
|
"@emmetio/codemirror-plugin": "^0.5.4",
|
||||||
"@lingui/react": "^2.8.3",
|
"@lingui/react": "^2.8.3",
|
||||||
|
"canvas-confetti": "^1.9.2",
|
||||||
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
|
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
|
||||||
"codemirror": "^5.37.0",
|
"codemirror": "^5.37.0",
|
||||||
"copy-webpack-plugin": "^4.5.1",
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
|
@@ -7,9 +7,15 @@ import { A, Button } from './common';
|
|||||||
import { useCheckout } from '../hooks/useCheckout';
|
import { useCheckout } from '../hooks/useCheckout';
|
||||||
import { Text } from './Text';
|
import { Text } from './Text';
|
||||||
import { Icon } from './Icons';
|
import { Icon } from './Icons';
|
||||||
|
import { showConfetti } from '../utils';
|
||||||
|
|
||||||
|
const checkoutIds = {
|
||||||
|
monthly: '1601bc00-9623-435b-b1de-2a70a2445c13',
|
||||||
|
annual: 'aae95d78-05c8-46f5-b11e-2d40ddd211d3'
|
||||||
|
};
|
||||||
export function Pro({ user }) {
|
export function Pro({ user }) {
|
||||||
const hasCheckoutLoaded = useCheckout();
|
const hasCheckoutLoaded = useCheckout();
|
||||||
|
const [isAnnual, setIsAnnual] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasCheckoutLoaded) {
|
if (hasCheckoutLoaded) {
|
||||||
@@ -17,7 +23,13 @@ export function Pro({ user }) {
|
|||||||
eventHandler: e => {
|
eventHandler: e => {
|
||||||
console.log('eventHandler', e);
|
console.log('eventHandler', e);
|
||||||
if (e.event === 'Checkout.Success') {
|
if (e.event === 'Checkout.Success') {
|
||||||
window.location.reload();
|
showConfetti(2);
|
||||||
|
alertsService.add(
|
||||||
|
'You are now PRO! 🎉. Reloading your superpowers...'
|
||||||
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -25,7 +37,17 @@ export function Pro({ user }) {
|
|||||||
}
|
}
|
||||||
}, [hasCheckoutLoaded]);
|
}, [hasCheckoutLoaded]);
|
||||||
return (
|
return (
|
||||||
<VStack gap={4} align="stretch">
|
<VStack gap={2} align="stretch">
|
||||||
|
<Stack justify="center">
|
||||||
|
<Switch
|
||||||
|
labels={['Monthly', 'Annually']}
|
||||||
|
checked={isAnnual}
|
||||||
|
showBothLabels={true}
|
||||||
|
onChange={e => {
|
||||||
|
setIsAnnual(e.target.checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
<Stack gap={2} align="stretch">
|
<Stack gap={2} align="stretch">
|
||||||
<Card
|
<Card
|
||||||
price="Free"
|
price="Free"
|
||||||
@@ -38,13 +60,15 @@ export function Pro({ user }) {
|
|||||||
/>
|
/>
|
||||||
<Card
|
<Card
|
||||||
bg="#674dad"
|
bg="#674dad"
|
||||||
price="$6/mo"
|
price={!isAnnual ? '$8/mo' : '$65/yr'}
|
||||||
name="Pro"
|
name="Pro"
|
||||||
action={
|
action={
|
||||||
<A
|
<A
|
||||||
class="btn btn--primary lemonsqueezy-button d-f jc-c ai-c"
|
class="btn btn--primary lemonsqueezy-button d-f jc-c ai-c"
|
||||||
style="gap:0.2rem"
|
style="gap:0.2rem"
|
||||||
href={`https://web-maker.lemonsqueezy.com/checkout/buy/1601bc00-9623-435b-b1de-2a70a2445c13?embed=1&checkout[custom][userId]=${user.uid}`}
|
href={`https://web-maker.lemonsqueezy.com/checkout/buy/${
|
||||||
|
checkoutIds[isAnnual ? 'annual' : 'monthly']
|
||||||
|
}?embed=1&checkout[custom][userId]=${user.uid}`}
|
||||||
>
|
>
|
||||||
Go <ProBadge />
|
Go <ProBadge />
|
||||||
</A>
|
</A>
|
||||||
@@ -59,6 +83,11 @@ export function Pro({ user }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<Stack justify="center">
|
||||||
|
<Text tag="p" appearance="secondary">
|
||||||
|
Prices are excluding taxes. 30 days refund policy if not satisfied.
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import { h } from 'preact';
|
|
||||||
|
|
||||||
export default function Switch({
|
export default function Switch({
|
||||||
checked,
|
checked,
|
||||||
onChange,
|
onChange,
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
--color-overlay: rgba(3, 8, 27, 0.7);
|
--color-overlay: rgba(3, 8, 27, 0.7);
|
||||||
--color-close-btn: #d12b4a;
|
--color-close-btn: #d12b4a;
|
||||||
--code-font-size: 16px;
|
--code-font-size: 16px;
|
||||||
--color-button: #d3a447;
|
--color-button: #e3ba26;
|
||||||
--color-focus-outline: #d3a447;
|
--color-focus-outline: #d3a447;
|
||||||
--color-form-control-bg: #2c214b;
|
--color-form-control-bg: #2c214b;
|
||||||
|
|
||||||
@@ -412,6 +412,7 @@ a > svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn--primary {
|
.btn--primary {
|
||||||
|
--black-mix: 70%;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
180deg,
|
180deg,
|
||||||
var(--color-button),
|
var(--color-button),
|
||||||
@@ -419,7 +420,8 @@ a > svg {
|
|||||||
);
|
);
|
||||||
color: black;
|
color: black;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
border: 1px solid color-mix(in lch, var(--color-button), black 70%);
|
border: 1px solid
|
||||||
|
color-mix(in lch, var(--color-button), black var(--black-mix));
|
||||||
box-shadow: inset 0 1px 0px 0 rgba(255, 255, 255, 0.15);
|
box-shadow: inset 0 1px 0px 0 rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,8 +436,11 @@ a > svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn:hover {
|
.btn:hover {
|
||||||
|
--black-mix: 90%;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);
|
box-shadow:
|
||||||
|
rgba(0, 0, 0, 0.1) 0px 20px 25px -5px,
|
||||||
|
rgba(0, 0, 0, 0.04) 0px 10px 10px -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:focus {
|
*:focus {
|
||||||
@@ -795,6 +800,8 @@ body > #demo-frame {
|
|||||||
|
|
||||||
.btn--dark,
|
.btn--dark,
|
||||||
.main-header__btn-wrap > button {
|
.main-header__btn-wrap > button {
|
||||||
|
--clr-1: hsl(0, 0%, 25%);
|
||||||
|
--clr-2: hsl(0, 0%, 13%);
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
/* text-transform: uppercase; */
|
/* text-transform: uppercase; */
|
||||||
/* font-size: 0.875rem; */
|
/* font-size: 0.875rem; */
|
||||||
@@ -809,7 +816,7 @@ body > #demo-frame {
|
|||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.9);
|
border: 1px solid rgba(0, 0, 0, 0.9);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: linear-gradient(180deg, hsl(0, 0%, 25%) 0, hsl(0, 0%, 13%) 100%);
|
background: linear-gradient(180deg, var(--clr-1) 0, var(--clr-2) 100%);
|
||||||
box-shadow: inset 0 1px 0px 0 rgba(255, 255, 255, 0.15);
|
box-shadow: inset 0 1px 0px 0 rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,12 +834,12 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn--dark:hover {
|
.btn--dark:hover {
|
||||||
background: #9297b3;
|
--clr-1: #6844ad;
|
||||||
color: #111;
|
/* color: #111; */
|
||||||
/* border-color: rgba(146, 151, 179, 0.5); */
|
/* border-color: rgba(146, 151, 179, 0.5); */
|
||||||
}
|
}
|
||||||
.btn--dark:hover > svg {
|
.btn--dark:hover > svg {
|
||||||
fill: #111;
|
/* fill: #111; */
|
||||||
}
|
}
|
||||||
.btn--dark.btn--active {
|
.btn--dark.btn--active {
|
||||||
background: linear-gradient(0deg, hsl(0, 0%, 25%) 0, hsl(0, 0%, 13%) 100%);
|
background: linear-gradient(0deg, hsl(0, 0%, 25%) 0, hsl(0, 0%, 13%) 100%);
|
||||||
@@ -2202,8 +2209,19 @@ while the theme CSS file is loading */
|
|||||||
background-position: bottom right;
|
background-position: bottom right;
|
||||||
}
|
}
|
||||||
.plan-card {
|
.plan-card {
|
||||||
|
background: rgb(255 255 255 / 10%);
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
--shadow-color: 253deg 47% 15%;
|
||||||
|
--shadow-elevation-low: 0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),
|
||||||
|
0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),
|
||||||
|
1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);
|
||||||
|
--shadow-elevation-medium: 0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),
|
||||||
|
0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),
|
||||||
|
2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),
|
||||||
|
5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);
|
||||||
|
|
||||||
|
box-shadow: var(--shadow-elevation-low);
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
body {
|
body {
|
||||||
|
34
src/utils.js
34
src/utils.js
@@ -1,9 +1,9 @@
|
|||||||
import { trackEvent } from './analytics';
|
import { trackEvent } from './analytics';
|
||||||
|
|
||||||
import { computeHtml, computeCss, computeJs } from './computes';
|
import { computeHtml, computeCss, computeJs } from './computes';
|
||||||
import { modes, HtmlModes, CssModes, JsModes } from './codeModes';
|
import { modes, HtmlModes, CssModes, JsModes } from './codeModes';
|
||||||
import { deferred } from './deferred';
|
import { deferred } from './deferred';
|
||||||
import { getExtensionFromFileName } from './fileUtils';
|
import { getExtensionFromFileName } from './fileUtils';
|
||||||
|
import confetti from 'canvas-confetti';
|
||||||
const esprima = require('esprima');
|
const esprima = require('esprima');
|
||||||
|
|
||||||
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
|
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
|
||||||
@@ -594,3 +594,35 @@ export async function copyToClipboard(text) {
|
|||||||
console.error('Failed to copy text: ', err);
|
console.error('Failed to copy text: ', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showConfetti(time = 4) {
|
||||||
|
var end = Date.now() + time * 1000;
|
||||||
|
|
||||||
|
(function frame() {
|
||||||
|
confetti({
|
||||||
|
particleCount: 1,
|
||||||
|
startVelocity: 0,
|
||||||
|
ticks: 100,
|
||||||
|
origin: {
|
||||||
|
x: Math.random(),
|
||||||
|
// since they fall down, start a bit higher than random
|
||||||
|
y: Math.random() - 0.2
|
||||||
|
},
|
||||||
|
colors: [
|
||||||
|
[
|
||||||
|
'#26ccff',
|
||||||
|
'#a25afd',
|
||||||
|
'#ff5e7e',
|
||||||
|
'#88ff5a',
|
||||||
|
'#fcff42',
|
||||||
|
'#ffa62d',
|
||||||
|
'#ff36ff'
|
||||||
|
][~~(Math.random() * 7)]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Date.now() < end) {
|
||||||
|
requestAnimationFrame(frame);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user