update landing

This commit is contained in:
AykutSarac 2024-08-20 12:21:16 +03:00
parent ffcda7a7a0
commit bc570810ca
No known key found for this signature in database
12 changed files with 182 additions and 359 deletions

View File

@ -32,7 +32,9 @@
"JSON Crack will provide you with a reasonable prior notice of any change in Subscription fees to give you an opportunity to terminate your Subscription before such change becomes effective.",
"Your continued use of Service after Subscription fee change comes into effect constitutes your agreement to pay the modified Subscription fee amount."
],
"Refunds": ["If not stated explicitly during the purchase, all payments are non-refundable except when required by law."],
"Refunds": [
"If not stated explicitly during the purchase, all payments are non-refundable except when required by law."
],
"Content": [
"Our Service allows you to post, link, store, share and otherwise make available certain information, text, graphics, videos, or other material (“Content”). You are responsible for Content that you post on or through Service, including its legality, reliability, and appropriateness.",
"By posting Content on or through Service, You represent and warrant that: (i) Content is yours (you own it) and/or you have the right to use it and the right to grant us the rights and license as provided in these Terms, and (ii) that the posting of your Content on or through Service does not violate the privacy rights, publicity rights, copyrights, contract rights or any other rights of any person or entity. We reserve the right to terminate the account of anyone found to be infringing on a copyright.",

View File

@ -47,7 +47,6 @@ const LiveEditor = () => {
<StyledLiveEditor onContextMenuCapture={e => e.preventDefault()}>
<ButtonGroup className="tab-group">
<Button
fw={500}
c="gray"
miw={80}
size="xs"

View File

@ -135,12 +135,12 @@ export const Features = () => {
spacing="xl"
>
{features.map((feature, index) => (
<Paper key={index} bg="gray.1" p="lg" radius="md">
<Paper key={index} bg="gray.0" p="lg" radius="md">
<Flex gap="sm" align="center" justify="center" direction="column">
<ThemeIcon radius="xl" size="xl" variant="light" color={feature.color}>
{feature.icon}
</ThemeIcon>
<Title ta="center" c="gray.9" order={3}>
<Title fw={500} ta="center" c="gray.9" order={3}>
{feature.title}
</Title>
<Text fz="sm" c="gray.8">

View File

@ -4,7 +4,6 @@ import Link from "next/link";
import { Stack, Flex, Badge, Button } from "@mantine/core";
import styled from "styled-components";
import { FaChevronRight } from "react-icons/fa6";
import { LovedBy } from "./LovedBy";
const plusJakartaSans = Plus_Jakarta_Sans({
subsets: ["latin-ext"],
@ -19,8 +18,8 @@ const StyledHeroSection = styled.main`
width: 100%;
height: 100%;
background-size: 40px 40px;
background-image: linear-gradient(to right, #f6f6f6 1px, transparent 1px),
linear-gradient(to bottom, #f6f6f6 1px, transparent 1px);
background-image: linear-gradient(to right, #f7f7f7 1px, transparent 1px),
linear-gradient(to bottom, #f7f7f7 1px, transparent 1px);
image-rendering: pixelated;
-webkit-mask-image: linear-gradient(to bottom, transparent, 0%, white, 98%, transparent);
mask-image: linear-gradient(to bottom, transparent, 0%, white, 98%, transparent);
@ -37,7 +36,7 @@ const StyledHeroSectionBody = styled.div`
flex-wrap: wrap;
align-items: center;
justify-content: center;
padding: 6rem 10% 3rem;
padding: 6rem 10% 8rem;
overflow: hidden;
text-align: center;
gap: 60px;
@ -100,7 +99,7 @@ const StyledHeroText = styled.h2`
}
`;
export const HeroSection = ({ stars }: { stars: number }) => {
export const HeroSection = () => {
return (
<StyledHeroSection>
<StyledHeroSectionBody>
@ -159,7 +158,6 @@ export const HeroSection = ({ stars }: { stars: number }) => {
size="md"
radius="md"
fw="500"
rightSection={<FaChevronRight />}
>
Premium
</Button>
@ -184,12 +182,10 @@ export const HeroSection = ({ stars }: { stars: number }) => {
size="lg"
radius="md"
fw="500"
rightSection={<FaChevronRight />}
>
Premium
</Button>
</Flex>
<LovedBy stars={stars} />
</Stack>
</StyledHeroSectionBody>
</StyledHeroSection>

View File

@ -97,7 +97,6 @@ export const PremiumPreview = () => {
variant="light"
color="gray"
c="black"
fw={500}
radius="sm"
size="lg"
fullWidth

View File

@ -1,8 +1,7 @@
import React from "react";
import Link from "next/link";
import { Title, Overlay, Image, Container, Flex, Box, List, Button, Paper } from "@mantine/core";
import { Title, Image, Container, Flex, Box, List, Button, Paper } from "@mantine/core";
import styled from "styled-components";
import { ReactCompareSlider, ReactCompareSliderHandle } from "react-compare-slider";
import { FaArrowRightLong } from "react-icons/fa6";
const StyledImageWrapper = styled.div`
@ -12,22 +11,6 @@ const StyledImageWrapper = styled.div`
`;
export const PremiumVsFree = () => {
const [labelOpacity, setLabelOpacity] = React.useState(1);
const labelStyle = {
fontSize: "1rem",
position: "absolute" as any,
padding: "6px 12px",
margin: "0 -6px",
color: "white",
opacity: labelOpacity,
borderRadius: ".25rem",
border: "1px solid white",
backdropFilter: "blur(0.25rem) saturate(180%) contrast(80%) brightness(120%)",
WebkitBackdropFilter: "blur(0.25rem) saturate(180%) contrast(80%) brightness(120%)",
backgroundColor: "rgba(0, 0, 0, 0.5)",
transition: "opacity 0.25s ease-in-out",
};
return (
<Container size="lg" id="premium" component="section" my={120}>
<Paper radius="lg" bg="dark" p="xl">
@ -78,7 +61,6 @@ export const PremiumVsFree = () => {
size="lg"
rightSection={<FaArrowRightLong />}
radius="xl"
fw={500}
fz="md"
>
See all features
@ -86,9 +68,11 @@ export const PremiumVsFree = () => {
</Box>
<StyledImageWrapper>
<ReactCompareSlider
onPointerDown={() => setLabelOpacity(0)}
onPointerUp={() => setLabelOpacity(1)}
<Link href="/premium#features" prefetch={false}>
<Image
loading="lazy"
src="./assets/preview/1.webp"
alt="Pro"
style={{
borderRadius: 10,
overflow: "hidden",
@ -96,43 +80,8 @@ export const PremiumVsFree = () => {
outline: "1px solid #c1c1c1",
outlineOffset: "6px",
}}
itemOne={<Image loading="lazy" src="./assets/preview/1.webp" alt="Pro" />}
itemTwo={
<>
<Overlay color="#000" backgroundOpacity={0.1} />
<Image loading="lazy" src="./assets/preview/free.webp" alt="Free" />
</>
}
handle={
<div
style={{
display: "flex",
alignItems: "center",
height: "100%",
}}
>
<ReactCompareSliderHandle />
<div
style={{
...labelStyle,
translate: "-100% 0",
left: 0,
}}
>
Premium
</div>
<div
style={{
...labelStyle,
translate: "100% 0",
right: 0,
}}
>
Free
</div>
</div>
}
/>
</Link>
</StyledImageWrapper>
</Flex>
</Paper>

View File

@ -58,23 +58,10 @@ export const Navbar = () => {
color="black"
radius="sm"
size="sm"
fw={500}
ml="sm"
>
VS Code
</Button>
<Button
component={Link}
prefetch={false}
href="/premium"
variant="subtle"
color="black"
radius="sm"
size="sm"
fw={500}
>
Premium
</Button>
<Button
component={Link}
prefetch={false}
@ -83,34 +70,19 @@ export const Navbar = () => {
color="black"
radius="sm"
size="sm"
fw={500}
>
Pricing
</Button>
<Button
component={Link}
prefetch={false}
href="/docs"
href="/affiliates"
variant="subtle"
color="black"
radius="sm"
size="sm"
fw={500}
>
Docs
</Button>
<Button
component={Link}
prefetch={false}
href="/#faq"
variant="subtle"
color="black"
radius="sm"
size="sm"
fw={500}
>
FAQ
Affiliate
</Button>
</Left>
<Right>

View File

@ -2,7 +2,7 @@ import React from "react";
import type { AppProps } from "next/app";
import Head from "next/head";
import { useRouter } from "next/router";
import { MantineProvider, createTheme } from "@mantine/core";
import { createTheme, MantineProvider } from "@mantine/core";
import "@mantine/core/styles.css";
import "@mantine/code-highlight/styles.css";
import { ThemeProvider } from "styled-components";
@ -43,6 +43,13 @@ const theme = createTheme({
radius: {
lg: "12px",
},
components: {
Button: {
defaultProps: {
fw: 500,
},
},
},
});
const isDevelopment = process.env.NODE_ENV === "development";

View File

@ -83,8 +83,8 @@ const Affiliate = () => {
</Text>
<Link href={AFFILIATE_SINGUP_URL} target="_blank" rel="noopener">
<Button
variant="default"
mt="lg"
color="orange"
radius="md"
size="lg"
rightSection={<MdChevronRight size={30} />}

View File

@ -1,5 +1,4 @@
import React from "react";
import type { GetStaticProps, InferGetStaticPropsType } from "next";
import Head from "next/head";
import { generateJsonld } from "src/constants/jsonld";
import { metaDescription } from "src/constants/landing";
@ -11,7 +10,7 @@ import { PremiumVsFree } from "src/containers/Landing/PremiumVsFree";
import { Pricing } from "src/containers/Landing/Pricing";
import Layout from "src/layout/Layout";
export const HomePage = ({ stars }: InferGetStaticPropsType<typeof getStaticProps>) => {
export const HomePage = () => {
return (
<Layout>
<Head>
@ -26,7 +25,7 @@ export const HomePage = ({ stars }: InferGetStaticPropsType<typeof getStaticProp
key="product-jsonld"
/>
</Head>
<HeroSection stars={stars} />
<HeroSection />
<HeroPreview />
<Features />
<PremiumVsFree />
@ -37,20 +36,3 @@ export const HomePage = ({ stars }: InferGetStaticPropsType<typeof getStaticProp
};
export default HomePage;
export const getStaticProps = (async () => {
try {
const res = await fetch("https://api.github.com/repos/AykutSarac/jsoncrack.com");
const repo = await res.json();
const stars = repo.stargazers_count;
return { props: { stars } };
} catch (error) {
return {
props: {
stars: 0,
},
};
}
}) satisfies GetStaticProps<{
stars: number;
}>;

View File

@ -307,7 +307,9 @@ const Premium = () => {
<Text fw={600} fz="xl" c="gray.7">
${PRICING.MONTHLY}
</Text>
<Text fw={500} fz="sm" c="gray.5" ml="2">
/ month
</Text>
</Flex>
</Group>
</StyledRadioCard>
@ -322,7 +324,9 @@ const Premium = () => {
<Text fw={600} fz="xl" c="gray.7">
${PRICING.ANNUAL * 12}
</Text>
<Text fw={500} fz="sm" c="gray.5" ml="2">
/ year
</Text>
</Flex>
</Group>
</StyledRadioCard>
@ -346,7 +350,9 @@ const Premium = () => {
<Text fw={600} fz="xl" c="gray.7">
${PRICING.LTD}
</Text>
<Text fw={500} fz="sm" c="gray.5" ml="2">
/ lifetime
</Text>
</Flex>
</Group>
</StyledRadioCard>

View File

@ -10,16 +10,13 @@ import {
Paper,
SegmentedControl,
Center,
Badge,
Tooltip,
Anchor,
type PaperProps,
Box,
} from "@mantine/core";
import styled from "styled-components";
import { AiOutlineInfoCircle } from "react-icons/ai";
import { FaArrowRightLong, FaCheck, FaXmark } from "react-icons/fa6";
import { VscLinkExternal } from "react-icons/vsc";
import { FaArrowRightLong, FaCheck } from "react-icons/fa6";
import Layout from "src/layout/Layout";
import { gaEvent } from "src/lib/utils/gaEvent";
@ -39,37 +36,38 @@ export const purchaseLinks = {
};
const StyledPaper = styled(Paper)<PaperProps & any>`
padding: 1.5em;
width: 350px;
padding: 1em;
width: 320px;
border-radius: 8px;
border: 2px solid #e2e2e2;
background: white;
border: 2px solid #efefef;
background: #fcfcfc;
`;
export const PricingCards = () => {
const [isMonthly, setIsMonthly] = React.useState(true);
return (
<Stack gap="0" align="center" maw="730px" mx="auto">
<Stack gap="0" align="center" maw="665px" mx="auto">
<Center my="lg">
<SegmentedControl
bg="gray.3"
bg="gray.1"
color="white"
value={isMonthly ? "Monthly" : "Annual"}
onChange={v => setIsMonthly(v === "Monthly")}
size="sm"
size="md"
w={280}
data={[
{
label: "Pay monthly",
label: "Monthly Billing",
value: "Monthly",
},
{
label: `Pay yearly (save ${PRICING.getAnnualSave()}%)`,
label: "Yearly Billing",
value: "Annual",
},
]}
radius="xl"
styles={{ label: { color: "black" } }}
styles={{ label: { color: "#282828" } }}
/>
</Center>
<Flex
@ -84,34 +82,92 @@ export const PricingCards = () => {
}}
mx="auto"
>
<StyledPaper>
<Flex justify="space-between">
<Stack gap="0">
<Text fw={500} size="lg" c="black">
Free
</Text>
<Text fz={36} fw={600} c="black">
$0
</Text>
<Text fz="xs" c="gray.7">
billed {isMonthly ? "monthly" : "annually"}
</Text>
</Stack>
</Flex>
<Button
component="a"
href="https://app.jsoncrack.com/sign-up"
target="_blank"
size="md"
radius="md"
variant="default"
color="dark"
fullWidth
my="md"
>
Sign Up
</Button>
<Flex direction="column" justify="space-between">
<List
spacing="sm"
size="sm"
c="black"
center
icon={<FaCheck size="18" color="#5fb409" />}
>
<List.Item>
<Text c="black" fw={500} fz="sm">
<Text component="span" c="violet" inherit>
25{" "}
</Text>
Documents Storage
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
<Text component="span" c="violet" inherit>
300 KB{" "}
</Text>
Data Support
</Text>
</List.Item>
<List.Item>
<Anchor
href="https://github.com/AykutSarac/jsoncrack.com"
target="_blank"
rel="noreferrer"
c="violet"
fw={500}
fz="sm"
style={{
textDecoration: "underline",
textDecorationStyle: "dashed",
textUnderlineOffset: "2px",
}}
>
Open Source
</Anchor>
</List.Item>
</List>
</Flex>
</StyledPaper>
<StyledPaper>
<Flex justify="space-between">
<Stack gap="0" w="100%">
<Flex align="center">
<Text fw={500} size="xl" c="black">
<Text fw={500} size="md" c="black">
Premium
</Text>
{!isMonthly && (
<Badge
fw={600}
size="md"
variant="light"
c="brightBlue"
radius="sm"
color="brightBlue"
ml="sm"
>
SAVE {PRICING.getAnnualSave()}%
</Badge>
)}
</Flex>
<Flex gap="xs" align="baseline">
<Text fz={38} fw={600} c="black">
<Text fz={36} fw={600} c="black">
${isMonthly ? PRICING.MONTHLY : PRICING.ANNUAL}
</Text>
<Text fz="md" c="gray.6">
/ mo
<Text fz="md" fw={500} c="gray.6">
/ month
</Text>
</Flex>
<Flex justify="space-between">
@ -126,226 +182,80 @@ export const PricingCards = () => {
</Flex>
<Button
component="a"
color="brightBlue"
color="dark"
onClick={() => gaEvent("Pricing", "click upgrade premium")}
href={isMonthly ? purchaseLinks.monthly : purchaseLinks.annual}
target="_blank"
size="lg"
size="md"
radius="md"
fullWidth
my="md"
rightSection={<FaArrowRightLong />}
>
Get Started
Upgrade
</Button>
<Text mt="xs" fz="xs" c="dimmed">
Full-featured version of the editor with unlimited access.
</Text>
<Flex direction="column" justify="space-between">
<List
spacing="sm"
size="sm"
mt="xs"
c="black"
center
icon={<FaCheck size="18" color="#1866db" />}
icon={<FaCheck size="18" color="#5fb409" />}
>
<List.Item>
<Tooltip
color="blue"
label="Visualize up to 4 MB of data"
maw={350}
multiline
withArrow
>
<Text
c="black"
fw={500}
fz="sm"
style={{
textDecoration: "underline",
textDecorationStyle: "dashed",
textUnderlineOffset: "2px",
}}
>
Larger data support
</Text>
</Tooltip>
</List.Item>
<List.Item>
<Tooltip
color="blue"
label="Load data 5x faster and 50% smaller graph size."
maw={350}
multiline
withArrow
>
<Text
c="black"
fw={500}
fz="sm"
style={{
textDecoration: "underline",
textDecorationStyle: "dashed",
textUnderlineOffset: "2px",
}}
>
Compact and Fast Visualization
</Text>
</Tooltip>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Compare data
Edit Data from Visualization
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Edit data on graph
Multi-Document Tabs
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Built-in tabs for multiple documents
Compare Data & Highlight Changes
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Store 200 documents
Customizable Themes
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
AI-powered data filter
AI-Powered Data Filtering
</Text>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Customize graph colors
<Text component="span" c="violet" inherit>
4 MB{" "}
</Text>
</List.Item>
</List>
</Flex>
</StyledPaper>
<StyledPaper>
<Flex justify="space-between">
<Stack gap="0">
<Text fw={500} size="xl" c="black">
Free
Data Support
</Text>
<Text fz={38} fw={600} c="black">
$0
</Text>
<Text fz="xs" c="gray.7">
billed {isMonthly ? "monthly" : "annually"}
</Text>
</Stack>
</Flex>
<Button
component={Link}
href="/editor"
prefetch={false}
size="lg"
radius="md"
variant="outline"
color="dark"
fullWidth
my="md"
rightSection={<FaArrowRightLong />}
>
Start Free
</Button>
<Text mt="xs" fz="xs" c="dimmed">
Basic version of the editor with limited features, open-source.
</Text>
<Flex direction="column" justify="space-between">
<List
spacing="sm"
size="sm"
mt="lg"
c="black"
center
icon={<FaCheck size="18" color="#1866db" />}
>
<List.Item>
<Tooltip
color="blue"
label="Visualize up to ~300 KB of data"
maw={350}
multiline
withArrow
>
<Text
c="black"
fw={500}
fz="sm"
style={{
textDecoration: "underline",
textDecorationStyle: "dashed",
textUnderlineOffset: "2px",
}}
>
Basic data size support
</Text>
</Tooltip>
</List.Item>
<List.Item>
<Tooltip
color="blue"
label={
<Flex align="center" gap="xs">
Open source and free to use
<VscLinkExternal />
</Flex>
}
maw={350}
multiline
withArrow
>
<Anchor
href="https://github.com/AykutSarac/jsoncrack.com"
target="_blank"
c="black"
fw={500}
fz="sm"
style={{
textDecoration: "underline",
textDecorationStyle: "dashed",
textUnderlineOffset: "2px",
}}
>
Open Source
</Anchor>
</Tooltip>
</List.Item>
<List.Item>
<Text c="black" fw={500} fz="sm">
Store 25 documents
<Text component="span" c="violet" inherit>
200{" "}
</Text>
Documents Storage
</Text>
</List.Item>
<List.Item icon={<FaXmark color="gray" size={20} />}>
<Text c="gray.6" fw={500} fz="sm">
Edit data on graph
<List.Item>
<Text c="black" fw={500} fz="sm">
<Text component="span" c="violet" inherit>
5x
</Text>{" "}
Faster Loading
</Text>
</List.Item>
<List.Item icon={<FaXmark color="gray" size={20} />}>
<Text c="gray.6" fw={500} fz="sm">
AI-powered data filter
<List.Item>
<Text c="black" fw={500} fz="sm">
<Text component="span" c="violet" inherit>
50%{" "}
</Text>
</List.Item>
<List.Item icon={<FaXmark color="gray" size={20} />}>
<Text c="gray.6" fw={500} fz="sm">
Compact visualization
</Text>
</List.Item>
<List.Item icon={<FaXmark color="gray" size={20} />}>
<Text c="gray.6" fw={500} fz="sm">
Compare data
</Text>
</List.Item>
<List.Item icon={<FaXmark color="gray" size={20} />}>
<Text c="gray.6" fw={500} fz="sm">
Customize graph colors
Smaller Graphs
</Text>
</List.Item>
</List>
@ -357,7 +267,7 @@ export const PricingCards = () => {
<Stack gap="5">
<Text c="dark" fz="md" fw={500}>
Buy once,
<Text ml={4} component="span" inherit c="brightBlue">
<Text ml={4} component="span" inherit c="violet">
use forever
</Text>
!
@ -370,10 +280,11 @@ export const PricingCards = () => {
component="a"
href={purchaseLinks.ltd}
target="_blank"
fw={500}
fz="sm"
size="md"
color="indigo"
variant="light"
radius="md"
color="violet"
rightSection={<FaArrowRightLong />}
>
Get Lifetime Access for ${PRICING.LTD}