Skip to content
This repository was archived by the owner on Dec 13, 2023. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 12 additions & 76 deletions web/components/pricing-card/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import styled from "@emotion/styled";
import BlankArea from "components/blank-area";
import Icon from "components/icon";
import LandingpageText from "components/landingpage/text";
import Link from "next/link";
import React, { useCallback } from "react";
import { Button, Flex, Text } from "rebass";

import BlankArea from "components/blank-area";
import Icon from "components/icon";
import LandingpageText from "components/landingpage/text";
import { usePopupContext } from "utils/context/PopupContext";
import { LandingpageUrls } from "utils/landingpage/constants";
import { media } from "utils/styled/media";
import { ThemeInterface } from "utils/styled/theme";
import PricingCTAButton from "components/pricing-cta-button";

function PricingCard(props: {
type: "paid" | "none-paid";
title: string;
price: string;
per?: string;
planList: string[];
button: React.ReactChild;
}) {
const { addPopup, removePopup } = usePopupContext();

Expand Down Expand Up @@ -51,49 +55,10 @@ function PricingCard(props: {
});
}, []);

const handleClickPaidPlan = useCallback(() => {
addPopup({
title: "",
element: (
<Flex
width="calc(100vw - 40px)"
alignItems="center"
flexDirection="column"
p="48px"
>
<Icon
className="cursor"
name="headerClose"
ml="auto"
onClick={() => removePopup()}
/>
<Flex width="80%" flexDirection="column" alignItems="center">
<LandingpageText variant="h4" textAlign="center">
Woopsy.
</LandingpageText>
<BlankArea height={[48, 48]} />
<LandingpageText variant="body1" textAlign="center">
Grida paid plans are disabled temporarily. Meanwhile, you can use
our free plan which basically does the same.
<Link href={LandingpageUrls.signup_with_return}>
<span style={{ margin: "0px 5px", color: "#172AD7" }}>
Sign up
</span>
</Link>
here.
</LandingpageText>
</Flex>
</Flex>
),
});
}, []);

return (
<Wrapper type={props.type}>
<Heading>
<LandingpageText variant="h4">
{props.type != "none-paid" ? "For you team" : "For you"}
</LandingpageText>
<LandingpageText variant="h4">{props.title}</LandingpageText>
{props.type === "none-paid" && (
<Icon
className="cursor"
Expand All @@ -103,10 +68,8 @@ function PricingCard(props: {
)}
</Heading>
<PlanPricing>
<LandingpageText variant="h4">
{props.type != "none-paid" ? "$20" : "$0"}
</LandingpageText>
{props.type != "none-paid" && <Seat variant="body1">per seat/mo</Seat>}
<LandingpageText variant="h4">{props.price}</LandingpageText>
{props.per && <Seat variant="body1">{props.per}</Seat>}
</PlanPricing>
<Flex alignItems="center" height="100%" my="30px">
<PlanDescription>
Expand All @@ -120,22 +83,7 @@ function PricingCard(props: {
))}
</PlanDescription>
</Flex>
{props.type === "none-paid" ? (
<PricingCTAButton
mt="auto"
style={{ borderRadius: 4, marginTop: "auto" }}
>
Start now
</PricingCTAButton>
) : (
<CardCTAButton
className="cursor"
type={props.type}
onClick={() => props.type != "none-paid" && handleClickPaidPlan()}
>
Start 14 Day Trial
</CardCTAButton>
)}
{props.button}
</Wrapper>
);
}
Expand Down Expand Up @@ -180,18 +128,6 @@ const Seat = styled(LandingpageText)`
margin-left: 10px;
`;

const CardCTAButton = styled(Button)`
margin-top: auto;
border-radius: 4px;
${p => {
if (p.type === "paid") {
return {
backgroundColor: "#D2D2D2",
};
}
}}
`;

