diff --git a/README.md b/README.md
index dfa05e177..5545418c3 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
# Project Auth API
-Replace this readme with your own information about your project.
-
-Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
+This project was about buildig a registration form. The user should be able to sign up and then sign in with the credentials. Once signed in the user should see something that would be accessable if not logged in. This fullstack project was built in a group of three people.
+We started by setting up the backend and then the frontend.
## The problem
-Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
+We were having some issues with setting the frontend functionallity up since we wanted to have it pretty dry in the beginning but then in the end saw that this is making things even harder.
## View it live
-Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
+Backend: https://project-auth-moonlight-flamingos.onrender.com
+Frontend: https://project-auth-moonlight-flamingos.netlify.app/
diff --git a/backend/.gitignore b/backend/.gitignore
index 25c8fdbab..16b0af9c2 100644
--- a/backend/.gitignore
+++ b/backend/.gitignore
@@ -1,2 +1,8 @@
node_modules
-package-lock.json
\ No newline at end of file
+package-lock.json
+.DS_Store
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
\ No newline at end of file
diff --git a/backend/models/userSchema.js b/backend/models/userSchema.js
new file mode 100644
index 000000000..417a6a3c6
--- /dev/null
+++ b/backend/models/userSchema.js
@@ -0,0 +1,25 @@
+import bcrypt from "bcrypt"
+import mongoose from "mongoose";
+
+const { Schema, model } = mongoose;
+const UserSchema = new Schema({
+ username: {
+ type: String,
+ required: true,
+ minlength: 4,
+ unique: true,
+ },
+ password: {
+ type: String,
+ required: true,
+ minlength: 8,
+ },
+ accessToken: {
+ type: String,
+ default: () => bcrypt.genSaltSync(),
+ },
+});
+
+// Username, email?, encrypted password, role?
+
+export const User = model("User", UserSchema);
diff --git a/backend/package.json b/backend/package.json
index 8de5c4ce0..e6ef0e256 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -12,8 +12,11 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
+ "bcrypt": "^5.1.1",
"cors": "^2.8.5",
+ "dotenv": "^16.4.5",
"express": "^4.17.3",
+ "express-list-endpoints": "^7.1.0",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
}
diff --git a/backend/server.js b/backend/server.js
index dfe86fb8e..1b1dc3b8e 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -1,24 +1,156 @@
+import bcrypt from "bcrypt";
import cors from "cors";
+import dotenv from "dotenv";
import express from "express";
+import expressListEndpoints from "express-list-endpoints";
import mongoose from "mongoose";
-const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
+// Importing the Model
+import { User } from "./models/userSchema";
+
+// Getting the dotenv file
+dotenv.config();
+
+const mongoUrl =
+ process.env.MONGO_URL || "mongodb://localhost/project-authorization";
mongoose.connect(mongoUrl);
mongoose.Promise = Promise;
// Defines the port the app will run on. Defaults to 8080, but can be overridden
// when starting the server. Example command to overwrite PORT env variable value:
// PORT=9000 npm start
-const port = process.env.PORT || 8080;
+const port = process.env.PORT || 8088;
const app = express();
+//Middleware to Authenticate User
+const authenticateUser = async (req, res, next) => {
+ const user = await User.findOne({ accessToken: req.header("Authorization") });
+ if (user) {
+ req.user = user;
+ next();
+ } else {
+ res.status(401).json({ loggedOut: true });
+ }
+};
+
// Add middlewares to enable cors and json body parsing
-app.use(cors());
+// Adding our frontend URL to the cors that way only that URL is allowed to make backend requests.
+app.use(cors("https://project-auth-moonlight-flamingos.netlify.app/"));
app.use(express.json());
-// Start defining your routes here
+// API Documentation
app.get("/", (req, res) => {
- res.send("Hello Technigo!");
+ try {
+ const endpoints = expressListEndpoints(app).map((endpoint) => {
+ if (endpoint.path === "/register") {
+ endpoint.query = {
+ description: `In this endpoint you can register a new user with a POST request. Send a username of at least four characters and a password of at least eight characters in a JSON to set up a new user.`,
+ };
+ }
+ if (endpoint.path === "/login") {
+ endpoint.query = {
+ description: `In this endpoint you can login in a user with a POST request. Please send the users password and username in a JSON file to log in and acces the token for the user.`,
+ };
+ }
+ if (endpoint.path === "/secrets") {
+ endpoint.query = {
+ description: `For this endpoint there is only the GET request available if you have a valid access token you will be able to see this endpoint otherwise not.`,
+ };
+ }
+ return endpoint;
+ });
+ res.status(200).json(endpoints);
+ } catch (err) {
+ console.error("The following error occured:", err);
+ res
+ .status(500)
+ .send(
+ "Sorry, this page is not available at the moment. Please try again later."
+ );
+ }
+});
+
+//Sign Up Endpoint
+app.post("/register", async (req, res) => {
+ try {
+ const { username, password } = req.body;
+
+ //Check the username
+ if (!username) {
+ return res.status(400).json({ message: "Username is required" });
+ }
+
+ if (username.length < 4) {
+ return res
+ .status(400)
+ .json({ message: "Username must be at least 4 characters long" });
+ }
+
+ //Check the password
+ if (!password) {
+ return res.status(400).json({ message: "Password is required" });
+ }
+
+ if (password.length < 8) {
+ return res
+ .status(400)
+ .json({ message: "Password must be at least 8 characters long" });
+ }
+
+ //Create a User
+ const user = new User({
+ username: username,
+ password: bcrypt.hashSync(password, 10),
+ });
+ await user.save();
+ res.status(201).json({
+ message: "Registration Complete!",
+ id: user._id,
+ accessToken: user.accessToken,
+ });
+ } catch (err) {
+ res
+ .status(400)
+ .json({ message: "Could not register user.", error: err.errors });
+ }
+});
+
+// Login Endpoint
+app.post("/login", async (req, res) => {
+ try {
+ const { username, password } = req.body;
+
+ //Find the user by username in the Database
+ const user = await User.findOne({ username: username });
+
+ //Compare the password of the found user
+ if (user) {
+ const isPasswordCorrect = await bcrypt.compare(password, user.password);
+ if (isPasswordCorrect) {
+ res.status(202).json({
+ message: "Logged in",
+ id: user._id,
+ username: user.username,
+ accessToken: user.accessToken,
+ });
+ } else {
+ res.status(401).json({ message: "This password is incorrect." });
+ }
+ } else {
+ res.status(404).json({ message: "User not found." });
+ }
+ } catch (err) {
+ res.status(500).json({
+ message: "Somethings wrong with the sign in. Please try again later.",
+ error: err.message,
+ });
+ }
+});
+
+//Secrets Endpoint
+app.get("/secrets", authenticateUser);
+app.get("/secrets", (req, res) => {
+ res.status(200).json({ secret: `Super secrets... nobody will know. Well other signed in people will know I guess...` });
});
// Start the server
diff --git a/frontend/README.md b/frontend/README.md
deleted file mode 100644
index f768e33fc..000000000
--- a/frontend/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# React + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-
-Currently, two official plugins are available:
-
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
diff --git a/frontend/index.html b/frontend/index.html
index 0c589eccd..dcbdd6cbd 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1,10 +1,15 @@
-
+
-
+
- Vite + React
+
+
+ Authentication Project
diff --git a/frontend/package.json b/frontend/package.json
index e9c95b79f..f9fb3dbae 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "lottie-react": "^2.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
diff --git a/frontend/public/auth.png b/frontend/public/auth.png
new file mode 100644
index 000000000..867587d49
Binary files /dev/null and b/frontend/public/auth.png differ
diff --git a/frontend/public/background.png b/frontend/public/background.png
new file mode 100644
index 000000000..e97a2abad
Binary files /dev/null and b/frontend/public/background.png differ
diff --git a/frontend/public/crypTech.svg b/frontend/public/crypTech.svg
new file mode 100644
index 000000000..f1318b555
--- /dev/null
+++ b/frontend/public/crypTech.svg
@@ -0,0 +1,57 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg
deleted file mode 100644
index e7b8dfb1b..000000000
--- a/frontend/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 1091d4310..85949e030 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -1,3 +1,30 @@
+import { useState } from "react";
+import { Footer } from "./Footer";
+import { Header } from "./Header";
+import { MainSection } from "./MainSection";
+
export const App = () => {
- return
+ Welcome to our Authentication Site.
+ Please sign up here:
+
+
+ >
+ )}
+
+ >
+ );
+};
+
+MainSection.propTypes = {
+ formSelect: PropTypes.string,
+ isLoggedIn: PropTypes.bool,
+ setIsLoggedIn: PropTypes.func,
+ isMessage: PropTypes.bool,
+ setIsMessage: PropTypes.func,
+ setFormSelect: PropTypes.func,
+};
diff --git a/frontend/src/assets/orange-alert.json b/frontend/src/assets/orange-alert.json
new file mode 100644
index 000000000..41dc22277
--- /dev/null
+++ b/frontend/src/assets/orange-alert.json
@@ -0,0 +1 @@
+{"v":"4.8.0","meta":{"g":"LottieFiles AE 1.0.0","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":60,"w":720,"h":720,"nm":"Alert","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[360,348,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[92,92,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[1,0.596078431373,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":56,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":360,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.596078431373,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":56,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,72],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.337],"y":[1]},"o":{"x":[0.334],"y":[0]},"t":10,"s":[0]},{"t":45,"s":[79]}],"ix":2},"o":{"a":0,"k":210,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":10,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[360,348,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[92,92,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.960784313725,0.486274509804,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":52,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":360,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[0.960784313725,0.486274509804,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":52,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,72],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.251],"y":[0]},"t":0,"s":[0]},{"t":40,"s":[83]}],"ix":2},"o":{"a":0,"k":210,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[360,562,0],"ix":2},"a":{"a":0,"k":[-92,-96,0],"ix":1},"s":{"a":0,"k":[-113.406,113.406,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-92,-328],[-92,136]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.596078431373,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":52,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-96],"ix":2},"a":{"a":0,"k":[-92,-96],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.251],"y":[0]},"t":10,"s":[0]},{"t":45,"s":[32]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":10,"op":60,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[360,562,0],"ix":2},"a":{"a":0,"k":[-92,-96,0],"ix":1},"s":{"a":0,"k":[-113.406,113.406,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-92,-328],[-92,136]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.960784313725,0.486274509804,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":48,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.956862984452,0.262744978362,0.211765005074,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-96],"ix":2},"a":{"a":0,"k":[-92,-96],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.251],"y":[0]},"t":0,"s":[0]},{"t":40,"s":[42]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[361.396,868.604,0],"ix":2},"a":{"a":0,"k":[-92,-96,0],"ix":1},"s":{"a":0,"k":[-113.406,113.406,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-92,-328],[-92,136]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.596078431373,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":52,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-96],"ix":2},"a":{"a":0,"k":[-92,-96],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.251],"y":[0]},"t":40,"s":[1]},{"t":55,"s":[1]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":40,"op":70,"st":10,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[361.396,868.604,0],"ix":2},"a":{"a":0,"k":[-92,-96,0],"ix":1},"s":{"a":0,"k":[-113.406,113.406,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-92,-328],[-92,136]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.960784313725,0.486274509804,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":48,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.956862984452,0.262744978362,0.211765005074,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-96],"ix":2},"a":{"a":0,"k":[-92,-96],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.251],"y":[0]},"t":30,"s":[0]},{"t":50,"s":[5]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":30,"op":70,"st":10,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/frontend/src/assets/orange-loading.json b/frontend/src/assets/orange-loading.json
new file mode 100644
index 000000000..5af50fb34
--- /dev/null
+++ b/frontend/src/assets/orange-loading.json
@@ -0,0 +1 @@
+{"v":"4.8.0","fr":29.9700012207031,"ip":0,"op":71.0000028918893,"w":160,"h":160,"nm":"loading 2 dark","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[80,80,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[160,160]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","_render":true},{"ty":"st","c":{"a":0,"k":[1,0.5569,0.2275,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":20},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[76.473,76.473],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.176],"y":[0.988]},"o":{"x":[0.762],"y":[0.003]},"n":["0p176_0p988_0p762_0p003"],"t":23,"s":[0],"e":[45]},{"i":{"x":[0.319],"y":[1]},"o":{"x":[0.581],"y":[0.016]},"n":["0p319_1_0p581_0p016"],"t":35,"s":[45],"e":[99.9]},{"t":67.0000027289659}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.289],"y":[1]},"o":{"x":[0.566],"y":[0]},"n":["0p289_1_0p566_0"],"t":-1,"s":[0],"e":[100]},{"t":44.0000017921567}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":-1,"s":[0],"e":[360]},{"t":67.0000027289659}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","_render":true}],"ip":-1.00000004073083,"op":299.00001217852,"st":-1.00000004073083,"bm":0,"sr":1,"completed":true},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[80,80,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[160,160]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.9872,0.639,0.3728,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":20},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[76.473,76.473],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.176],"y":[0.99]},"o":{"x":[0.762],"y":[0.002]},"n":["0p176_0p99_0p762_0p002"],"t":26,"s":[0],"e":[46]},{"i":{"x":[0.787],"y":[0.908]},"o":{"x":[0.647],"y":[0.014]},"n":["0p787_0p908_0p647_0p014"],"t":37,"s":[46],"e":[80]},{"i":{"x":[0.392],"y":[1]},"o":{"x":[0.171],"y":[0.125]},"n":["0p392_1_0p171_0p125"],"t":53,"s":[80],"e":[100]},{"t":69.0000028104276}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.443],"y":[0.887]},"o":{"x":[0.637],"y":[0]},"n":["0p443_0p887_0p637_0"],"t":2,"s":[0],"e":[33.78]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.276],"y":[0.032]},"n":["0p833_1_0p276_0p032"],"t":37,"s":[33.78],"e":[61]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":53,"s":[61],"e":[100]},{"t":69.0000028104276}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":2,"s":[0],"e":[360]},{"t":69.0000028104276}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"}],"ip":2.00000008146167,"op":302.000012300712,"st":2.00000008146167,"bm":0,"sr":1,"completed":true},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[80,80,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[160,160]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[1,0.6713,0.42,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":20},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[76.473,76.473],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.713],"y":[0.988]},"o":{"x":[0.382],"y":[0.001]},"n":["0p713_0p988_0p382_0p001"],"t":29,"s":[0],"e":[36]},{"i":{"x":[0.84],"y":[0.887]},"o":{"x":[0.624],"y":[0.05]},"n":["0p84_0p887_0p624_0p05"],"t":39,"s":[36],"e":[59.495]},{"i":{"x":[0.381],"y":[0.884]},"o":{"x":[0.234],"y":[0.157]},"n":["0p381_0p884_0p234_0p157"],"t":52,"s":[59.495],"e":[80.321]},{"i":{"x":[0.568],"y":[1]},"o":{"x":[0.247],"y":[0.036]},"n":["0p568_1_0p247_0p036"],"t":63,"s":[80.321],"e":[100]},{"t":71.0000028918893}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.72],"y":[0.909]},"o":{"x":[0.391],"y":[0]},"n":["0p72_0p909_0p391_0"],"t":5,"s":[0],"e":[32]},{"i":{"x":[0.71],"y":[0.925]},"o":{"x":[0.379],"y":[0.065]},"n":["0p71_0p925_0p379_0p065"],"t":39,"s":[32],"e":[54.957]},{"i":{"x":[0.709],"y":[0.882]},"o":{"x":[0.379],"y":[0.097]},"n":["0p709_0p882_0p379_0p097"],"t":52,"s":[54.957],"e":[74.645]},{"i":{"x":[0.722],"y":[1]},"o":{"x":[0.397],"y":[0.091]},"n":["0p722_1_0p397_0p091"],"t":63,"s":[74.645],"e":[100]},{"t":71.0000028918893}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":5,"s":[0],"e":[360]},{"t":71.0000028918893}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"}],"ip":5.00000020365417,"op":305.000012422905,"st":5.00000020365417,"bm":0,"sr":1,"completed":true}],"__complete":true}
\ No newline at end of file
diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg
deleted file mode 100644
index 6c87de9bb..000000000
--- a/frontend/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/assets/success-animation.json b/frontend/src/assets/success-animation.json
new file mode 100644
index 000000000..67bb46e1a
--- /dev/null
+++ b/frontend/src/assets/success-animation.json
@@ -0,0 +1 @@
+{"v":"4.10.1","fr":30,"ip":0,"op":40,"w":80,"h":80,"nm":"Success Checkmark","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Check Mark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-1.312,6,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-15.75,8],[-8,16],[13.125,-4]],"o":[[-15.75,8],[-8,16],[13.125,-4]],"v":[[-15.75,8],[-8,16],[13.125,-4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":25,"s":[0],"e":[100]},{"t":33}],"ix":1},"e":{"a":0,"k":0,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":40,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":2,"ty":4,"nm":"Circle Flash","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[0],"e":[98]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[98],"e":[0]},{"t":38}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":25,"s":[0,0,100],"e":[100,100,100]},{"t":30}],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":0,"k":[64,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.961,0.6652,0.439,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true}],"ip":0,"op":40,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":3,"ty":4,"nm":"Circle Stroke","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.022,39.022,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":16,"s":[100,100,100],"e":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":22,"s":[80,80,100],"e":[120,120,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":25,"s":[120,120,100],"e":[100,100,100]},{"t":29}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[60,60],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[100]},{"t":16}],"ix":1},"e":{"a":0,"k":0,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true},{"ty":"st","c":{"a":0,"k":[1,0.4392,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0.978,0.978],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":40,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":4,"ty":4,"nm":"Circle Green Fill","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":21,"s":[0],"e":[98]},{"t":28}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":21,"s":[0,0,100],"e":[100,100,100]},{"t":28}],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":0,"k":[64,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,0.4392,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true}],"ip":0,"op":40,"st":0,"bm":0,"completed":true}],"__complete":true}
\ No newline at end of file
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 3e560a674..4addb698c 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -1,13 +1,20 @@
:root {
+ font-family: "Overpass", "Arial Narrow Bold", sans-serif;
+}
+
+* {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ box-sizing: border-box;
}
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
- monospace;
-}
\ No newline at end of file
+body{
+ width: 100vw;
+ max-width: 100%;
+ background-image: url(/background.png);
+ background-position: center;
+ background-repeat: none;
+ min-height:100vh;
+ display:flex;
+ flex-direction:column;
+ justify-content:space-between;
+}
diff --git a/instructions.md b/instructions.md
deleted file mode 100644
index eccc02575..000000000
--- a/instructions.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Instructions
-Your project needs two parts; a backend API, and a React frontend. You'll need to create a `User` model using mongoose, with properties for your registered user, and to store a user's access token.
-
-Then, on the frontend side of things, you'll need to build up a registration form that POSTs to your API. You'll need to store the access token you get back in the browser using local storage, and then use that token when making other requests to your API.
-
-Once a user is logged in, you will need to have one last endpoint which returns some content which only logged-in users should be able to access. You can choose what you want this endpoint to return, and if you want to make multiple endpoints, that's fine too. It could return hard-coded data or something from the database - either is fine. Whatever you choose, it should be displayed in the frontend after you've logged in.
-
-To summarise, your API needs:
-- Registration endpoint, to create a new user.
-- Sign-in endpoint, to authenticate a returning user.
-- An authenticated endpoint which only returns content if the `Authorization` header with the user's token was correct.
-
-Your frontend needs:
-- A registration form.
-- A sign-in form.
-- A page to show the authenticated content from the API.
-- A 'sign out' button that removes the saved access token and redirects the user to the login form.
-
-## Requirements
-- Your API should have routes to register and login, and finally an authenticated endpoint.
-- The authenticated endpoint should return a 401 or 403 (see [401 vs. 403 on SO](https://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses)) with an error message if you try to access it without an `Authentication` access token or with an invalid token.
-- Your frontend should have a registration form which POSTs to the API to create a new user.
-- Your passwords in the database should be encrypted with bcrypt.
-- Your API should validate the user input when creating a new user, and return error messages which could be shown by the frontend (displaying the errors in a nice way in the frontend is a stretch goal - it’s fine to just show 'Something went wrong' on the frontend if you run out of time).
-
-## Stretch goals
-So you’ve completed the requirements? Great job! Make sure you've committed and pushed a version of your project before starting on the stretch goals. Remember that the stretch goals are optional.
-
-### Intermediate Stretch Goals
-- Store data in the database for your authenticated data routes.
-- When registering, display error messages from the API next to the field which has the error. For example, if the email address is invalid, show an error message next to the email input.
-- To challenge yourself, try to implement Google authentication with Firebase. [Here](https://www.freecodecamp.org/news/react-firebase-authentication-and-crud-operations/) you will find detailed tutorial which will guide you through implementation (some of the steps connected to [Material UI](https://mui.com/) components can be replaced with your custom components).
-
-
-### Advanced Stretch Goals
-- Add more routes, perhaps even a `POST` route to create new objects in your database as a logged-in user.
-- Improve validations in the backend to ensure unique email addresses, or validate the email address format using a regular expression.
diff --git a/netlify.toml b/netlify.toml
index 95443a1f3..c05012bee 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,6 +1,11 @@
# This file tells netlify where the code for this project is and
# how it should build the JavaScript assets to deploy from.
[build]
- base = "frontend/"
- publish = "build/"
+ base = "frontend"
+ publish = "dist"
command = "npm run build"
+
+[[redirects]]
+ from = "/*"
+ to = "/index.html"
+ status = 200
\ No newline at end of file
diff --git a/pull_request_template.md b/pull_request_template.md
deleted file mode 100644
index d92c89b51..000000000
--- a/pull_request_template.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Netlify link
-Add your Netlify link here.
-PS. Don't forget to add it in your readme as well.
-
-## Collaborators
-Add your collaborators here. Write their GitHub usernames in square brackets. If there's more than one, separate them with a comma, like this:
-[github-username-1, github-username-2]