create pricing page

This commit is contained in:
AykutSarac 2022-12-25 21:05:41 +03:00
parent f42bbe6b83
commit 0195933c0a
5 changed files with 138 additions and 109 deletions

View File

@ -17,7 +17,7 @@ interface ButtonProps {
type ConditionalProps =
| ({
link?: boolean;
link: boolean;
} & React.ComponentPropsWithoutRef<"a">)
| ({
link?: never;
@ -30,18 +30,20 @@ function getButtonStatus(status: keyof typeof ButtonType, theme: DefaultTheme) {
const StyledButton = styled.button<{
status: keyof typeof ButtonType;
block: boolean;
link: boolean;
}>`
display: inline-flex;
align-items: center;
background: ${({ status, theme }) => getButtonStatus(status, theme)};
color: #ffffff;
padding: 8px 16px;
padding: ${({ link }) => (link ? "2px 16px" : "8px 16px")};
min-width: 70px;
min-height: 32px;
border-radius: 3px;
font-family: "Mona Sans";
font-size: 14px;
font-weight: 500;
width: ${({ block }) => (block ? "100%" : "fit-content")};
width: ${({ block }) => (block ? "-webkit-fill-available" : "fit-content")};
height: 40px;
background-image: none;
@ -89,6 +91,7 @@ export const Button: React.FC<ButtonProps & ConditionalProps> = ({
as={link ? "a" : "button"}
status={status ?? "PRIMARY"}
block={block}
link={link}
{...props}
>
<StyledButtonContent>{children}</StyledButtonContent>

View File

@ -85,7 +85,7 @@ export const BottomBar = () => {
if (hasChanges) {
try {
toast.loading("Saving JSON...", { id: "jsonSave" });
const res = await saveJson({ id: query.json, data: getJson() });
const res = await saveJson({ id: query.json as string, data: getJson() });
if (res.errors && res.errors.items.length > 0) throw res.errors;
if (res.data._id) replace({ query: { json: res.data._id } });
@ -149,8 +149,8 @@ export const BottomBar = () => {
Powered by
<StyledImg
height="20"
src="https://regexlearn.com/altogic.svg"
alt="powered by buildable"
src="https://www.altogic.com/img/logo_dark.svg"
alt="powered by altogic"
light={lightmode}
/>
</StyledBottomBarItem>

View File

@ -3,7 +3,6 @@ import Head from "next/head";
import Link from "next/link";
import Script from "next/script";
import { AiOutlineRight } from "react-icons/ai";
import { FaHeart } from "react-icons/fa";
import {
HiCursorClick,
HiLightningBolt,
@ -17,8 +16,8 @@ import { Producthunt } from "src/components/Producthunt";
import { Sponsors } from "src/components/Sponsors";
import { SupportButton } from "src/components/SupportButton";
import { baseURL } from "src/constants/data";
import { GoalsModal } from "src/containers/Modals/GoalsModal";
import * as Styles from "./styles";
import { IoRocketSharp } from "react-icons/io5";
const Navbar = () => (
<Styles.StyledNavbar>
@ -61,9 +60,9 @@ const HeroSection = () => {
</Styles.StyledButton>
<Styles.StyledButtonWrapper>
<Styles.StyledSponsorButton onClick={() => setModalVisible(true)}>
Help JSON Crack&apos;s Goals
<FaHeart />
<Styles.StyledSponsorButton href="/pricing" link>
GET PREMIUM
<IoRocketSharp />
</Styles.StyledSponsorButton>
<Styles.StyledSponsorButton
href="https://marketplace.visualstudio.com/items?itemName=AykutSarac.jsoncrack-vscode"
@ -73,7 +72,6 @@ const HeroSection = () => {
GET IT ON VS CODE
<SiVisualstudiocode />
</Styles.StyledSponsorButton>
<GoalsModal visible={isModalVisible} setVisible={setModalVisible} />
</Styles.StyledButtonWrapper>
</Styles.StyledHeroSection>
);
@ -205,7 +203,7 @@ const EmbedSection = () => (
intuitive interface makes it easy to navigate and understand even complex JSON data, making
it a valuable tool for anyone working with JSON.
</Styles.StyledMinorTitle>
<Styles.StyledButton href="https://jsoncrack.com/docs" status="SECONDARY" link>
<Styles.StyledButton href="/docs" status="SECONDARY" link>
LEARN TO EMBED
</Styles.StyledButton>
</Styles.StyledSectionArea>

View File

@ -1,96 +0,0 @@
import React from "react";
import { useRouter } from "next/router";
import { FaHeart, FaTwitter } from "react-icons/fa";
import { Button } from "src/components/Button";
import { Modal } from "src/components/Modal";
import styled from "styled-components";
const StyledTitle = styled.p`
display: flex;
align-items: center;
color: ${({ theme }) => theme.TEXT_POSITIVE};
flex: 1;
font-weight: 700;
margin-top: 0;
&::after {
background: ${({ theme }) => theme.TEXT_POSITIVE};
height: 1px;
content: "";
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
margin-left: 4px;
opacity: 0.6;
}
`;
const ButtonsWrapper = styled.div`
display: flex;
padding: 40px 0 0;
gap: 20px;
`;
export const GoalsModal = ({ visible, setVisible }) => {
const { push } = useRouter();
return (
<Modal visible={visible} setVisible={setVisible} size="md">
<Modal.Header>Help JSON Crack&apos;s Goals</Modal.Header>
<Modal.Content>
<StyledTitle>OUR GOAL</StyledTitle>
Dear user,
<br />
<br />
We are the team behind JSON Crack, an open-source JSON visualization app that helps users
better understand and work with complex JSON data. We are passionate about making JSON data
more accessible and user-friendly, and we believe our app has the potential to make a real
difference for developers and data analysts alike.
<br />
<br />
However, developing and maintaining JSON Crack takes time and resources, and we would love
your support in helping us continue to improve the app and make it even more useful for our
users. As a sponsor, your support would help us to continue to develop and maintain JSON
Crack, and would allow us to add new features and capabilities to the app.
<br />
<br />
We believe that JSON Crack has the potential to make a real difference for developers and
data analysts, and we would be grateful for your support in helping us continue to improve
the app. Thank you for considering sponsoring JSON Crack.
<br />
<br />
Sincerely,
<br />
<br />
The JSON Crack team
<ButtonsWrapper>
<Button
href="https://github.com/sponsors/AykutSarac"
target="_blank"
rel="me"
status="DANGER"
block
link
>
<FaHeart />
Sponsor
</Button>
<Button
href={`https://twitter.com/intent/tweet?button=&url=${encodeURIComponent(
"https://jsoncrack.com"
)}&text=Looking+to+understand+or+explore+some+JSON?+Just+paste+or+upload+to+visualize+it+as+a+graph+with+JSON+Crack+😍&button=`}
rel="noreferrer"
status="SECONDARY"
block
link
>
<FaTwitter />
Share on Twitter
</Button>
</ButtonsWrapper>
</Modal.Content>
<Modal.Controls setVisible={setVisible} />
</Modal>
);
};

124
src/pages/pricing.tsx Normal file
View File

@ -0,0 +1,124 @@
import React from "react";
import { Button } from "src/components/Button";
import { Footer } from "src/components/Footer";
import styled from "styled-components";
const StyledPageWrapper = styled.div`
padding: 5%;
`;
const StyledHeroSection = styled.section`
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
`;
const StyledPricingSection = styled.section`
display: flex;
justify-content: space-evenly;
background: rgba(181, 116, 214, 0.23);
width: 60%;
margin: 5% auto 0;
border-radius: 6px;
padding: 40px 20px;
`;
const StyledPricingCard = styled.div<{ premium?: boolean }>`
padding: 6px;
width: 40%;
${({ premium }) =>
premium
? `
background: rgba(255, 5, 214, 0.19);
border-radius: 4px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 5, 214, 0.74);`
: `background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.3);`};
`;
const StyledPricingCardTitle = styled.h2`
text-align: center;
font-weight: 800;
font-size: 24px;
`;
const StyledPricingCardPrice = styled.h3`
text-align: center;
font-weight: 600;
font-size: 24px;
color: ${({ theme }) => theme.SILVER};
`;
const StyledPricingCardDetails = styled.ul`
color: ${({ theme }) => theme.TEXT_NORMAL};
line-height: 2.3;
`;
const StyledPricingCardDetailsItem = styled.li`
font-weight: 500;
`;
const StyledButton = styled(Button)`
border: 1px solid white;
`;
const Pricing = () => {
return (
<>
<StyledPageWrapper>
<StyledHeroSection>
<img src="assets/icon.png" alt="json crack" width="400" />
<h1>Premium</h1>
</StyledHeroSection>
<StyledPricingSection>
<StyledPricingCard>
<StyledPricingCardTitle>Free</StyledPricingCardTitle>
<StyledPricingCardDetails>
<StyledPricingCardDetailsItem>Store up to 20 files</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>
Create short-links for saved JSON files
</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>
Embed saved JSON instantly
</StyledPricingCardDetailsItem>
</StyledPricingCardDetails>
</StyledPricingCard>
<StyledPricingCard premium>
<StyledPricingCardTitle>Premium</StyledPricingCardTitle>
<StyledPricingCardPrice>$5/mo</StyledPricingCardPrice>
<StyledPricingCardDetails>
<StyledPricingCardDetailsItem>
Create and share up to 200 files
</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>Store private JSON</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>
Premium role at Discord server
</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>
Get access to JSON Crack API to generate JSON remotely
</StyledPricingCardDetailsItem>
<StyledPricingCardDetailsItem>
Everything in previous tier
</StyledPricingCardDetailsItem>
</StyledPricingCardDetails>
<StyledButton href="https://www.patreon.com/jsoncrack" status="SUCCESS" block link>
GET IT NOW!
</StyledButton>
</StyledPricingCard>
</StyledPricingSection>
</StyledPageWrapper>
<Footer />
</>
);
};
export default Pricing;