index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. import React from "react";
  2. import Head from "next/head";
  3. import Link from "next/link";
  4. import { useRouter } from "next/router";
  5. import { FaGithub, FaLinkedin, FaTwitter } from "react-icons/fa";
  6. import {
  7. HiCursorClick,
  8. HiLightningBolt,
  9. HiOutlineDownload,
  10. HiOutlineSearchCircle,
  11. } from "react-icons/hi";
  12. import { TwitterTweetEmbed } from "react-twitter-embed";
  13. import { Button } from "src/components/Button";
  14. import { Producthunt } from "src/components/Producthunt";
  15. import { CarbonAds } from "src/components/CarbonAds";
  16. import styled from "styled-components";
  17. import pkg from "../../package.json";
  18. const StyledHome = styled.div`
  19. display: flex;
  20. flex-direction: column;
  21. gap: 8em;
  22. font-family: "Roboto", sans-serif;
  23. * {
  24. box-sizing: border-box;
  25. }
  26. @media only screen and (max-width: 768px) {
  27. gap: 3em;
  28. }
  29. `;
  30. const StyledGradientText = styled.span`
  31. background: #ffb76b;
  32. background: linear-gradient(
  33. to right,
  34. #ffb76b 0%,
  35. #ffa73d 30%,
  36. #ff7c00 60%,
  37. #ff7f04 100%
  38. );
  39. background-clip: text;
  40. -webkit-background-clip: text;
  41. -webkit-text-fill-color: transparent;
  42. `;
  43. const StyledNavbar = styled.nav`
  44. display: flex;
  45. justify-content: center;
  46. align-items: center;
  47. width: 100%;
  48. padding: 16px 16px;
  49. gap: 20px;
  50. @media only screen and (max-width: 768px) {
  51. a:first-of-type {
  52. display: none;
  53. }
  54. }
  55. `;
  56. const StyledHeroSection = styled.section`
  57. display: flex;
  58. flex-direction: column;
  59. justify-content: center;
  60. align-items: center;
  61. gap: 1.5em;
  62. min-height: 45vh;
  63. padding: 0 3%;
  64. `;
  65. const StyledNavLink = styled.a`
  66. display: flex;
  67. justify-content: center;
  68. align-items: center;
  69. font-size: 1rem;
  70. cursor: pointer;
  71. transition: color 0.2s;
  72. &:hover {
  73. font-weight: 500;
  74. color: ${({ theme }) => theme.ORANGE};
  75. }
  76. `;
  77. const StyledTitle = styled.h1`
  78. font-size: 5rem;
  79. font-weight: 900;
  80. margin: 0;
  81. @media only screen and (max-width: 768px) {
  82. font-size: 3rem;
  83. }
  84. `;
  85. const StyledSubTitle = styled.h2`
  86. color: #dedede;
  87. text-align: center;
  88. font-size: 2.5rem;
  89. max-width: 40rem;
  90. margin: 0;
  91. @media only screen and (max-width: 768px) {
  92. font-size: 1.75rem;
  93. }
  94. `;
  95. const StyledMinorTitle = styled.p`
  96. color: #b4b4b4;
  97. text-align: center;
  98. font-size: 1.25rem;
  99. margin: 0;
  100. letter-spacing: 1.2px;
  101. @media only screen and (max-width: 992px) {
  102. font-size: 1rem;
  103. }
  104. `;
  105. const StyledButton = styled(Button)`
  106. background: ${({ status }) => !status && "#a13cc2"};
  107. padding: 12px 24px;
  108. div {
  109. font-family: "Roboto", sans-serif;
  110. font-weight: 700;
  111. font-size: 16px;
  112. }
  113. `;
  114. const StyledFeaturesSection = styled.section`
  115. display: flex;
  116. max-width: 85%;
  117. margin: 0 auto;
  118. gap: 2rem;
  119. padding: 60px 3%;
  120. @media only screen and (max-width: 768px) {
  121. flex-direction: column;
  122. max-width: 80%;
  123. }
  124. `;
  125. const StyledSectionCard = styled.div`
  126. text-align: center;
  127. flex: 1;
  128. `;
  129. const StyledCardTitle = styled.div`
  130. font-weight: 700;
  131. font-size: 1.5rem;
  132. padding: 1.5rem 0 0.5rem;
  133. letter-spacing: 1px;
  134. `;
  135. const StyledCardIcon = styled.div``;
  136. const StyledCardDescription = styled.p`
  137. color: #e0e0e0;
  138. text-align: left;
  139. line-height: 1.5rem;
  140. font-size: 0.875rem;
  141. `;
  142. const StyledGitHubSection = styled.section`
  143. display: flex;
  144. flex-direction: row;
  145. justify-content: space-between;
  146. max-width: 85%;
  147. margin: 0 auto;
  148. gap: 4rem;
  149. line-height: 1.5;
  150. padding: 60px 3%;
  151. & > div {
  152. width: 100%;
  153. }
  154. @media only screen and (max-width: 768px) {
  155. flex-direction: column-reverse;
  156. max-width: 80%;
  157. }
  158. `;
  159. const StyledSectionArea = styled.div`
  160. display: flex;
  161. flex-direction: column;
  162. gap: 2rem;
  163. width: 40%;
  164. margin-top: 3rem;
  165. h2,
  166. p {
  167. text-align: left;
  168. letter-spacing: unset;
  169. }
  170. @media only screen and (max-width: 768px) {
  171. width: 100%;
  172. h2,
  173. p {
  174. text-align: center;
  175. }
  176. button {
  177. align-self: center;
  178. }
  179. }
  180. `;
  181. const StyledSponsorSection = styled.section`
  182. display: flex;
  183. flex-direction: column;
  184. justify-content: center;
  185. align-items: center;
  186. max-width: 85%;
  187. margin: 0 auto;
  188. gap: 2rem;
  189. line-height: 1.5;
  190. padding: 60px 3%;
  191. @media only screen and (max-width: 768px) {
  192. max-width: 80%;
  193. }
  194. `;
  195. const StyledPreviewSection = styled.section`
  196. display: flex;
  197. flex-direction: row;
  198. justify-content: space-between;
  199. max-width: 85%;
  200. margin: 0 auto;
  201. padding: 0 3%;
  202. @media only screen and (max-width: 768px) {
  203. display: none;
  204. max-width: 80%;
  205. }
  206. `;
  207. const StyledImage = styled.img`
  208. max-width: 100%;
  209. filter: drop-shadow(0px 0px 12px rgba(255, 255, 255, 0.6));
  210. `;
  211. const StyledFooter = styled.footer`
  212. display: flex;
  213. flex-direction: row;
  214. justify-content: space-between;
  215. width: 80%;
  216. margin: 0 auto;
  217. padding: 30px 3%;
  218. border-top: 1px solid #b4b4b4;
  219. opacity: 0.7;
  220. `;
  221. const StyledFooterText = styled.p`
  222. color: #b4b4b4;
  223. `;
  224. const StyledIconLinks = styled.div`
  225. display: flex;
  226. gap: 20px;
  227. ${StyledNavLink} {
  228. color: unset;
  229. }
  230. `;
  231. const StyledHighlightedText = styled.span`
  232. text-decoration: underline;
  233. text-decoration-style: dashed;
  234. text-decoration-color: #eab308;
  235. `;
  236. const StyledProducthunt = styled.div`
  237. display: flex;
  238. flex-direction: column;
  239. justify-content: space-between;
  240. align-items: center;
  241. gap: 3rem;
  242. border-right: 1px solid white;
  243. padding-right: 3rem;
  244. @media only screen and (max-width: 768px) {
  245. border-right: none;
  246. border-bottom: 1px solid white;
  247. padding-bottom: 3rem;
  248. padding-right: 0;
  249. }
  250. `;
  251. const StyledPaidSection = styled.section`
  252. display: flex;
  253. max-width: 85%;
  254. margin: 0 auto;
  255. gap: 2rem;
  256. padding: 60px 3%;
  257. @media only screen and (max-width: 768px) {
  258. flex-direction: column;
  259. max-width: 80%;
  260. }
  261. `;
  262. const StyledAffiliate = styled.div`
  263. display: flex;
  264. flex-direction: column;
  265. justify-content: space-between;
  266. align-items: center;
  267. gap: 3rem;
  268. `;
  269. const StyledCarbonWrapper = styled.div`
  270. display: flex;
  271. background: #111827;
  272. border-radius: 5px;
  273. overflow: hidden;
  274. `;
  275. const StyledCarbon = styled.span`
  276. display: flex;
  277. position: relative;
  278. `;
  279. const StyledCarbonAttribute = styled.a`
  280. display: block;
  281. padding: 6px 8px;
  282. text-align: center;
  283. text-transform: uppercase;
  284. letter-spacing: 0.5px;
  285. font-weight: 600;
  286. font-size: 8px;
  287. line-height: 1;
  288. border-top-left-radius: 3px;
  289. position: absolute;
  290. bottom: 0;
  291. right: 0;
  292. `;
  293. const StyledCarbonImage = styled.a`
  294. display: block;
  295. margin: 0;
  296. line-height: 1;
  297. img {
  298. display: block;
  299. }
  300. `;
  301. const StyledCarbonText = styled.a`
  302. font-size: 13px;
  303. padding: 10px;
  304. line-height: 1.5;
  305. text-align: left;
  306. `;
  307. const Home: React.FC = () => {
  308. const { push } = useRouter();
  309. const [isMobile, setIsMobile] = React.useState(false);
  310. React.useEffect(() => {
  311. setIsMobile(window.screen.width <= 768);
  312. }, []);
  313. return (
  314. <StyledHome>
  315. <Head>
  316. <title>JSON Visio - Directly onto graphs</title>
  317. </Head>
  318. <StyledNavbar>
  319. <Link href="/editor" passHref>
  320. <StyledNavLink>Editor</StyledNavLink>
  321. </Link>
  322. <Link href="#features" passHref>
  323. <StyledNavLink>Features</StyledNavLink>
  324. </Link>
  325. <Link href="#sponsor" passHref>
  326. <StyledNavLink>Sponsor</StyledNavLink>
  327. </Link>
  328. <StyledNavLink
  329. href="https://github.com/AykutSarac/jsonvisio.com"
  330. target="_blank"
  331. rel="external"
  332. >
  333. GitHub
  334. </StyledNavLink>
  335. </StyledNavbar>
  336. <StyledHeroSection id="main">
  337. <StyledTitle>
  338. <StyledGradientText>JSON</StyledGradientText> Visio
  339. </StyledTitle>
  340. <StyledSubTitle>
  341. Seamlessly visualize your JSON data{" "}
  342. <StyledHighlightedText>instantly</StyledHighlightedText> into graphs.
  343. </StyledSubTitle>
  344. <StyledMinorTitle>Paste - Import - Fetch!</StyledMinorTitle>
  345. <StyledButton onClick={() => push("/editor")} disabled={isMobile}>
  346. {isMobile ? "Incompatible Device" : "GO TO EDITOR"}
  347. </StyledButton>
  348. </StyledHeroSection>
  349. <StyledPreviewSection>
  350. <StyledImage
  351. width="1200"
  352. height="auto"
  353. src="/jsonvisio-screenshot.png"
  354. alt="preview"
  355. />
  356. </StyledPreviewSection>
  357. <StyledFeaturesSection id="features">
  358. <StyledSectionCard>
  359. <StyledCardIcon>
  360. <HiCursorClick size={50} color="#3BA55D" />
  361. </StyledCardIcon>
  362. <StyledCardTitle>EASY-TO-USE</StyledCardTitle>
  363. <StyledCardDescription>
  364. Don&apos;t even bother to update your schema to view your JSON into
  365. graphs; directly paste, import or fetch! JSON Visio helps you to
  366. visualize without any additional values and save your time.
  367. </StyledCardDescription>
  368. </StyledSectionCard>
  369. <StyledSectionCard>
  370. <StyledCardIcon>
  371. <HiOutlineSearchCircle size={50} color="#5865F2" />
  372. </StyledCardIcon>
  373. <StyledCardTitle>SEARCH</StyledCardTitle>
  374. <StyledCardDescription>
  375. Have a huge file of values, keys or arrays? Worry no more, type in
  376. the keyword you are looking for into search input and it will take
  377. you to each node with matching result highlighting the line to
  378. understand better!
  379. </StyledCardDescription>
  380. </StyledSectionCard>
  381. <StyledSectionCard>
  382. <StyledCardIcon>
  383. <HiOutlineDownload size={50} color="#DA2877" />
  384. </StyledCardIcon>
  385. <StyledCardTitle>DOWNLOAD</StyledCardTitle>
  386. <StyledCardDescription>
  387. Download the graph to your local machine and use it wherever you
  388. want, to your blogs, website or make it a poster and paste to the
  389. wall. Who wouldn&apos;t want to see a JSON Visio graph onto their
  390. wall, eh?
  391. </StyledCardDescription>
  392. </StyledSectionCard>
  393. <StyledSectionCard>
  394. <StyledCardIcon>
  395. <HiLightningBolt size={50} color="#F5E027" />
  396. </StyledCardIcon>
  397. <StyledCardTitle>LIVE</StyledCardTitle>
  398. <StyledCardDescription>
  399. With Microsoft&apos;s Monaco Editor which is also used by VS Code,
  400. easily edit your JSON and directly view through the graphs. Also
  401. there&apos;s a JSON validator above of it to make sure there is no
  402. type error.
  403. </StyledCardDescription>
  404. </StyledSectionCard>
  405. </StyledFeaturesSection>
  406. <StyledGitHubSection id="github">
  407. <TwitterTweetEmbed
  408. tweetId="1519363257794015233"
  409. options={{
  410. width: "600",
  411. align: "center",
  412. }}
  413. />
  414. <StyledSectionArea>
  415. <StyledSubTitle>Open Source Community</StyledSubTitle>
  416. <StyledMinorTitle>
  417. Join the Open Source Community by suggesting new ideas, support by
  418. contributing; implementing new features, fixing bugs and doing
  419. changes minor to major!
  420. </StyledMinorTitle>
  421. <StyledButton
  422. onClick={() => push("https://github.com/AykutSarac/jsonvisio.com")}
  423. status="SECONDARY"
  424. >
  425. STAR ON GITHUB
  426. </StyledButton>
  427. </StyledSectionArea>
  428. </StyledGitHubSection>
  429. <StyledPaidSection>
  430. <StyledProducthunt>
  431. <StyledSubTitle>
  432. Support JSON Visio at
  433. <br />
  434. <StyledHighlightedText>Product Hunt</StyledHighlightedText>
  435. </StyledSubTitle>
  436. <Producthunt />
  437. </StyledProducthunt>
  438. <StyledAffiliate>
  439. <StyledSubTitle>Affiliate</StyledSubTitle>
  440. <CarbonAds />
  441. </StyledAffiliate>
  442. </StyledPaidSection>
  443. <StyledSponsorSection id="sponsor">
  444. <StyledSubTitle>Sponsors</StyledSubTitle>
  445. <StyledMinorTitle>
  446. Your supports make JSON Visio possible to continue and accessible for
  447. everyone!
  448. </StyledMinorTitle>
  449. <StyledButton
  450. status="SUCCESS"
  451. onClick={() => push("https://www.patreon.com/aykutsarac")}
  452. >
  453. Become A Sponsor!
  454. </StyledButton>
  455. </StyledSponsorSection>
  456. <StyledFooter>
  457. <StyledFooterText>© 2022 JSON Visio - {pkg.version}</StyledFooterText>
  458. <StyledIconLinks>
  459. <StyledNavLink
  460. href="https://github.com/AykutSarac/jsonvisio.com"
  461. target="_blank"
  462. aria-label="github"
  463. >
  464. <FaGithub size={26} />
  465. </StyledNavLink>
  466. <StyledNavLink
  467. href="https://www.linkedin.com/in/aykutsarac/"
  468. target="_blank"
  469. aria-label="linkedin"
  470. >
  471. <FaLinkedin size={26} />
  472. </StyledNavLink>
  473. <StyledNavLink
  474. href="https://twitter.com/aykutsarach"
  475. target="_blank"
  476. aria-label="twitter"
  477. >
  478. <FaTwitter size={26} />
  479. </StyledNavLink>
  480. </StyledIconLinks>
  481. </StyledFooter>
  482. </StyledHome>
  483. );
  484. };
  485. export default Home;