diff --git a/client/src/components/Auth/AuthForm.tsx b/client/src/components/Auth/AuthForm.tsx new file mode 100644 index 0000000..cb4aec1 --- /dev/null +++ b/client/src/components/Auth/AuthForm.tsx @@ -0,0 +1,88 @@ +import { ChangeEvent, FormEvent, useState, useContext, Fragment } from 'react'; +import { AuthContext } from '../../store'; +import { Button } from '../UI'; + +export const AuthForm = (): JSX.Element => { + const [isInLogin, setIsInLogin] = useState(true); + const [formData, setFormData] = useState({ email: '', password: '' }); + const { login } = useContext(AuthContext); + + const inputHandler = (e: ChangeEvent) => { + const { name, value } = e.target; + setFormData({ + ...formData, + [name]: value + }); + }; + + const formHandler = (e: FormEvent) => { + e.preventDefault(); + + if (isInLogin) { + login(formData); + } else { + // register + } + }; + + return ( + +
{isInLogin ? 'Login' : 'Register'}
+

+ {isInLogin ? "Don't have an account yet?" : 'Already a user?'} + setIsInLogin(!isInLogin)} + className='text-success cursor-pointer' + > + {isInLogin ? ' Sign Up' : ' Login'} + +

+
+ +
formHandler(e)}> +
+ + inputHandler(e)} + /> +
+
+ + inputHandler(e)} + /> +
+ +
+
+
+
+
+ ); +}; diff --git a/client/src/components/Auth/index.ts b/client/src/components/Auth/index.ts new file mode 100644 index 0000000..5787d43 --- /dev/null +++ b/client/src/components/Auth/index.ts @@ -0,0 +1 @@ +export * from './AuthForm'; diff --git a/client/src/components/Navigation/routes.json b/client/src/components/Navigation/routes.json index b07cf9d..f706f3f 100644 --- a/client/src/components/Navigation/routes.json +++ b/client/src/components/Navigation/routes.json @@ -14,6 +14,11 @@ "name": "Editor", "dest": "/editor", "isPublic": false + }, + { + "name": "Auth", + "dest": "/auth", + "isPublic": true } ] } diff --git a/client/src/containers/Auth.tsx b/client/src/containers/Auth.tsx new file mode 100644 index 0000000..83f3dd5 --- /dev/null +++ b/client/src/containers/Auth.tsx @@ -0,0 +1,14 @@ +import { AuthForm } from '../components/Auth'; +import { Card, Layout } from '../components/UI'; + +export const Auth = (): JSX.Element => { + return ( + +
+ + + +
+
+ ); +}; diff --git a/client/src/containers/index.ts b/client/src/containers/index.ts index 71b0f1d..360027b 100644 --- a/client/src/containers/index.ts +++ b/client/src/containers/index.ts @@ -2,3 +2,4 @@ export * from './Home'; export * from './Snippet'; export * from './Snippets'; export * from './Editor'; +export * from './Auth'; diff --git a/client/src/store/AuthContext.tsx b/client/src/store/AuthContext.tsx index 7316c1c..04ca979 100644 --- a/client/src/store/AuthContext.tsx +++ b/client/src/store/AuthContext.tsx @@ -1,6 +1,8 @@ -import { useState, createContext, ReactNode } from 'react'; +import axios from 'axios'; +import { createContext, ReactNode } from 'react'; -import { AuthContext as Context } from '../typescript/interfaces'; +import { AuthContext as Context, Response } from '../typescript/interfaces'; +import { errorHandler } from '../utils'; export const AuthContext = createContext({ isAuthenticated: false, @@ -13,7 +15,19 @@ interface Props { export const AuthContextProvider = (props: Props): JSX.Element => { const login = async (formData: { email: string; password: string }) => { - console.table(formData); + try { + const res = await axios.post>( + '/api/auth/login', + formData + ); + + localStorage.setItem('token', res.data.data.token); + + // get profile + // redirect to snippets? / home? + } catch (err) { + errorHandler(err); + } }; const context: Context = { diff --git a/client/src/typescript/interfaces/User.ts b/client/src/typescript/interfaces/User.ts new file mode 100644 index 0000000..b6a1093 --- /dev/null +++ b/client/src/typescript/interfaces/User.ts @@ -0,0 +1,5 @@ +import { Model } from '.'; + +export interface User extends Model { + email: string; +} diff --git a/client/src/typescript/interfaces/index.ts b/client/src/typescript/interfaces/index.ts index 991b300..e6a6608 100644 --- a/client/src/typescript/interfaces/index.ts +++ b/client/src/typescript/interfaces/index.ts @@ -5,3 +5,4 @@ export * from './Response'; export * from './Context'; export * from './Statistics'; export * from './SearchQuery'; +export * from './User'; diff --git a/client/src/utils/errorHandler.ts b/client/src/utils/errorHandler.ts new file mode 100644 index 0000000..98a1159 --- /dev/null +++ b/client/src/utils/errorHandler.ts @@ -0,0 +1,15 @@ +import { AxiosError } from 'axios'; + +export const errorHandler = (err: any) => { + const error = err as AxiosError<{ error: string }>; + + let msg: string; + + if (error.response) { + msg = error.response.data.error; + } else { + msg = 'Something went wrong'; + } + + console.log(msg); +}; diff --git a/client/src/utils/index.ts b/client/src/utils/index.ts index 60912ec..9327a09 100644 --- a/client/src/utils/index.ts +++ b/client/src/utils/index.ts @@ -3,3 +3,4 @@ export * from './badgeColor'; export * from './findLanguage'; export * from './searchParser'; export * from './ProtectedRoute'; +export * from './errorHandler';