Browse Source

initial commit

AykutSarac 2 năm trước cách đây
mục cha
commit
1c27e34aa3

+ 1 - 0
package.json

@@ -23,6 +23,7 @@
     "react-hot-toast": "^2.2.0",
     "react-icons": "^4.3.1",
     "react-render-if-visible": "^2.1.0",
+    "react-twitter-embed": "^4.0.4",
     "react-zoom-pan-pinch": "^2.1.3",
     "reaflow": "^5.0.4",
     "save-html-as-image": "^1.7.1",

BIN
public/jsonvisio-screenshot.png


+ 1 - 0
src/components/Button/index.tsx

@@ -24,6 +24,7 @@ const StyledButton = styled.button<{ status: keyof typeof ButtonType }>`
   color: #ffffff;
   padding: 8px 16px;
   min-width: 60px;
+  width: fit-content;
 
   :disabled {
     cursor: not-allowed;

+ 0 - 45
src/components/Footer/index.tsx

@@ -1,45 +0,0 @@
-import React from "react";
-import Link from "next/link";
-import styled from "styled-components";
-import { AiFillGithub, AiOutlineTwitter } from "react-icons/ai";
-
-import pkg from "../../../package.json";
-
-const StyledFooter = styled.footer`
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  flex-direction: column;
-  width: 100%;
-  color: ${({ theme }) => theme.SILVER};
-`;
-
-const StyledVersion = styled.pre`
-  margin-top: 0;
-`;
-
-const StyledSocial = styled.div`
-  display: flex;
-  gap: 14px;
-  font-size: 26px;
-`;
-
-export const Footer: React.FC = () => {
-  return (
-    <StyledFooter>
-      <StyledSocial>
-        <Link href="https://github.com/AykutSarac/jsonvisio.com">
-          <a aria-label="GitHub" rel="me" target="_blank">
-            <AiFillGithub />
-          </a>
-        </Link>
-        <Link href="https://twitter.com/aykutsarach">
-          <a aria-label="Twitter" rel="me" target="_blank">
-            <AiOutlineTwitter />
-          </a>
-        </Link>
-      </StyledSocial>
-      <StyledVersion>{pkg.version}</StyledVersion>
-    </StyledFooter>
-  );
-};

+ 7 - 15
src/components/Producthunt/index.tsx

@@ -1,19 +1,9 @@
 import React from "react";
 import styled from "styled-components";
 
-const StyledProducthunt = styled.a`
-  position: fixed;
-  bottom: 12px;
-  right: 12px;
-
-  @media only screen and (max-width: 768px) {
-    display: none;
-  }
-`;
-
 const StyledImage = styled.img`
