Skip to content

Search for your next destination from Flymango! You will also find inspirational pictures of other's trip.

Notifications You must be signed in to change notification settings

Rosa-Kang/mernstack-blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Flymango

Flymango is a web application where users can share their good memories from their trips and search for the next destination.


Table of Contents

  1. Purpose of the Project
  2. Use tech
  3. About The Project
  4. Authentication Process
  5. Lessons
  6. Reference

Purpose of the project

  • To build a Full Stack Web Application using MongoDB - Express - React - Node.
  • Authentication & Login with JWT (Json Web Token)
  • Creating Realtime Web App with CRUD function
  • App with Redux Framework with React Hooks

Used tech

Dependency

After 'git-clone', you can simply run this application from your local server by installing each dependencies from Client and Server Client : yarn add jwt-decode react-google-login / Server: yarn add bcrypt jsonwebtoken

##Server side## . npm i body-parser : to POST request . npm i cors : Cross Origin Resource Sharing : a middleware to Connect/ Express . npm i express : a framework for creating the Routing of our application . npm i mongoose : to create models of our POST . npm i nodemon : auto reset the server . npm i bcryptjs jsonwebtoken

##Client side## . npm i @material-ui/core : ui kit used in this project . npm i axios : for making api request . npm i moment : library working with time and date . npm i react-file-base . npm i redux redux-thunk : asynchronous actions with redux . npm i jwt-decode react-google-login


About The Project

Demo link

Landing Page


img img
img img

Structure

.
│  
└── Client
│    └── src
│    │    ├── actions
│    │    ├── api
│    │    ├── components
│    │    ├── constants
│    │    └── reducers
│    │
│    ├── App.js
│    └── index.js
│ 
└── Server
     ├── controller
     ├── middleware
     ├── models
     ├── routes
     └── index.js


Features

shot
**|Login Process|**
  1. Client / Auth.js : The Login Information entered by users received from Auth.js file and here the action is dispatched so the data is sent to Reducers.
   const handleSubmit =(e)=> {
      e.preventDefault();

      if (isSignup) {
        dispatch(signup(form, history))
      } else {
        dispatch(signin(form, history))     
      }
 }

 const handleChange=(e)=> {
   setForm({...form,[e.target.name]: e.target.value});
 }
  const googleSuccess = async (res) => {
    const result = res?.profileObj;
    const token = res?.tokenId;
   try {
     dispatch({type: 'AUTH', data:{result, token}});

     history.push('/');
   } catch (error) {
     console.log(error);
   }
  
  }

  const googleFailure =( error ) => {
   console.log("Google Sign In was unsuccessful. Try Again Later")
   console.log(error);
  }

  1. Client / Reducer > Auth.js : Once the action is dispatched to a reduce, based on the action type, it will be sent to reduces. In this case the action type was Auth so the Auth.js in reduces folder will be executed and the {state & action} will be received into Reducer.
const authReducer = (state = { authData: null }, action) => {
  switch (action.type) {
    
    case actionType.AUTH:
      localStorage.setItem('profile', JSON.stringify({ ...action?.data }));

      return { ...state, authData: action.data, loading: false, errors: null };
    case actionType.LOGOUT:
      localStorage.clear();

      return { ...state, authData: null, loading: false, errors: null };
    default:
      return state;
  }
};

  1. Server / controllers > user.js : This is where our server actually pass in the input data and save into our server.
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";

import UserModal from "../models/user.js";

const secret = "test";


export const signup = async (req, res) => {
  const { email, password, firstName, lastName } = req.body;

  try {
    const oldUser = await UserModal.findOne({ email });

    if (oldUser)
      return res.status(400).json({ message: "User already exists" });

    const hashedPassword = await bcrypt.hash(password, 12);

    const result = await UserModal.create({
      email,
      password: hashedPassword,
      name: `${firstName} ${lastName}`,
    });

    const token = jwt.sign({ email: result.email, id: result._id }, secret, {
      expiresIn: "1h",
    });

    res.status(201).json({ result, token });
  } catch (error) {
    res.status(500).json({ message: "Something went wrong" });

    console.log(error);
  }
};


export const signin = async (req, res) => {
  const { email, password } = req.body;

  try {
    const oldUser = await UserModal.findOne({ email });

    if (!oldUser)
      return res.status(404).json({ message: "User doesn't exist" });

    const isPasswordCorrect = await bcrypt.compare(password, oldUser.password);

    if (!isPasswordCorrect)
      return res.status(400).json({ message: "Invalid credentials" });

    const token = jwt.sign({ email: oldUser.email, id: oldUser._id }, secret, {
      expiresIn: "1h",
    });

    res.status(200).json({ result: oldUser, token });
  } catch (err) {
    res.status(500).json({ message: "Something went wrong" });
  }
};

Lessons

  • MongoDB for the database
  • Node & Express for the server-side
  • React for the client-side

About

Search for your next destination from Flymango! You will also find inspirational pictures of other's trip.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published