AykutSarac 2 vuotta sitten
vanhempi
commit
f37325aad1

+ 60 - 0
src/components/Navbar/index.tsx

@@ -0,0 +1,60 @@
+import React from "react";
+import Link from "next/link";
+import styled from "styled-components";
+
+const StyledNavbar = styled.div`
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  gap: 20px;
+  padding: 16px 48px;
+
+  @media only screen and (max-width: 768px) {
+    a:first-of-type {
+      display: none;
+    }
+  }
+`;
+
+const StyledLinkWrapper = styled.nav`
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 20px;
+`;
+
+const StyledNavLink = styled(Link)`
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 1rem;
+  cursor: pointer;
+  transition: color 0.2s;
+
+  &:hover {
+    font-weight: 500;
+    color: ${({ theme }) => theme.ORANGE};
+  }
+`;
+
+export const Navbar = () => (
+  <StyledNavbar>
+    <Link href="/">
+      <img src="assets/icon.png" alt="json crack" width="120" />
+    </Link>
+    <StyledLinkWrapper>
+      <StyledNavLink href="https://pro.jsoncrack.com">Pro</StyledNavLink>
+      <StyledNavLink href="/editor">Editor</StyledNavLink>
+      <StyledNavLink href="#features">Features</StyledNavLink>
+      <StyledNavLink href="#sponsor">Sponsor</StyledNavLink>
+      <StyledNavLink
+        href="https://github.com/AykutSarac/jsoncrack.com"
+        target="_blank"
+        rel="external"
+      >
+        GitHub
+      </StyledNavLink>
+      <StyledNavLink href="docs">Documentation</StyledNavLink>
+    </StyledLinkWrapper>
+  </StyledNavbar>
+);

+ 1 - 16
src/containers/Home/index.tsx

@@ -14,6 +14,7 @@ import { SiVisualstudiocode } from "react-icons/si";
 import vscDarkPlus from "react-syntax-highlighter/dist/cjs/styles/prism/vsc-dark-plus";
 import vscDarkPlus from "react-syntax-highlighter/dist/cjs/styles/prism/vsc-dark-plus";
 import { CarbonAds } from "src/components/CarbonAds";
 import { CarbonAds } from "src/components/CarbonAds";
 import { Footer } from "src/components/Footer";
 import { Footer } from "src/components/Footer";
+import { Navbar } from "src/components/Navbar";
 import { Producthunt } from "src/components/Producthunt";
 import { Producthunt } from "src/components/Producthunt";
 import { Sponsors } from "src/components/Sponsors";
 import { Sponsors } from "src/components/Sponsors";
 import { SupportButton } from "src/components/SupportButton";
 import { SupportButton } from "src/components/SupportButton";
@@ -26,22 +27,6 @@ const SyntaxHighlighter = dynamic(() => import("react-syntax-highlighter/dist/cj
   ssr: false,
   ssr: false,
 });
 });
 
 
