diff --git a/packages/frontend/src/contexts/auth.js b/packages/frontend/src/contexts/auth.js new file mode 100644 index 0000000..7badd1d --- /dev/null +++ b/packages/frontend/src/contexts/auth.js @@ -0,0 +1,51 @@ +import { createContext } from 'react' +import { makeAutoObservable } from 'mobx' + +import { SERVER } from '../config' + +export default class Auth { + constructor() { + makeAutoObservable(this) + } + + async join(platform) { + console.log('join through', platform) + + // authorization through relay + const currentUrl = new URL(window.location.href) + const dest = new URL('/join', currentUrl.origin) + + if (platform === 'twitter') { + const url = new URL('/api/oauth/twitter', SERVER) + url.searchParams.set('redirectDestination', dest.toString()) + url.searchParams.set('isSigningUp', true) + window.location.replace(url.toString()) + } + if (platform === 'github') { + const url = new URL('/api/oauth/github', SERVER) + url.searchParams.set('redirectDestination', dest.toString()) + url.searchParams.set('isSigningUp', true) + window.location.replace(url.toString()) + } + } + + async signInWithGithub() { + try { + const res = await fetch('/api/auth/github') + const { url } = await res.json() + window.location.replace(url) + } catch (error) { + console.error(error) + } + } + + async signInWithTwitter() { + try { + const res = await fetch('/api/auth/twitter') + const { url } = await res.json() + window.location.replace(url) + } catch (error) { + console.error(error) + } + } +} diff --git a/packages/frontend/src/contexts/state.js b/packages/frontend/src/contexts/state.js index 33bd4d5..ab01734 100644 --- a/packages/frontend/src/contexts/state.js +++ b/packages/frontend/src/contexts/state.js @@ -2,15 +2,18 @@ import { createContext } from 'react' import Interface from './interface' import User from './User' import Address from './address' +import Auth from './auth' const state = {} const address = new Address(state) +const auth = new Auth(state) const ui = new Interface(state) const user = new User(state) Object.assign(state, { address, + auth, ui, user, }) diff --git a/packages/frontend/src/index.jsx b/packages/frontend/src/index.jsx index 91f995c..4191dc8 100644 --- a/packages/frontend/src/index.jsx +++ b/packages/frontend/src/index.jsx @@ -4,6 +4,7 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom' import Header from './pages/Header' import Start from './pages/Start' import Address from './pages/Address' +import Auth from './pages/Auth' import './index.css' export default function App() { @@ -11,7 +12,8 @@ export default function App() { }> - } /> + } /> + } /> } /> diff --git a/packages/frontend/src/pages/Auth.jsx b/packages/frontend/src/pages/Auth.jsx new file mode 100644 index 0000000..fb5626d --- /dev/null +++ b/packages/frontend/src/pages/Auth.jsx @@ -0,0 +1,111 @@ +import React, { useEffect, useState, useContext } from 'react' +import { observer } from 'mobx-react-lite' +import { Link, useNavigate, useSearchParams } from 'react-router-dom' +import Button from '../components/Button' + +import state from '../contexts/state' + +export default observer(() => { + const navigate = useNavigate() + const [params, setParams] = useSearchParams() + + const { auth, user } = useContext(state) + + const [isLoading, setIsLoading] = useState(false) + const [errorMsg, setErrorMsg] = useState('') + const [idInput, setIdInput] = useState('') + + const signup = async (platform, access_token) => { + setErrorMsg('') + setIsLoading(true) + try { + await user.signup(platform, access_token) + await user.getRep(platform) + return navigate('/user') + } catch (e) { + setErrorMsg(e.toString()) + setIsLoading(false) + } + } + + useEffect(() => { + const platform = params.get('platform') + const access_token = params.get('access_token') + const signupError = params.get('signupError') + const isSigningUp = params.get('isSigningUp') + if (platform && access_token) { + if (isSigningUp && parseInt(isSigningUp)) { + signup(platform, access_token) + } else { + user.storeAccessToken(platform, access_token) + } + } else if (signupError) { + setErrorMsg( + `Sign up through ${platform.toUpperCase()} error: ${signupError}` + ) + } + setParams('') + }, []) + + const login = async () => { + try { + await user.login(idInput) + return navigate('/user') + } catch (e) { + setErrorMsg(e.toString()) + } + } + + const onIdInputChange = (event) => { + setIdInput(event.target.value) + } + + return ( + <> + {isLoading ? ( +
+ + Any question? +
+ ) : ( +
+ {errorMsg.length > 0 && ( + + )} + + + +
Already has account?
+
+ )} + + ) +}) + +{ + /*
+