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()