diff --git a/.env.example b/.env.example index a75fdf9..b3e29c7 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,7 @@ NODE_ENV=development # in production this will be the full url # but in dev it is the name of the database -DATABASE_URL=neststarterappdevelopement \ No newline at end of file +DATABASE_URL=neststarterappdevelopement + +# recommend using randomkeygen.com to generate a key +ENCRYPTION_KEY=yourencryptionkey \ No newline at end of file diff --git a/client/app.jsx b/client/app.jsx index 5ae62df..6414fad 100644 --- a/client/app.jsx +++ b/client/app.jsx @@ -1,10 +1,25 @@ -import { BrowserRouter } from 'react-router-dom'; +import { useReducer } from 'react'; +import { HashRouter } from 'react-router-dom'; import { Router } from './components/router'; +import { SettingsContext } from './utils/settings_context'; + +const settingsReducer = (state, action) => { + switch (action.type) { + case 'update': { + return { ...state, ...action.payload }; + } + } + return state; +}; export const App = () => { + const [settings, dispatch] = useReducer(settingsReducer, window.SETTINGS); + return ( - - - + + + + + ); }; diff --git a/client/components/router.jsx b/client/components/router.jsx index a40b06e..6760bea 100644 --- a/client/components/router.jsx +++ b/client/components/router.jsx @@ -1,10 +1,21 @@ -import { Routes, Route } from 'react-router-dom'; +import { useContext } from 'react'; +import { Routes, Route, Navigate } from 'react-router-dom'; import { Home } from './home/_home'; +import { SettingsContext } from '../utils/settings_context'; +import { SignIn } from './sign_in/_sign_in'; +import { SignUp } from './sign_up/_sign_up'; export const Router = () => { + const [settings] = useContext(SettingsContext); + const { JWT } = settings; return ( - } /> + : } // no JWT means not logged in + /> + } /> + } /> ); }; diff --git a/client/components/sign_in/_sign_in.jsx b/client/components/sign_in/_sign_in.jsx index 099ecd6..753b2b5 100644 --- a/client/components/sign_in/_sign_in.jsx +++ b/client/components/sign_in/_sign_in.jsx @@ -1,3 +1,37 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router'; + export const SignIn = () => { - return
I am the sign in page
; + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const navigate = useNavigate(); + + const goToSignUp = () => { + navigate('/signup'); + }; + + return ( +
+
Email
+ setEmail(e.target.value)} + /> +
Password
+ setPassword(e.target.value)} + /> +
+ +
+
+ +
+
+ ); }; diff --git a/client/components/sign_up/_sign_up.jsx b/client/components/sign_up/_sign_up.jsx new file mode 100644 index 0000000..bbbd51b --- /dev/null +++ b/client/components/sign_up/_sign_up.jsx @@ -0,0 +1,86 @@ +import { useState } from 'react'; + +export const SignUp = () => { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [emailConfirmation, setEmailConfirmation] = useState(''); + const [password, setPassword] = useState(''); + const [passwordConfiramation, setPasswordConfirmation] = useState(''); + const [errorMessage, setErrorMessage] = useState(''); + + const signUp = async () => { + if (email === '') { + setErrorMessage('Email cannot be blank'); + return; + } + if (email !== emailConfirmation) { + setErrorMessage('Email does not match.'); + return; + } + if (password === '') { + setErrorMessage('Password cannot be blank'); + return; + } + if (password !== passwordConfiramation) { + setErrorMessage('Password does not match'); + return; + } + if (name === '') { + setErrorMessage('Name cannot be blank.'); + return; + } + try { + await fetch('/users', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name, + email, + password, + }), + }); + } catch (e) { + console.log(e.message); + } + }; + + return ( +
+
Name
+ setName(e.target.value)} + /> +
Email
+ setEmail(e.target.value)} + /> +
Confirm Email
+ setEmailConfirmation(e.target.value)} + /> +
Password
+ setPassword(e.target.value)} + /> +
Confirm Password
+ setPasswordConfirmation(e.target.value)} + /> +
+ +
+
+ ); +}; diff --git a/client/utils/settings_context.js b/client/utils/settings_context.js new file mode 100644 index 0000000..6c088b2 --- /dev/null +++ b/client/utils/settings_context.js @@ -0,0 +1,3 @@ +import { createContext } from 'react'; + +export const SettingsContext = createContext({}); diff --git a/server/controllers/users.controller.ts b/server/controllers/users.controller.ts index 773b110..120a2b3 100644 --- a/server/controllers/users.controller.ts +++ b/server/controllers/users.controller.ts @@ -6,7 +6,7 @@ import { Post, Res, } from '@nestjs/common'; -import bcrypt from 'bcrypt'; +import * as bcrypt from 'bcrypt'; import { Response } from 'express'; import * as jwt from 'jsonwebtoken'; import { CreateUserDto } from 'server/dto/create_user.dto'; diff --git a/server/providers/services/users.service.ts b/server/providers/services/users.service.ts index 5a2a1fb..0f502b2 100644 --- a/server/providers/services/users.service.ts +++ b/server/providers/services/users.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import bcrypt from 'bcrypt'; +import * as bcrypt from 'bcrypt'; import { User } from '../../entities/user.entity'; @Injectable()