-  width: 250px;
-  height: 54px;
+  object-fit: contain;
+  max-width: 300px;
 
   @media only screen and (max-width: 768px) {
     width: 200px;
@@ -23,15 +13,17 @@ const StyledImage = styled.img`
 
 export const Producthunt = () => {
   return (
-    <StyledProducthunt
+    <a
       href="https://www.producthunt.com/posts/json-visio?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-json-visio"
       target="_blank"
       rel="me"
     >
       <StyledImage
-        src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=332281&theme=light"
+        width="500"
+        height="200"
+        src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=332281&theme=neutral"
         alt="JSON Visio - Simple visualization tool for your JSON data. | Product Hunt"
       />
-    </StyledProducthunt>
+    </a>
   );
 };

+ 0 - 138
src/pages/index.bin.tsx

@@ -1,138 +0,0 @@
-import React from "react";
-import { Button } from "src/components/Button";
-import { Container } from "src/components/Container";
-import { Navbar } from "src/components/Navbar";
-import { Image } from "src/components/Image";
-import { AiFillGithub } from "react-icons/ai";
-import { Footer } from "src/components/Footer";
-import Head from "next/head";
-import { Producthunt } from "src/components/Producthunt";
-import { useRouter } from "next/router";
-import styled from "styled-components";
-
-const StyledHome = styled.div`
-  padding: 24px;
-
-  ::-webkit-scrollbar {
-    width: 8px;
-    background: #23272a !important;
-  }
-
-  ::-webkit-scrollbar-thumb {
-    border-radius: 5px;
-    background-color: #4d4d4d !important;
-  }
-`;
-
-const StyledContent = styled.div`
-  font-size: 20px;
-  font-weight: 500;
-  color: ${({ theme }) => theme.SILVER};
-  width: 50%;
-
-  @media only screen and (max-width: 768px) {
-    width: 100%;
-    text-align: center;
-
-    button {
-      margin-left: auto;
-      margin-right: auto;
-    }
-  }
-`;
-
-const StyledHeader = styled.h2`
-  font-size: 3rem;
-  color: ${({ theme }) => theme.FULL_WHITE};
-
-  @media only screen and (max-width: 768px) {
-    font-size: 2.2rem;
-  }
-`;
-
-const StyledSubContent = styled.div`
-  margin-bottom: 20px;
-`;
-
-const StyledText = styled.span<{ white?: boolean }>`
-  color: ${({ theme, white }) => (white ? theme.FULL_WHITE : theme.ORANGE)};
-`;
-
-const Home: React.FC = () => {
-  const { push } = useRouter();
-
-  return (
-    <StyledHome>
-      <Head>
-        <title>JSON Visio - Directly onto graphs</title>
-      </Head>
-      <Navbar />
-      <Container>
-        <StyledContent>
-          <StyledHeader as="h1">
-            Visualize your JSON into interactive graphs.
-          </StyledHeader>
-          <StyledSubContent>
-            Simple visualization tool for your JSON data. No forced structure,
-            paste your JSON and view it instantly.
-          </StyledSubContent>
-          <Button status="SECONDARY" onClick={() => push("/editor")}>
-            Start Generating
-          </Button>
-        </StyledContent>
-        <Image src="421.svg" width={500} height={400} alt="graphs" />
-      </Container>
-
-      <Container reverse>
-        <StyledContent>
-          <StyledHeader>No Rules</StyledHeader>
-          <StyledSubContent>
-            Be free, you don&apos;t have to restructure your json to transform
-            it onto graphs. We&apos;ve done it at our side, so you can just
-            paste your JSON.
-          </StyledSubContent>
-          <Button status="SUCCESS" onClick={() => push("/editor")}>
-            Paste It!
-          </Button>
-        </StyledContent>
-        <Image src="graphs3.svg" width={500} height={400} alt="preview" />
-      </Container>
-
-      <Container>
-        <StyledContent>
-          <StyledHeader>Import File</StyledHeader>
-          <StyledSubContent>
-            Have an existing file for your data? No worries, directly import it
-            into our editor without having to scroll through all of it!
-          </StyledSubContent>
-          <Button status="SUCCESS" onClick={() => push("/editor")}>
-            Import JSON
-          </Button>
-        </StyledContent>
-        <Image src="graphs4.svg" width={500} height={400} alt="preview" />
-      </Container>
-
-      <Container reverse>
-        <StyledContent>
-          <StyledHeader>Supported by Open Source</StyledHeader>
-          <StyledSubContent>
-            We do our work at open source. Help us improve by contributing to
-            <StyledText> JSON</StyledText>
-            <StyledText white> Visio</StyledText> at GitHub!
-          </StyledSubContent>
-          <Button
-            onClick={() => push("https://github.com/AykutSarac/jsonvisio.com")}
-          >
-            <AiFillGithub size={20} />
-            Check GitHub
-          </Button>
-        </StyledContent>
-        <Image src="graphs5.svg" width={500} height={400} alt="preview" />
-      </Container>
-      <Producthunt />
-      <Footer />
-    </StyledHome>
-  );
-};
-
-export default Home;

+ 327 - 33
src/pages/index.tsx

@@ -1,20 +1,33 @@
+import React from "react";
+import Head from "next/head";
 import Link from "next/link";
 import { useRouter } from "next/router";
-import React from "react";
+import { FaGithub, FaLinkedin, FaTwitter } from "react-icons/fa";
 import {
   HiCursorClick,
   HiLightningBolt,
   HiOutlineDownload,
   HiOutlineSearchCircle,
 } from "react-icons/hi";
+import { TwitterTweetEmbed } from "react-twitter-embed";
 import { Button } from "src/components/Button";
+import { Producthunt } from "src/components/Producthunt";
 import styled from "styled-components";
+import pkg from "../../package.json";
 
 const StyledHome = styled.div`
   display: flex;
   flex-direction: column;
   gap: 8em;
   font-family: "Roboto", sans-serif;
+
+  * {
+    box-sizing: border-box;
+  }
+
+  @media only screen and (max-width: 768px) {
+    gap: 3em;
+  }
 `;
 
 const StyledGradientText = styled.span`
@@ -38,6 +51,12 @@ const StyledNavbar = styled.nav`
   width: 100%;
   padding: 16px 16px;
   gap: 20px;
+
+  @media only screen and (max-width: 768px) {
+    a:first-of-type {
+      display: none;
+    }
+  }
 `;
 
 const StyledHeroSection = styled.section`
@@ -46,10 +65,14 @@ const StyledHeroSection = styled.section`
   justify-content: center;
   align-items: center;
   gap: 1.5em;
-  min-height: 50vh;
+  min-height: 45vh;
+  padding: 0 3%;
 `;
 
 const StyledNavLink = styled.a`
+  display: flex;
+  justify-content: center;
+  align-items: center;
   font-size: 1rem;
   cursor: pointer;
   transition: color 0.2s;
@@ -64,6 +87,10 @@ const StyledTitle = styled.h1`
   font-size: 5rem;
   font-weight: 900;
   margin: 0;
+
+  @media only screen and (max-width: 768px) {
+    font-size: 3rem;
+  }
 `;
 
 const StyledSubTitle = styled.h2`
@@ -72,6 +99,10 @@ const StyledSubTitle = styled.h2`
   font-size: 2.5rem;
   max-width: 40rem;
   margin: 0;
+
+  @media only screen and (max-width: 768px) {
+    font-size: 1.5rem;
+  }
 `;
 
 const StyledMinorTitle = styled.p`
@@ -80,10 +111,14 @@ const StyledMinorTitle = styled.p`
   font-size: 1.25rem;
   margin: 0;
   letter-spacing: 1.2px;
+
+  @media only screen and (max-width: 992px) {
+    font-size: 1rem;
+  }
 `;
 
 const StyledButton = styled(Button)`
-  background: #d0880d;
+  background: ${({ status }) => !status && "#a13cc2"};
   padding: 12px 24px;
 
   div {
@@ -91,17 +126,34 @@ const StyledButton = styled(Button)`
     font-weight: 700;
     font-size: 16px;
   }
