mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
update payment flow
This commit is contained in:
parent
f820d59542
commit
21150a21c4
@ -1,3 +1,4 @@
|
||||
NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
||||
NEXT_PUBLIC_ALTOGIC_ENV_URL=https://jsoncrack.c5-na.altogic.com
|
||||
NEXT_PUBLIC_ALTOGIC_CLIENT_KEY=f1e92022789f4ccf91273a345ab2bdf8
|
||||
NEXT_PUBLIC_ALTOGIC_CLIENT_KEY=f1e92022789f4ccf91273a345ab2bdf8
|
||||
NEXT_PUBLIC_PAYMENT_URL=https://herowand.lemonsqueezy.com/checkout/buy/ce30521f-c7cc-44f3-9435-995d3260ba22
|
@ -1,3 +1,4 @@
|
||||
NEXT_PUBLIC_BASE_URL=https://jsoncrack.com
|
||||
NEXT_PUBLIC_ALTOGIC_ENV_URL=https://jsoncrack.c5-na.altogic.com
|
||||
NEXT_PUBLIC_ALTOGIC_CLIENT_KEY=f1e92022789f4ccf91273a345ab2bdf8
|
||||
NEXT_PUBLIC_ALTOGIC_CLIENT_KEY=f1e92022789f4ccf91273a345ab2bdf8
|
||||
NEXT_PUBLIC_PAYMENT_URL=https://herowand.lemonsqueezy.com/checkout/buy/ce30521f-c7cc-44f3-9435-995d3260ba22
|
@ -3,7 +3,7 @@ import useUser from "src/store/useUser";
|
||||
|
||||
export const CarbonAds = () => {
|
||||
const ref = React.useRef<HTMLDivElement>(null!);
|
||||
const premium = useUser(state => state.isPremium());
|
||||
const premium = useUser(state => state.premium);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!premium) {
|
||||
|
@ -2,6 +2,7 @@ import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Badge, Button, Image, List, ThemeIcon, Title } from "@mantine/core";
|
||||
import { BsCheck } from "react-icons/bs";
|
||||
import { paymentURL } from "src/constants/data";
|
||||
|
||||
const StyledPremiumView = styled.div`
|
||||
position: relative;
|
||||
@ -185,7 +186,7 @@ export const PremiumView = () => (
|
||||
component="a"
|
||||
variant="gradient"
|
||||
gradient={{ from: "blue", to: "teal" }}
|
||||
href="https://www.patreon.com/join/herowand/checkout?rid=8549056"
|
||||
href={paymentURL}
|
||||
target="_blank"
|
||||
>
|
||||
UPGRADE TO PREMIUM $5.00
|
||||
|
@ -59,7 +59,7 @@ const StyledEditorWrapper = styled.div<{ widget: boolean }>`
|
||||
|
||||
export const Graph = ({ isWidget = false }: GraphProps) => {
|
||||
const { validateHiddenNodes } = useToggleHide();
|
||||
const isPremium = useUser(state => state.isPremium());
|
||||
const isPremium = useUser(state => state.premium);
|
||||
const setLoading = useGraph(state => state.setLoading);
|
||||
const setZoomPanPinch = useGraph(state => state.setZoomPanPinch);
|
||||
const centerView = useGraph(state => state.centerView);
|
||||
|
@ -1,4 +1,5 @@
|
||||
export const baseURL = process.env.NEXT_PUBLIC_BASE_URL;
|
||||
export const baseURL = process.env.NEXT_PUBLIC_BASE_URL as string;
|
||||
export const paymentURL = process.env.NEXT_PUBLIC_PAYMENT_URL as string;
|
||||
|
||||
// Example taken from https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json
|
||||
const sampleJson = Object.freeze({
|
||||
|
@ -84,7 +84,7 @@ export const BottomBar = () => {
|
||||
const { query } = useRouter();
|
||||
const data = useFile(state => state.fileData);
|
||||
const user = useUser(state => state.user);
|
||||
const premium = useUser(state => state.isPremium());
|
||||
const premium = useUser(state => state.premium);
|
||||
const lightmode = useStored(state => state.lightmode);
|
||||
const hasChanges = useFile(state => state.hasChanges);
|
||||
const hasErrors = useFile(state => state.hasError);
|
||||
|
@ -103,7 +103,7 @@ export const Tools: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) =>
|
||||
const expandGraph = useGraph(state => state.expandGraph);
|
||||
const collapseGraph = useGraph(state => state.collapseGraph);
|
||||
const lightmode = useStored(state => state.lightmode);
|
||||
const premium = useUser(state => state.isPremium());
|
||||
const premium = useUser(state => state.premium);
|
||||
|
||||
const CoreKey = navigator.userAgent.indexOf("Mac OS X") ? "⌘" : "CTRL";
|
||||
|
||||
|
@ -2,6 +2,7 @@ import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Modal, Group, Button, Badge, Avatar, Grid, Divider, ModalProps } from "@mantine/core";
|
||||
import { IoRocketSharp } from "react-icons/io5";
|
||||
import { paymentURL } from "src/constants/data";
|
||||
import useModal from "src/store/useModal";
|
||||
import useUser from "src/store/useUser";
|
||||
|
||||
@ -45,7 +46,7 @@ const StyledContainer = styled.div`
|
||||
export const AccountModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
const user = useUser(state => state.user);
|
||||
const isPremium = useUser(state => state.isPremium());
|
||||
const isPremium = useUser(state => state.premium);
|
||||
const logout = useUser(state => state.logout);
|
||||
|
||||
return (
|
||||
@ -93,11 +94,7 @@ export const AccountModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
<Divider py="xs" />
|
||||
<Group position="right">
|
||||
{isPremium ? (
|
||||
<Button
|
||||
variant="light"
|
||||
color="red"
|
||||
onClick={() => window.open("https://patreon.com/herowand", "_blank")}
|
||||
>
|
||||
<Button variant="light" color="red" onClick={() => window.open(paymentURL, "_blank")}>
|
||||
Cancel Subscription
|
||||
</Button>
|
||||
) : (
|
||||
|
@ -165,7 +165,7 @@ const GraphCard: React.FC<{ data: File; refetch: () => void; active: boolean }>
|
||||
|
||||
const CreateCard: React.FC<{ reachedLimit: boolean }> = ({ reachedLimit }) => {
|
||||
const { replace } = useRouter();
|
||||
const isPremium = useUser(state => state.isPremium());
|
||||
const isPremium = useUser(state => state.premium);
|
||||
const getContents = useFile(state => state.getContents);
|
||||
const setHasChanges = useFile(state => state.setHasChanges);
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
|
@ -47,7 +47,7 @@ const CodeBlock: React.FC<{ children: any; [key: string]: any }> = ({
|
||||
};
|
||||
|
||||
export const NodeModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
const isPremium = useUser(state => state.isPremium());
|
||||
const isPremium = useUser(state => state.premium);
|
||||
const editContents = useFile(state => state.editContents);
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
const lightmode = useStored(state => (state.lightmode ? "light" : "vs-dark"));
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
Badge,
|
||||
} from "@mantine/core";
|
||||
import { BsCheck } from "react-icons/bs";
|
||||
import { paymentURL } from "src/constants/data";
|
||||
|
||||
export const PremiumModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
return (
|
||||
@ -52,7 +53,7 @@ export const PremiumModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
</Title>
|
||||
<Button
|
||||
component="a"
|
||||
href="https://www.patreon.com/join/herowand/checkout?rid=8549056"
|
||||
href={paymentURL}
|
||||
variant="filled"
|
||||
color="teal"
|
||||
size="md"
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
} from "@mantine/core";
|
||||
import { CgChevronDown } from "react-icons/cg";
|
||||
import { VscStarEmpty } from "react-icons/vsc";
|
||||
import { paymentURL } from "src/constants/data";
|
||||
import { JSONCrackLogo } from "../JsonCrackLogo";
|
||||
|
||||
const links: HeaderActionProps[] = [
|
||||
@ -36,12 +37,12 @@ const links: HeaderActionProps[] = [
|
||||
{ link: "/oss", label: "Open Source" },
|
||||
{ link: "https://github.com/sponsors/AykutSarac", label: "Sponsor" },
|
||||
{
|
||||
link: "https://www.patreon.com/herowand",
|
||||
link: paymentURL,
|
||||
label: "Become Backer",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ link: "https://www.patreon.com/join/herowand", label: "Plus" },
|
||||
{ link: paymentURL, label: "Plus" },
|
||||
{ link: "/docs", label: "Docs" },
|
||||
];
|
||||
|
||||
|
@ -6,20 +6,11 @@ import useModal from "./useModal";
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV === "development";
|
||||
|
||||
interface CustomUser extends User {
|
||||
premium: {
|
||||
status: boolean;
|
||||
end_date: string;
|
||||
};
|
||||
type: 0 | 1;
|
||||
}
|
||||
|
||||
interface UserActions {
|
||||
login: (response: AltogicAuth) => void;
|
||||
logout: () => void;
|
||||
setUser: (key: keyof typeof initialStates, value: any) => void;
|
||||
checkSession: () => void;
|
||||
isPremium: () => boolean;
|
||||
}
|
||||
|
||||
const devUser = {
|
||||
@ -32,28 +23,23 @@ const devUser = {
|
||||
signUpAt: "2022-12-04T11:07:32.000Z",
|
||||
lastLoginAt: "2023-05-13T09:56:02.915Z",
|
||||
updatedAt: "2023-05-06T16:19:47.486Z",
|
||||
type: 1,
|
||||
} as CustomUser;
|
||||
} as User;
|
||||
|
||||
interface UserStates {
|
||||
user: CustomUser | null;
|
||||
user: User | null;
|
||||
isAuthenticated: boolean;
|
||||
premium: boolean;
|
||||
}
|
||||
|
||||
const initialStates: UserStates = {
|
||||
isAuthenticated: false,
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
premium: false,
|
||||
};
|
||||
|
||||
const useUser = create<UserStates & UserActions>()((set, get) => ({
|
||||
const useUser = create<UserStates & UserActions>()(set => ({
|
||||
...initialStates,
|
||||
setUser: (key, value) => set({ [key]: value }),
|
||||
isPremium: () => {
|
||||
const user = get().user;
|
||||
|
||||
if (user) return user.type > 0;
|
||||
return false;
|
||||
},
|
||||
logout: async () => {
|
||||
const session = altogic.auth.getSession();
|
||||
if (!session) return;
|
||||
@ -66,14 +52,15 @@ const useUser = create<UserStates & UserActions>()((set, get) => ({
|
||||
toast.success("Logged out.");
|
||||
useModal.setState({ account: false });
|
||||
},
|
||||
login: user => set({ user: user as unknown as CustomUser, isAuthenticated: true }),
|
||||
login: user => set({ user: user as unknown as User, isAuthenticated: true }),
|
||||
checkSession: async () => {
|
||||
if (isDevelopment) {
|
||||
return set({ user: devUser as User, isAuthenticated: true, premium: true });
|
||||
}
|
||||
|
||||
const currentSession = altogic.auth.getSession();
|
||||
|
||||
if (currentSession) {
|
||||
if (isDevelopment) {
|
||||
return set({ user: devUser as CustomUser, isAuthenticated: true });
|
||||
}
|
||||
const { user, errors } = await altogic.auth.getUserFromDB();
|
||||
if (errors?.items || !user) {
|
||||
altogic.auth.clearLocalData();
|
||||
@ -82,8 +69,9 @@ const useUser = create<UserStates & UserActions>()((set, get) => ({
|
||||
|
||||
altogic.auth.setUser(user);
|
||||
altogic.auth.setSession(currentSession);
|
||||
const { data: premiumData } = await altogic.endpoint.get("/isPremium");
|
||||
|
||||
set({ user: user as CustomUser, isAuthenticated: true });
|
||||
set({ user: user as User, isAuthenticated: true, premium: premiumData.premium });
|
||||
} else if (new URLSearchParams(window.location.search).get("access_token")) {
|
||||
const { errors, user } = await altogic.auth.getAuthGrant();
|
||||
if (errors?.items) {
|
||||
@ -91,7 +79,8 @@ const useUser = create<UserStates & UserActions>()((set, get) => ({
|
||||
return;
|
||||
}
|
||||
|
||||
set({ user: user as CustomUser, isAuthenticated: true });
|
||||
const { data: premiumData } = await altogic.endpoint.get("/isPremium");
|
||||
set({ user: user as User, isAuthenticated: true, premium: premiumData.data.premium });
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user