mirror of
https://github.com/wasp-lang/open-saas.git
synced 2025-06-07 05:29:32 +02:00
move customer portal url to .env.client
This commit is contained in:
parent
88545be87f
commit
6848d16da4
@ -1,2 +1,5 @@
|
|||||||
# learn more about client side env vars https://wasp-lang.dev/docs/project/env-vars
|
# All client-side env vars must start with REACT_APP_ https://wasp-lang.dev/docs/project/env-vars
|
||||||
REACT_APP_SOME_VAR_NAME=foo
|
|
||||||
|
# Find your test url at https://dashboard.stripe.com/test/settings/billing/portal
|
||||||
|
# Remember to replace the test url with the live url before deploying to production
|
||||||
|
REACT_APP_STRIPE_CUSTOMER_PORTAL=
|
@ -1,8 +1,8 @@
|
|||||||
import { Link } from 'wasp/client/router';
|
import { Link } from 'wasp/client/router';
|
||||||
import { type User } from 'wasp/entities';
|
import { type User } from 'wasp/entities';
|
||||||
import { logout } from 'wasp/client/auth';
|
import { logout } from 'wasp/client/auth';
|
||||||
import { STRIPE_CUSTOMER_PORTAL_LINK } from '../../shared/constants';
|
|
||||||
import { TierIds } from '../../shared/constants';
|
import { TierIds } from '../../shared/constants';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
export default function AccountPage({ user }: { user: User }) {
|
export default function AccountPage({ user }: { user: User }) {
|
||||||
return (
|
return (
|
||||||
@ -82,7 +82,13 @@ function BuyMoreButton() {
|
|||||||
|
|
||||||
function CustomerPortalButton() {
|
function CustomerPortalButton() {
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
window.open(STRIPE_CUSTOMER_PORTAL_LINK, '_blank');
|
try {
|
||||||
|
const schema = z.string().url();
|
||||||
|
const customerPortalUrl = schema.parse(import.meta.env.REACT_APP_STRIPE_CUSTOMER_PORTAL);
|
||||||
|
window.open(customerPortalUrl, '_blank');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { useAuth } from 'wasp/client/auth';
|
import { useAuth } from 'wasp/client/auth';
|
||||||
import { stripePayment } from 'wasp/client/operations';
|
import { stripePayment } from 'wasp/client/operations';
|
||||||
import { TierIds, STRIPE_CUSTOMER_PORTAL_LINK } from '../../shared/constants';
|
import { TierIds } from '../../shared/constants';
|
||||||
import { AiFillCheckCircle } from 'react-icons/ai';
|
import { AiFillCheckCircle } from 'react-icons/ai';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { cn } from '../../shared/utils';
|
import { cn } from '../../shared/utils';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
export const tiers = [
|
export const tiers = [
|
||||||
{
|
{
|
||||||
@ -57,6 +58,20 @@ const PricingPage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleCustomerPortalClick = () => {
|
||||||
|
if (!user) {
|
||||||
|
history.push('/login');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const schema = z.string().url();
|
||||||
|
const customerPortalUrl = schema.parse(import.meta.env.REACT_APP_STRIPE_CUSTOMER_PORTAL);
|
||||||
|
window.open(customerPortalUrl, '_blank');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='py-10 lg:mt-10'>
|
<div className='py-10 lg:mt-10'>
|
||||||
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
|
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
|
||||||
@ -115,8 +130,8 @@ const PricingPage = () => {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{!!user && user.hasPaid ? (
|
{!!user && user.hasPaid ? (
|
||||||
<a
|
<button
|
||||||
href={STRIPE_CUSTOMER_PORTAL_LINK}
|
onClick={handleCustomerPortalClick}
|
||||||
aria-describedby='manage-subscription'
|
aria-describedby='manage-subscription'
|
||||||
className={cn(
|
className={cn(
|
||||||
'mt-8 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-yellow-400',
|
'mt-8 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-yellow-400',
|
||||||
@ -127,7 +142,7 @@ const PricingPage = () => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
Manage Subscription
|
Manage Subscription
|
||||||
</a>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleBuyNowClick(tier.id)}
|
onClick={() => handleBuyNowClick(tier.id)}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
export enum TierIds {
|
export enum TierIds {
|
||||||
HOBBY = 'hobby-tier',
|
HOBBY = 'hobby-tier',
|
||||||
PRO = 'pro-tier',
|
PRO = 'pro-tier',
|
||||||
@ -8,38 +6,3 @@ export enum TierIds {
|
|||||||
|
|
||||||
export const DOCS_URL = 'https://docs.opensaas.sh';
|
export const DOCS_URL = 'https://docs.opensaas.sh';
|
||||||
export const BLOG_URL = 'https://docs.opensaas.sh/blog';
|
export const BLOG_URL = 'https://docs.opensaas.sh/blog';
|
||||||
|
|
||||||
const isDevEnv = process.env.NODE_ENV !== 'production';
|
|
||||||
const customerPortalTestUrl = '<your-url-here>'; // TODO: find your test url at https://dashboard.stripe.com/test/settings/billing/portal
|
|
||||||
const customerPortalProdUrl = '<your-url-here>'; // TODO: add before deploying to production
|
|
||||||
|
|
||||||
export const STRIPE_CUSTOMER_PORTAL_LINK = isDevEnv ? customerPortalTestUrl : customerPortalProdUrl;
|
|
||||||
|
|
||||||
checkStripePortalLinksExist({ customerPortalTestUrl, customerPortalProdUrl });
|
|
||||||
|
|
||||||
type StripePortalUrls = {
|
|
||||||
customerPortalTestUrl: string | undefined;
|
|
||||||
customerPortalProdUrl: string | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
function checkStripePortalLinksExist(links: StripePortalUrls) {
|
|
||||||
const schema = z.string().url();
|
|
||||||
const testResult = schema.safeParse(links.customerPortalTestUrl);
|
|
||||||
const prodResult = schema.safeParse(links.customerPortalProdUrl);
|
|
||||||
let consoleMsg = {
|
|
||||||
color: '\x1b[33m%s\x1b[0m',
|
|
||||||
msg: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (testResult.success && prodResult.success) {
|
|
||||||
consoleMsg.color = '\x1b[32m%s\x1b[0m';
|
|
||||||
consoleMsg.msg = '✅ Both STRIPE_CUSTOMER_PORTAL_LINK links defined';
|
|
||||||
} else if (!testResult.success && !prodResult.success) {
|
|
||||||
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined';
|
|
||||||
} else if (!testResult.success) {
|
|
||||||
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined for test env';
|
|
||||||
} else {
|
|
||||||
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined for prod env';
|
|
||||||
}
|
|
||||||
console.log(consoleMsg.color, consoleMsg.msg);
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
|
"module": "ES2022",
|
||||||
// We're bundling all code in the end so this is the most appropriate option,
|
// We're bundling all code in the end so this is the most appropriate option,
|
||||||
// it's also important for autocomplete to work properly.
|
// it's also important for autocomplete to work properly.
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user