From 46389bad329986d985c5abf8cf8bdc1be69fae1f Mon Sep 17 00:00:00 2001 From: Dm1tr1y147 <me@dmitriy.icu> Date: Wed, 14 Oct 2020 11:21:24 +0500 Subject: [PATCH] Added login and authorize routes and components, added basic UserPage component and query --- package.json | 1 + src/apollo/{queries.ts => defs.ts} | 12 +++++- src/apollo/index.ts | 3 +- src/components/App.tsx | 56 ++++++++++++++------------ src/components/Authorize/index.tsx | 15 +++++++ src/components/Login/index.tsx | 35 ++++++++++++++++ src/components/TextComponent/index.tsx | 7 ++++ src/components/UserPage/index.tsx | 22 ++++++++++ src/hooks.ts | 5 +++ 9 files changed, 127 insertions(+), 29 deletions(-) rename src/apollo/{queries.ts => defs.ts} (67%) create mode 100644 src/components/Authorize/index.tsx create mode 100644 src/components/Login/index.tsx create mode 100644 src/components/TextComponent/index.tsx create mode 100644 src/components/UserPage/index.tsx diff --git a/package.json b/package.json index 409fc11..e645900 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@types/react": "^16.9.0", "@types/react-dom": "^16.9.0", "@types/react-router-dom": "^5.1.6", + "@types/validator": "^13.1.0", "graphql": "^15.3.0", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/src/apollo/queries.ts b/src/apollo/defs.ts similarity index 67% rename from src/apollo/queries.ts rename to src/apollo/defs.ts index f360e2b..0d05073 100644 --- a/src/apollo/queries.ts +++ b/src/apollo/defs.ts @@ -17,4 +17,14 @@ const FORM = gql` } ` -export { LOGIN, FORM } +const USER = gql` + query User { + user { + email + id + name + } + } +` + +export { LOGIN, FORM, USER } diff --git a/src/apollo/index.ts b/src/apollo/index.ts index fe62862..3343847 100644 --- a/src/apollo/index.ts +++ b/src/apollo/index.ts @@ -2,7 +2,7 @@ import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client' import { setContext } from '@apollo/client/link/context' -import { LOGIN } from './queries' +export * from './defs' const httpLink = createHttpLink({ uri: process.env.GRAPHQL_URL || process.env.REACT_APP_GRAPHQL_URL || undefined @@ -28,4 +28,3 @@ const client = new ApolloClient({ }) export default client -export { LOGIN } diff --git a/src/components/App.tsx b/src/components/App.tsx index c958fe3..a39064a 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,38 +1,40 @@ -import { ApolloProvider, useMutation, useQuery } from '@apollo/client' -import React, { useContext } from 'react' +import { ApolloProvider } from '@apollo/client' +import React from 'react' import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' import client from '../apollo' -import { FORM, LOGIN } from '../apollo/queries' import Context from '../context' import { useUser } from '../hooks' +import Authorize from './Authorize' +import Login from './Login' +import UserPage from './UserPage' -const TestComponent: React.FC = () => { - const { loading, error, data } = useQuery(FORM, { - variables: { - id: 1 - } - }) +// const TestComponent: React.FC = () => { +// const { loading, error, data } = useQuery(FORM, { +// variables: { +// id: 1 +// } +// }) - const { user } = useContext(Context) +// const { user } = useContext(Context) - const [doLogin] = useMutation(LOGIN) +// const [doLogin] = useMutation(LOGIN) - if (loading) return <p>Loading...</p> - if (error) return <p>Error :(</p> +// if (loading) return <p>Loading...</p> +// if (error) return <p>Error :(</p> - return ( - <div> - <button - onClick={() => doLogin({ variables: { email: 'test@test.test' } })} - > - Click! - </button> - {user.id} - {data.form.id} - </div> - ) -} +// return ( +// <div> +// <button +// onClick={() => doLogin({ variables: { email: 'test@test.test' } })} +// > +// Click! +// </button> +// {user.id} +// {data.form.id} +// </div> +// ) +// } const App: React.FC = () => { const userContext = useUser() @@ -43,7 +45,9 @@ const App: React.FC = () => { <Context.Provider value={userContext}> <Router> <Switch> - <Route path="/" component={TestComponent} /> + <Route path="/login" component={Login} /> + <Route path="/authorize" component={Authorize} /> + <Route path="/user" component={UserPage} /> </Switch> </Router> </Context.Provider> diff --git a/src/components/Authorize/index.tsx b/src/components/Authorize/index.tsx new file mode 100644 index 0000000..dcd920f --- /dev/null +++ b/src/components/Authorize/index.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import { Redirect } from 'react-router-dom' +import { useURLQuery } from '../../hooks' + +const Authorize: React.FC = () => { + const query = useURLQuery() + + const token = query.get('token') + + if (token) localStorage.setItem('token', token) + + return <Redirect to="/" /> +} + +export default Authorize diff --git a/src/components/Login/index.tsx b/src/components/Login/index.tsx new file mode 100644 index 0000000..d2ac539 --- /dev/null +++ b/src/components/Login/index.tsx @@ -0,0 +1,35 @@ +import { useMutation } from '@apollo/client' +import React, { ChangeEvent, FormEvent, useState } from 'react' +import { Redirect } from 'react-router-dom' + +import { LOGIN } from '../../apollo' + +const Login: React.FC = () => { + const [email, setEmail] = useState<string>('') + + const [doLogin, { error, data }] = useMutation(LOGIN) + + const handleFormSubmit = async (e: FormEvent) => { + e.preventDefault() + try { + await doLogin({ variables: { email } }) + } catch (err) {} + } + + const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => { + setEmail(e.currentTarget.value) + } + + return ( + <div> + <form onSubmit={handleFormSubmit}> + <input type="text" onChange={handleInputChange} /> + <input type="submit" value="Login" /> + </form> + {error && error.message} + {data && data.login && data.login.success && <Redirect to="/" />} + </div> + ) +} + +export default Login diff --git a/src/components/TextComponent/index.tsx b/src/components/TextComponent/index.tsx new file mode 100644 index 0000000..d0b8455 --- /dev/null +++ b/src/components/TextComponent/index.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +const TextComponent: React.FC<{ text: string }> = (text) => { + return <div>{text}</div> +} + +export default TextComponent diff --git a/src/components/UserPage/index.tsx b/src/components/UserPage/index.tsx new file mode 100644 index 0000000..2a62f60 --- /dev/null +++ b/src/components/UserPage/index.tsx @@ -0,0 +1,22 @@ +import { useQuery } from '@apollo/client' +import React from 'react' +import { USER } from '../../apollo' + +const UserPage: React.FC = () => { + const { data, error, loading } = useQuery(USER) + if (loading) return <p>Loading...</p> + + if (error) return <p>{error.message}</p> + + console.log(Object.entries(data.user)) + + const user = Object.entries(data.user).map((el, index) => ( + <li key={index}> + {el[0]}: {el[1]} + </li> + )) + + return <ul>{user}</ul> +} + +export default UserPage diff --git a/src/hooks.ts b/src/hooks.ts index 444f78c..0f85206 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react' +import { useLocation } from 'react-router-dom' import { ContextType, initialUser, UserType } from './context' export const useUser = (): ContextType => { @@ -10,3 +11,7 @@ export const useUser = (): ContextType => { return { user, setUser } } + +export const useURLQuery = () => { + return new URLSearchParams(useLocation().search) +}