feat: update premium modal ui

This commit is contained in:
AykutSarac 2023-05-06 15:18:25 +03:00
parent 5c290a35d1
commit 53138b50c8
No known key found for this signature in database
5 changed files with 96 additions and 48 deletions

View File

@ -93,7 +93,7 @@ export const Graph = ({ isWidget = false }: GraphProps) => {
const changeRatio = Math.abs((areaSize * 100) / (paneWidth * paneHeight) - 100);
setPaneWidth(layout.width + 50);
setPaneHeight(layout.height as number + 50);
setPaneHeight((layout.height as number) + 50);
setTimeout(() => {
setLoading(false);

View File

@ -12,7 +12,7 @@ import {
AiOutlineUnlock,
} from "react-icons/ai";
import { MdReportGmailerrorred, MdOutlineCheckCircleOutline } from "react-icons/md";
import { VscAccount } from "react-icons/vsc";
import { VscAccount, VscWorkspaceTrusted } from "react-icons/vsc";
import { saveJson, updateJson } from "src/services/db/json";
import useJson from "src/store/useJson";
import useModal from "src/store/useModal";
@ -81,6 +81,7 @@ export const BottomBar = () => {
const data = useJson(state => state.data);
const hasError = useJson(state => state.hasError);
const user = useUser(state => state.user);
const premium = useUser(state => state.isPremium());
const lightmode = useStored(state => state.lightmode);
const hasChanges = useJson(state => state.hasChanges);
@ -155,6 +156,12 @@ export const BottomBar = () => {
<VscAccount />
{user ? user.name : "Login"}
</StyledBottomBarItem>
{!premium && (
<StyledBottomBarItem onClick={() => setVisible("premium")(true)}>
<VscWorkspaceTrusted />
Upgrade to Premium
</StyledBottomBarItem>
)}
<StyledBottomBarItem error={!!hasError}>
{hasError ? (
<Flex align="center" gap={2}>

View File

@ -1,8 +1,8 @@
import React from "react";
import Link from "next/link";
import styled from "styled-components";
import { Modal, Group, Button, Badge, Avatar, Grid, Divider, ModalProps } from "@mantine/core";
import { IoRocketSharp } from "react-icons/io5";
import useModal from "src/store/useModal";
import useUser from "src/store/useUser";
const StyledTitle = styled.div`
@ -43,6 +43,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 logout = useUser(state => state.logout);
@ -101,15 +102,14 @@ export const AccountModal: React.FC<ModalProps> = ({ opened, onClose }) => {
Cancel Subscription
</Button>
) : (
<Link href="/pricing" target="_blank" rel="noreferrer">
<Button
variant="gradient"
gradient={{ from: "teal", to: "lime", deg: 105 }}
leftIcon={<IoRocketSharp />}
>
UPGRADE TO PREMIUM!
</Button>
</Link>
<Button
variant="gradient"
gradient={{ from: "teal", to: "lime", deg: 105 }}
leftIcon={<IoRocketSharp />}
onClick={() => setVisible("premium")(true)}
>
UPGRADE TO PREMIUM!
</Button>
)}
<Button
color="red"

View File

@ -1,35 +1,85 @@
import React from "react";
import Link from "next/link";
import { Modal, Group, Button, Divider, ModalProps, Title, Image } from "@mantine/core";
import { IoRocketSharp } from "react-icons/io5";
import {
Modal,
ModalProps,
Title,
Flex,
Button,
Stack,
List,
ThemeIcon,
Divider,
Text,
Anchor,
} from "@mantine/core";
import { BsCheck } from "react-icons/bs";
export const PremiumModal: React.FC<ModalProps> = ({ opened, onClose }) => {
return (
<Modal title="JSON Crack Premium" opened={opened} onClose={onClose} centered>
<Group py="sm">
<Title
variant="gradient"
order={3}
gradient={{ from: "yellow", to: "hotpink" }}
strikethrough
align="center"
>
Enhance your experience, unlock full benefits of JSON Crack!
</Title>
<Image mx="auto" src="assets/bunny.png" width={150} alt="bunny" />
</Group>
<Divider py="xs" />
<Group position="center">
<Link href="/pricing" target="_blank" rel="noreferrer">
<Button
variant="gradient"
gradient={{ from: "yellow", to: "hotpink" }}
leftIcon={<IoRocketSharp />}
>
UPGRADE TO PREMIUM!
<Modal title="Your Plan" size="auto" opened={opened} onClose={onClose} centered>
<Flex gap="lg">
<Stack spacing="xs">
<Title order={3}>
Free plan
<Text size="sm" color="dimmed">
(Free)
</Text>
</Title>
<Button variant="filled" color="dark" size="md">
Your current plan
</Button>
</Link>
</Group>
<List
spacing="xs"
size="sm"
center
icon={
<ThemeIcon color="dark.6" size={20} radius="xl">
<BsCheck size="1rem" />
</ThemeIcon>
}
>
<List.Item>Store up to 15 files</List.Item>
<List.Item>Visualize standard size data</List.Item>
</List>
</Stack>
<Divider color="gray" orientation="vertical" />
<Stack spacing="xs">
<Title order={3}>
Herowand Premium
<Text size="sm" color="dimmed">
USD 5$/mo
</Text>
</Title>
<Button
component="a"
href="https://www.patreon.com/herowand"
variant="filled"
color="teal"
size="md"
target="_blank"
>
Upgrade plan
</Button>
<List
spacing="xs"
size="sm"
center
icon={
<ThemeIcon color="teal" size={20} radius="xl">
<BsCheck size="1rem" />
</ThemeIcon>
}
>
<List.Item>Edit directly on graph</List.Item>
<List.Item>JSON Schema support</List.Item>
<List.Item>Visualize data at full capability</List.Item>
<List.Item>Save up to 200 files</List.Item>
</List>
<Anchor fz="sm" href="https://editor.herowand.com" target="_blank">
Features are available at Herowand Editor
</Anchor>
</Stack>
</Flex>
</Modal>
);
};

View File

@ -10,7 +10,6 @@ interface UserActions {
setUser: (key: keyof typeof initialStates, value: any) => void;
checkSession: () => void;
isPremium: () => boolean;
validatePremium: (cb: () => void) => void;
}
const initialStates = {
@ -55,14 +54,6 @@ const useUser = create<UserStates & UserActions>()((set, get) => ({
}
}
},
validatePremium: callback => {
if (get().isAuthenticated) {
if (!get().isPremium()) return useModal.getState().setVisible("premium")(true);
return callback();
} else {
return useModal.getState().setVisible("account")(true);
}
},
}));
export default useUser;