const PlanDescription = styled(Flex)`
flex-direction: column;

Expand Down
11 changes: 7 additions & 4 deletions web/components/pricing-cta-button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import Button from "components/mdx/button";
import React from "react";

import Button from "components/mdx/button";
import { LandingpageUrls } from "utils/landingpage/constants";

function PricingCTAButton(props) {
const { ...style } = props;

const handleSignupClick = () => {
window.location.href = LandingpageUrls.signup_with_return;
const movetoDocs = () => {
window.location.href = LandingpageUrls.signup_with_custom_return(
"https://grida.co/docs/getting-started/intro",
);
};

return (
<Button className="cursor" onClick={handleSignupClick} {...style}>
<Button className="cursor" onClick={movetoDocs} {...style}>
Start now
</Button>
);
Expand Down
15 changes: 8 additions & 7 deletions web/components/start-now/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
import React from "react";
import styled from "@emotion/styled";
import React from "react";
import { Flex, Text, Heading, Button } from "rebass";

import Icon from "components/icon";
import PricingCTAButton from "components/pricing-cta-button";
import { media } from "utils/styled/media";
import { ThemeInterface } from "utils/styled/theme";
import PricingCTAButton from "components/pricing-cta-button";

const descList = [
{
title: "Code export including Flutter, React and more",
title: "Unlimited feature access",
},
{
title: "Private git integration",
title: "Unlimited public projects",
},
{
title: "Design linting",
title: "Up to 2 Figma files",
},
{
title: "Unlimited public projects",
title: "Code export including Flutter, React and more",
},
{
title: "Up to 5000 Objects",
title: "Design linting",
},
];

Expand Down
1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@mdx-js/react": "^1.6.22",
"@next/mdx": "^10.0.9",
"@reflect-ui/react-core": "0.0.1",
"@typeform/embed-react": "^1.2.4",
"@zeit/next-bundle-analyzer": "^0.1.2",
"@zeit/next-css": "^1.0.1",
"axios": "^0.21.1",
Expand Down
2 changes: 1 addition & 1 deletion web/pages/pricing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function PricingPage() {
<PageHead pageMeta={PAGES.pricing} />
<Sections.Hero_TryFreePlan />
<Sections.ComparePlans />
<Sections.FeaturesAndPricingTable />
{/* <Sections.FeaturesAndPricingTable /> */}
<Sections.FAQs />
</>
);
Expand Down
23 changes: 13 additions & 10 deletions web/sections/pricing/faqs.section.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import React from "react";
import { FaqQnaItem } from "components/faq/interface";

import FAQs from "components/faq";
import { FaqQnaItem } from "components/faq/interface";

const PRICING_FAQ_LIST: FaqQnaItem[] = [
{
query: "How do Grida make money?",
answer: "TBD",
answer:
"Grida makes money from Enterprise B2B plans. It's free and opensource for individual and startups.",
},
{
query: "What are the limitations with free plan?",
answer: "TBD",
answer: "There are no limitations with the free plan.",
},
{
query: "I cannot see images anymore. What happened?",
answer:
"Your image is uploaded and hosted on Grida cloud for 24 hours for development mode. If you enable publishing option for the screen / component you selected, all the resources will be long-lived. long-lived resource hosting is only available for paid plan. for free plan, we only support 24 hours temp hosting.",
"Your image is uploaded and hosted on Grida cloud for 24 hours for development mode. If you enable publishing option for the screen / component you selected, all the resources will be long-lived. long-lived resource hosting is only available for paid plan. for free plan, you have to download the asset, add manually to your repository.",
},
// {
// query: "How does the standard extra cloud usage fee calculated?",
// answer: "TBD",
// },
{
query: "How does the standard extra cloud usage fee calculated?",
answer: "TBD",
},
{
query: "Does Grida have explicit enterprise support plan?",
answer: "TBD",
query: "Do I need enterprise plan?",
answer:
"If you are a team of 5 or more, We highly recommand to contact us for enterprise plan. You can benefit the most from the enterprise plan, by customized build that will match your existing design, working process.",
},
];

Expand Down
88 changes: 63 additions & 25 deletions web/sections/pricing/pricing-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import React, { useCallback } from "react";
import styled from "@emotion/styled";
import { Flex, Heading, Text, Button } from "rebass";
import { PopupButton } from "@typeform/embed-react";
import SectionLayout from "layout/section";
import React from "react";
import { Flex, Heading, Text, Button } from "rebass";

import BlankArea from "components/blank-area";
import Icon from "components/icon";
import { media } from "utils/styled/media";
import defaultTheme, { ThemeInterface } from "utils/styled/theme";
import { usePopupContext } from "utils/context/PopupContext";
import { useWindowWidth } from "utils/hooks/use-window-width";
import Link from "next/link";
import { LandingpageUrls } from "utils/landingpage/constants";
import LandingpageText from "components/landingpage/text";
import PricingCard from "components/pricing-card";
import PricingCTAButton from "components/pricing-cta-button";
import { media } from "utils/styled/media";
import { ThemeInterface } from "utils/styled/theme";

const PersonalPlanList = [
"Private git integration",
"Design linting",
"Up to 2 Figma files",
"Unlimited Code generation",
"Unlimited ReactJS CodeGen",
"Unlimited Flutter CodeGen",
"0.5GB Asset Storage",
"Code export",
"Unlimited public projects",
"Up to 5000 Objects",
"1M Code blocks",
];

const TeamPlanList = [
const EnterprisePlanList = [
"Unlimited figma files",
"Unlimited Long-lived hosting",
"Unlimited Private projects",
"30GB Asset Storage",
"Code generation with full-engine capability",
"Unlimited Projects",
"Custom assets hosting / pipeline integration",
"Custom build for your existing design system",
"Custom build for your existing code base",
"Figma Webhook integration",
"Figma Shared Library support",
"Github CI integration",
"Custom Domain",
"1M Cloud objects",
"Unlimited Code blocks",
];

export default function PlanList() {

return (
<SectionLayout alignContent="center">
<Title mb="43px">Pay as you grow</Title>
<Title mb="43px">Customize for your company</Title>
<Desc mb={["69px", "185px", "145px", "159px"]}>
Start small, pay when you’re ready.
Enterprise Plan offers dedicated custom build
<br />
to best fit your existing product development process and architecture.
</Desc>
<Wrapper
width="100%"
Expand All @@ -49,8 +49,46 @@ export default function PlanList() {
justifyContent={["space-between", "center", "center", "center"]}
flexDirection={["column", "row", "row", "row"]}
>
<PricingCard type="none-paid" planList={PersonalPlanList} />
<PricingCard type="paid" planList={TeamPlanList} />
<PricingCard
type="none-paid"
title="For you"
price={"$0"}
planList={PersonalPlanList}
button={
<PricingCTAButton
mt="auto"
style={{ borderRadius: 4, marginTop: "auto" }}
>
Start now
</PricingCTAButton>
}
/>
<PricingCard
type="paid"
title="For you team"
planList={EnterprisePlanList}
price={"$90"}
per="per seat/mo"
button={
<PopupButton
id="i0HCo9XZ"
style={{
background: "black",
color: "white",
border: "none",
fontWeight: 500,
cursor: "pointer",
marginTop: "auto",
borderRadius: "4px",
padding: 12,
fontSize: 16,
}}
size={80}
>
Contact Sales
</PopupButton>
}
/>
</Wrapper>
<BlankArea height={[182, 264]} />
</SectionLayout>
Expand Down
2 changes: 2 additions & 0 deletions web/utils/landingpage/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const LandingpageUrls = {
* return to home after signup
*/
signup_with_return: `https://accounts.grida.co/signup?redirect_uri=${signup_callback_redirect_uri()}`,
signup_with_custom_return: redirect =>
`https://accounts.grida.co/signup?redirect_uri=${redirect}`,
signup: "https://accounts.grida.co/signup",
// todo endregion swap sign up when ready

Expand Down
Loading