-const Navbar = () => (
-  <Styles.StyledNavbar>
-    <Styles.StyledNavLink href="/editor">Editor</Styles.StyledNavLink>
-    <Styles.StyledNavLink href="#features">Features</Styles.StyledNavLink>
-    <Styles.StyledNavLink href="#sponsor">Sponsor</Styles.StyledNavLink>
-    <Styles.StyledNavLink
-      href="https://github.com/AykutSarac/jsoncrack.com"
-      target="_blank"
-      rel="external"
-    >
-      GitHub
-    </Styles.StyledNavLink>
-    <Styles.StyledNavLink href="docs">Documentation</Styles.StyledNavLink>
-  </Styles.StyledNavbar>
-);
-
 const HeroSection = () => (
 const HeroSection = () => (
   <Styles.StyledHeroSection id="main">
   <Styles.StyledHeroSection id="main">
     <Styles.StyledTitle>
     <Styles.StyledTitle>

+ 8 - 7
src/containers/Modals/LoginModal/index.tsx

@@ -1,12 +1,14 @@
 import React from "react";
 import React from "react";
-import { AiOutlineGoogle } from "react-icons/ai";
-import { altogic } from "src/api/altogic";
+import { useRouter } from "next/router";
 import { Button } from "src/components/Button";
 import { Button } from "src/components/Button";
 import { Modal, ModalProps } from "src/components/Modal";
 import { Modal, ModalProps } from "src/components/Modal";
 
 
 export const LoginModal: React.FC<ModalProps> = ({ setVisible, visible }) => {
 export const LoginModal: React.FC<ModalProps> = ({ setVisible, visible }) => {
-  const handleLoginClick = () => {
-    altogic.auth.signInWithProvider("google");
+  const { replace } = useRouter();
+
+  const onSignIn = () => {
+    replace("/sign-in");
+    setVisible(false);
   };
   };
 
 
   return (
   return (
@@ -15,9 +17,8 @@ export const LoginModal: React.FC<ModalProps> = ({ setVisible, visible }) => {
       <Modal.Content>
       <Modal.Content>
         <h2>Welcome Back!</h2>
         <h2>Welcome Back!</h2>
         <p>Login to unlock full potential of JSON Crack!</p>
         <p>Login to unlock full potential of JSON Crack!</p>
-        <Button onClick={handleLoginClick} status="SECONDARY" block>
-          <AiOutlineGoogle size={24} />
-          Login with Google
+        <Button onClick={onSignIn} status="SECONDARY" block>
+          Sign In
         </Button>
         </Button>
       </Modal.Content>
       </Modal.Content>
       <Modal.Controls setVisible={setVisible} />
       <Modal.Controls setVisible={setVisible} />

+ 72 - 0
src/pages/sign-in.tsx

@@ -0,0 +1,72 @@
+import React from "react";
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { AiOutlineGithub, AiOutlineGoogle } from "react-icons/ai";
+import { altogic } from "src/api/altogic";
+import { Button } from "src/components/Button";
+import { Footer } from "src/components/Footer";
+import { Navbar } from "src/components/Navbar";
+import useUser from "src/store/useUser";
+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 StyledLoginButtons = styled.div`
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  margin-top: 60px;
+  gap: 24px;
+`;
+
+const SignIn = () => {
+  const { isReady, replace } = useRouter();
+  const tokenAuth = useUser(state => state.tokenAuth);
+  const isAuthenticated = useUser(state => state.isAuthenticated);
+
+  React.useEffect(() => {
+    if (isReady) tokenAuth();
+    if (isAuthenticated) replace("/editor");
+  }, [tokenAuth, isReady]);
+
+  const handleLoginClick = (provider: "github" | "google") => {
+    altogic.auth.signInWithProvider(provider);
+  };
+
+  return (
+    <>
+      <Navbar />
+      <StyledPageWrapper>
+        <StyledHeroSection>
+          <Link href="/">
+            <img src="assets/icon.png" alt="json crack" width="400" />
+          </Link>
+          <h1>Sign In</h1>
+        </StyledHeroSection>
+        <StyledLoginButtons>
+          <Button status="DANGER" onClick={() => handleLoginClick("google")}>
+            <AiOutlineGoogle size={24} />
+            Sign In with Google
+          </Button>
+          <Button status="TERTIARY" onClick={() => handleLoginClick("github")}>
+            <AiOutlineGithub size={24} />
+            Sign In with GitHub
+          </Button>
+        </StyledLoginButtons>
+      </StyledPageWrapper>
+      <Footer />
+    </>
+  );
+};
+
+export default SignIn;

+ 12 - 0
src/store/useUser.tsx

@@ -10,6 +10,7 @@ interface UserActions {
   setUser: (key: keyof typeof initialStates, value: any) => void;
   setUser: (key: keyof typeof initialStates, value: any) => void;
   checkSession: () => void;
   checkSession: () => void;
   isPremium: () => boolean;
   isPremium: () => boolean;
+  tokenAuth: () => Promise<void>;
 }
 }
 
 
 const initialStates = {
 const initialStates = {
@@ -37,6 +38,17 @@ const useUser = create<UserStates & UserActions>()((set, get) => ({
   login: response => {
   login: response => {
     set({ user: response.user as any, isAuthenticated: true });
     set({ user: response.user as any, isAuthenticated: true });
   },
   },
+  tokenAuth: async () => {
+    if (new URLSearchParams(window.location.search).get("access_token")) {
+      const data = await altogic.auth.getAuthGrant();
+
+      if ((data.user as any)?.type > 0) {
+        location.replace(location.href.replace("://", "://pro."));
+      } else {
+        location.pathname = "/editor";
+      }
+    }
+  },
   checkSession: async () => {
   checkSession: async () => {
     const currentSession = altogic.auth.getSession();
     const currentSession = altogic.auth.getSession();