mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
create pricing page
This commit is contained in:
parent
f42bbe6b83
commit
0195933c0a
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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'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>
|
||||
|
@ -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'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
124
src/pages/pricing.tsx
Normal 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;
|
Loading…
x
Reference in New Issue
Block a user