+
+  @media only screen and (max-width: 768px) {
+    &:first-of-type {
+      pointer-events: none;
+
+      div {
+        content: "Incompatible Device";
+      }
+    }
+  }
 `;
 
 const StyledFeaturesSection = styled.section`
   display: flex;
-  max-width: 1200px;
+  max-width: 85%;
   margin: 0 auto;
   gap: 2rem;
+  padding: 60px 3%;
+
+  @media only screen and (max-width: 768px) {
+    flex-direction: column;
+    max-width: 80%;
+  }
 `;
 
 const StyledSectionCard = styled.div`
   text-align: center;
+  flex: 1;
 `;
 
 const StyledCardTitle = styled.div`
@@ -114,55 +166,220 @@ const StyledCardTitle = styled.div`
 const StyledCardIcon = styled.div``;
 
 const StyledCardDescription = styled.p`
+  color: #e0e0e0;
   text-align: left;
   line-height: 1.5rem;
   font-size: 0.875rem;
 `;
 
+const StyledGitHubSection = styled.section`
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  max-width: 85%;
+  margin: 0 auto;
+  gap: 4rem;
+  line-height: 1.5;
+  padding: 60px 3%;
+
+  & > div {
+    width: 100%;
+  }
+
+  @media only screen and (max-width: 768px) {
+    flex-direction: column-reverse;
+    max-width: 80%;
+  }
+`;
+
+const StyledSectionArea = styled.div`
+  display: flex;
+  flex-direction: column;
+  gap: 2rem;
+  width: 40%;
+  margin-top: 3rem;
+
+  h2,
+  p {
+    text-align: left;
+    letter-spacing: unset;
+  }
+
+  @media only screen and (max-width: 768px) {
+    width: 100%;
+
+    h2,
+    p {
+      text-align: center;
+    }
+
+    button {
+      align-self: center;
+    }
+  }
+`;
+
+const StyledSponsorSection = styled.section`
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  max-width: 85%;
+  margin: 0 auto;
+  gap: 2rem;
+  line-height: 1.5;
+  padding: 60px 3%;
+
+  @media only screen and (max-width: 768px) {
+    max-width: 80%;
+  }
+`;
+
+const StyledPreviewSection = styled.section`
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  max-width: 85%;
+  margin: 0 auto;
+  padding: 0 3%;
+
+  @media only screen and (max-width: 768px) {
+    display: none;
+    max-width: 80%;
+  }
+`;
+
+const StyledImage = styled.img`
+  max-width: 100%;
+  filter: drop-shadow(0px 0px 12px rgba(255, 255, 255, 0.6));
+`;
+
+const StyledFooter = styled.footer`
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  width: 80%;
+  margin: 0 auto;
+  padding: 30px 3%;
+  border-top: 1px solid #b4b4b4;
+  opacity: 0.7;
+`;
+
+const StyledFooterText = styled.p`
+  color: #b4b4b4;
+`;
+
+const StyledIconLinks = styled.div`
+  display: flex;
+  gap: 20px;
+
+  ${StyledNavLink} {
+    color: unset;
+  }
+`;
+
+const StyledHighlightedText = styled.span`
+  text-decoration: underline;
+  text-decoration-style: dashed;
+  text-decoration-color: #eab308;
+`;
+
+const StyledProducthuntSection = styled.section`
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 3rem;
+
+  max-width: 85%;
+  margin: 0 auto;
+  padding: 60px 3%;
+
+  ${StyledSectionArea} {
+    margin: 0;
+    width: 100%;
+
+    h2 {
+      text-align: right;
+    }
+  }
+
+  @media only screen and (max-width: 768px) {
+    flex-direction: column;
+    max-width: 80%;
+
+    ${StyledSectionArea} {
+      h2 {
+        text-align: center;
+      }
+    }
+  }
+`;
+
 const Home: React.FC = () => {
   const { push } = useRouter();
+  const [isMobile, setIsMobile] = React.useState(false);
+
+  React.useEffect(() => {
+    setIsMobile(window.screen.width <= 768);
+  }, []);
 
   return (
     <StyledHome>
+      <Head>
+        <title>JSON Visio - Directly onto graphs</title>
+      </Head>
       <StyledNavbar>
-        <Link href="/editor">
+        <Link href="/editor" passHref>
           <StyledNavLink>Editor</StyledNavLink>
         </Link>
-        <Link href="#features">
+        <Link href="#features" passHref>
           <StyledNavLink>Features</StyledNavLink>
         </Link>
-        <Link href="#sponsor">
+        <Link href="#sponsor" passHref>
           <StyledNavLink>Sponsor</StyledNavLink>
         </Link>
-        <Link href="https://github.com/AykutSarac/jsonvisio.com">
-          <StyledNavLink target="_blank" rel="external">
-            GitHub
-          </StyledNavLink>
-        </Link>
+        <StyledNavLink
+          href="https://github.com/AykutSarac/jsonvisio.com"
+          target="_blank"
+          rel="external"
+        >
+          GitHub
+        </StyledNavLink>
       </StyledNavbar>
 
-      <StyledHeroSection id="features">
+      <StyledHeroSection id="main">
         <StyledTitle>
           <StyledGradientText>JSON</StyledGradientText> Visio
         </StyledTitle>
         <StyledSubTitle>
-          Seamlessly visualize your JSON data instantly into graphs.
+          Seamlessly visualize your JSON data{" "}
+          <StyledHighlightedText>instantly</StyledHighlightedText> into graphs.
         </StyledSubTitle>
         <StyledMinorTitle>Paste - Import - Fetch!</StyledMinorTitle>
-        <StyledButton onClick={() => push("/editor")}>GET STARTED</StyledButton>
+        <StyledButton onClick={() => push("/editor")} disabled={isMobile}>
+          {isMobile ? "Incompatible Device" : "GO TO EDITOR"}
+        </StyledButton>
       </StyledHeroSection>
 
-      <StyledFeaturesSection>
+      <StyledPreviewSection>
+        <StyledImage
+          width="1200"
+          height="auto"
+          src="/jsonvisio-screenshot.png"
+          alt="preview"
+        />
+      </StyledPreviewSection>
+
+      <StyledFeaturesSection id="features">
         <StyledSectionCard>
           <StyledCardIcon>
             <HiCursorClick size={50} color="#3BA55D" />
           </StyledCardIcon>
-          <StyledCardTitle>SEAMLESS</StyledCardTitle>
+          <StyledCardTitle>EASY-TO-USE</StyledCardTitle>
           <StyledCardDescription>
-            What good is a powerful table if that super hip designer you just
-            hired can't work their UI magic on it? TanStack Table is headless by
-            design, which means 100% control down to the very smallest HTML tag,
-            component, class and style. Pixel Perfection? Go for it!
+            Don't even bother to update your schema to view your JSON into
+            graphs; directly paste, import or fetch! JSON Visio helps you to
+            visualize without any additional values and save your time.
           </StyledCardDescription>
         </StyledSectionCard>
 
@@ -172,10 +389,10 @@ const Home: React.FC = () => {
           </StyledCardIcon>
           <StyledCardTitle>SEARCH</StyledCardTitle>
           <StyledCardDescription>
-            What good is a powerful table if that super hip designer you just
-            hired can't work their UI magic on it? TanStack Table is headless by
-            design, which means 100% control down to the very smallest HTML tag,
-            component, class and style. Pixel Perfection? Go for it!
+            Have a huge file of values, keys or arrays? Worry no more, type in
+            the keyword you are looking for into search input and it will take
+            you to each node with matching result highlighting the line to
+            understand better!
           </StyledCardDescription>
         </StyledSectionCard>
 
@@ -185,10 +402,10 @@ const Home: React.FC = () => {
           </StyledCardIcon>
           <StyledCardTitle>DOWNLOAD</StyledCardTitle>
           <StyledCardDescription>
-            What good is a powerful table if that super hip designer you just
-            hired can't work their UI magic on it? TanStack Table is headless by
-            design, which means 100% control down to the very smallest HTML tag,
-            component, class and style. Pixel Perfection? Go for it!
+            Download the graph to your local machine and use it wherever you
+            want, to your blogs, website or make it a poster and paste to the
+            wall. Who wouldn't want to see a JSON Visio graph onto their wall,
+            eh?
           </StyledCardDescription>
         </StyledSectionCard>
 
@@ -198,13 +415,90 @@ const Home: React.FC = () => {
           </StyledCardIcon>
           <StyledCardTitle>LIVE</StyledCardTitle>
           <StyledCardDescription>
-            What good is a powerful table if that super hip designer you just
-            hired can't work their UI magic on it? TanStack Table is headless by
-            design, which means 100% control down to the very smallest HTML tag,
-            component, class and style. Pixel Perfection? Go for it!
+            With Microsoft's Monaco Editor which is also used by VS Code, easily
+            edit your JSON and directly view through the graphs. Also there's a
+            JSON validator above of it to make sure there is no type error.
           </StyledCardDescription>
         </StyledSectionCard>
       </StyledFeaturesSection>
+
+      <StyledGitHubSection id="github">
+        <TwitterTweetEmbed
+          tweetId="1519363257794015233"
+          options={{
+            width: "600",
+            align: "center",
+          }}
+        />
+        <StyledSectionArea>
+          <StyledSubTitle>Open Source Community</StyledSubTitle>
+          <StyledMinorTitle>
+            Join the Open Source Community by suggesting new ideas, support by
+            contributing; implementing new features, fixing bugs and doing
+            changes minor to major!
+          </StyledMinorTitle>
+          <StyledButton
+            onClick={() => push("https://github.com/AykutSarac/jsonvisio.com")}
+            status="SECONDARY"
+          >
+            STAR ON GITHUB
+          </StyledButton>
+        </StyledSectionArea>
+      </StyledGitHubSection>
+
+      <StyledSponsorSection id="sponsor">
+        <StyledSubTitle>Sponsors</StyledSubTitle>
+        <StyledMinorTitle>
+          Your supports make JSON Visio possible to continue and accessible for
+          everyone!
+        </StyledMinorTitle>
+        <StyledButton
+          status="SUCCESS"
+          onClick={() => push("https://www.patreon.com/aykutsarac")}
+        >
+          Become A Sponsor!
+        </StyledButton>
+      </StyledSponsorSection>
+
+      <StyledProducthuntSection>
+        <StyledSectionArea>
+          <StyledSubTitle>
+            Support JSON Visio at
+            <br />
+            <StyledHighlightedText>Product Hunt</StyledHighlightedText>
+          </StyledSubTitle>
+        </StyledSectionArea>
+        <Producthunt />
+      </StyledProducthuntSection>
+
+      <StyledFooter>
+        <StyledFooterText>© 2022 JSON Visio - {pkg.version}</StyledFooterText>
+        <StyledIconLinks>
+          <StyledNavLink
+            href="https://github.com/AykutSarac/jsonvisio.com"
+            target="_blank"
+            aria-label="github"
+          >
+            <FaGithub size={26} />
+          </StyledNavLink>
+
+          <StyledNavLink
+            href="https://www.linkedin.com/in/aykutsarac/"
+            target="_blank"
+            aria-label="linkedin"
+          >
+            <FaLinkedin size={26} />
+          </StyledNavLink>
+
+          <StyledNavLink
+            href="https://twitter.com/aykutsarach"
+            target="_blank"
+            aria-label="twitter"
+          >
+            <FaTwitter size={26} />
+          </StyledNavLink>
+        </StyledIconLinks>
+      </StyledFooter>
     </StyledHome>
   );
 };

+ 12 - 0
yarn.lock

@@ -5644,6 +5644,13 @@ react-scrolllock@^5.0.1:
   dependencies:
     exenv "^1.2.2"
 
+react-twitter-embed@^4.0.4:
+  version "4.0.4"
+  resolved "https://registry.yarnpkg.com/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz#4a6b8354acc266876ff1110b9f648518ea20db6d"
+  integrity sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA==
+  dependencies:
+    scriptjs "^2.5.9"
+
 react-use-gesture@^8.0.1:
   version "8.0.1"
   resolved "https://registry.yarnpkg.com/react-use-gesture/-/react-use-gesture-8.0.1.tgz#4360c0f7c9e26baf9fbe58f63fc9de7ef699c17f"
@@ -5945,6 +5952,11 @@ schema-utils@^3.1.1:
     ajv "^6.12.5"
     ajv-keywords "^3.5.2"
 
+scriptjs@^2.5.9:
+  version "2.5.9"
+  resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.9.tgz#343915cd2ec2ed9bfdde2b9875cd28f59394b35f"
+  integrity sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg==
+
 [email protected]:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"