1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-25 16:01:14 +02:00

get checkout ready

This commit is contained in:
Kushagra Gour
2024-03-15 18:16:55 +05:30
parent b938966a45
commit dbad7d7400
6 changed files with 107 additions and 14 deletions

15
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"dependencies": {
"@emmetio/codemirror-plugin": "^0.5.4",
"@lingui/react": "^2.8.3",
"canvas-confetti": "^1.9.2",
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
"codemirror": "^5.37.0",
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@@ -34038,6 +34048,11 @@
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",

View File

@@ -71,6 +71,7 @@
"dependencies": {
"@emmetio/codemirror-plugin": "^0.5.4",
"@lingui/react": "^2.8.3",
"canvas-confetti": "^1.9.2",
"code-blast-codemirror": "chinchang/code-blast-codemirror#web-maker",
"codemirror": "^5.37.0",
"copy-webpack-plugin": "^4.5.1",

View File

@@ -7,9 +7,15 @@ import { A, Button } from './common';
import { useCheckout } from '../hooks/useCheckout';
import { Text } from './Text';
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 }) {
const hasCheckoutLoaded = useCheckout();
const [isAnnual, setIsAnnual] = useState(true);
useEffect(() => {
if (hasCheckoutLoaded) {
@@ -17,7 +23,13 @@ export function Pro({ user }) {
eventHandler: e => {
console.log('eventHandler', e);
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]);
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">
<Card
price="Free"
@@ -38,13 +60,15 @@ export function Pro({ user }) {
/>
<Card
bg="#674dad"
price="$6/mo"
price={!isAnnual ? '$8/mo' : '$65/yr'}
name="Pro"
action={
<A
class="btn btn--primary lemonsqueezy-button d-f jc-c ai-c"
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 />
</A>
@@ -59,6 +83,11 @@ export function Pro({ user }) {
]}
/>
</Stack>
<Stack justify="center">
<Text tag="p" appearance="secondary">
Prices are excluding taxes. 30 days refund policy if not satisfied.
</Text>
</Stack>
</VStack>
);
}

View File

@@ -1,5 +1,3 @@
import { h } from 'preact';
export default function Switch({
checked,
onChange,

View File

@@ -6,7 +6,7 @@
--color-overlay: rgba(3, 8, 27, 0.7);
--color-close-btn: #d12b4a;
--code-font-size: 16px;
--color-button: #d3a447;
--color-button: #e3ba26;
--color-focus-outline: #d3a447;
--color-form-control-bg: #2c214b;
@@ -412,6 +412,7 @@ a > svg {
}
.btn--primary {
--black-mix: 70%;
background: linear-gradient(
180deg,
var(--color-button),
@@ -419,7 +420,8 @@ a > svg {
);
color: black;
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);
}
@@ -434,8 +436,11 @@ a > svg {
}
.btn:hover {
--black-mix: 90%;
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 {
@@ -795,6 +800,8 @@ body > #demo-frame {
.btn--dark,
.main-header__btn-wrap > button {
--clr-1: hsl(0, 0%, 25%);
--clr-2: hsl(0, 0%, 13%);
box-sizing: content-box;
/* text-transform: uppercase; */
/* font-size: 0.875rem; */
@@ -809,7 +816,7 @@ body > #demo-frame {
padding: 3px 8px;
border: 1px solid rgba(0, 0, 0, 0.9);
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);
}
@@ -827,12 +834,12 @@ body > #demo-frame {
}
.btn--dark:hover {
background: #9297b3;
color: #111;
--clr-1: #6844ad;
/* color: #111; */
/* border-color: rgba(146, 151, 179, 0.5); */
}
.btn--dark:hover > svg {
fill: #111;
/* fill: #111; */
}
.btn--dark.btn--active {
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;
}
.plan-card {
background: rgb(255 255 255 / 10%);
border-radius: 0.4rem;
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) {
body {

View File

@@ -1,9 +1,9 @@
import { trackEvent } from './analytics';
import { computeHtml, computeCss, computeJs } from './computes';
import { modes, HtmlModes, CssModes, JsModes } from './codeModes';
import { deferred } from './deferred';
import { getExtensionFromFileName } from './fileUtils';
import confetti from 'canvas-confetti';
const esprima = require('esprima');
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
@@ -594,3 +594,35 @@ export async function copyToClipboard(text) {
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);
}
})();
}