Skip to content

A MERN stack application to manage clients and project data that can make CRUD functionality with simple web page.

Notifications You must be signed in to change notification settings

nhistory/project-manage-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

project-manage-app

project-manage-app.mp4

Table of Contents

Project Management App

A MERN stack application to manage clients and project data that can make CRUD functionality with simple web page.

  • Built backend with expressjs and handled by using graphQL mutation.
  • Used graphiql for checking graphql schema on the browser.
  • Made cloud-based database by using mongodb atlas and controled with mongodb compass.
  • Build client side with React and apollo, graphql, react-router-dom, react-icons packages.
  • Deploy with PaaS service heroku application.
  • Resource: Git repo | Demo

Initialize application

  • initialize project: npm init -y -> package.json created
  • install dependencies: npm i express express-graphql graphql mongoose cors colors -> node_modules folder and package-lock.json file created.
  • install dev mode dependencires: npm i -D nodemon dotenv
  • change package.json scripts setting.
"scripts": {
        "start": "node server/index.js",
        "dev": "nodemon server/index.js"
    }

Now you can start server by using npm run dev command inside of working directory.

GraphiQL

GraphiQL is the GraphQL integrated development environment (IDE). We can make query and check data with GraphiQL on the localhost:5000/graphql.

image

image

Initiate Mongodb - Mongodb atlas, Mongodb compass

1. Mongodb atlas

Mongodb atlas is a cloud-based Mongodb service that don't need to install any program on the local machine.

Sign up with google acount and build a database.

image

Select share version and create cluster.

image

Add my local ip address and finish

image

Create database with own name mgmt_db and clients.

image

2. Mongodb compass

Download and install Mongodb compass. On the mongodb atlas, choose overview menu and click connect.

image

Select connect to the compass and copy the connection string. And change <username> and <password>. After that, you can see database connected with atlas on the compass.

image

To connect with application, select go back and make a choice connect your application. Copy connection string inside of .env file as a MONGO_URI variable. (Change , and add mgmt_db after mongodb.net/ )

image

3. Connect to the database

By using mongoose module, you can connect MongoDB with application. Inside of config folder, db.js have a connectDB as a module.

const mongoose = require('mongoose');

const connectDB = async () => {
  const conn = await mongoose.connect(process.env.MONGO_URI);

  console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline.bold);
};

module.exports = connectDB;

If you want to anticipate message as specific color and underline, we can use colors module.

image

4. Fetch MongoDB data

In order to fetch data from MongoDB after connected with, we need to make new schema for MongoDB again not for GraphQL. In this project, Client.js and Project.js file was made inside of models folder. And changed schema.js return values of each client and project.

5. CRUD client and project with GraphQL and MongoDB

For handling MongoDB database with GraphQL, mutation object type can be added inside of schema.js. Name of object is Mutation and you can add client data by using GraphiQL like below.

image

And you can find new client data was added successfully on the MongoDB client database with MongoDB compass. Object ID is automatically created by MongoDB.

image

In the same way, we can add deleteClient field to delete a client data with GraphiQL on the browser.

image

project database also can be added, deleted and updated by ustin mutation object type. This code is added into schema.js.

Build client side with React framework.

1. Create react application

We can initialize react app in the client folder with npx create-react-app client command. After that, some packages should be installed by npm i @apollo/client graphql react-router-dom react-icons command.

apollo/client

Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. Use it to fetch, cache, and modify application data, all while automatically updating your UI. Apollo Client helps you structure code in an economical, predictable, and declarative way that's consistent with modern development practices. The core @apollo/client library provides built-in integration with React, and the larger Apollo community maintains integrations for other popular view layers.

  • Whenever Apollo Client fetches query results from your server, it automatically caches those results locally. This makes later executions of that same query extremely fast.
  • Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache. This enables Apollo Client to respond almost immediately to queries for already-cached data, without even sending a network request.

react-router-dom

The react-router-dom package contains bindings for using React Router in web applications.

React Router includes three main packages:

  • react-router, the core package for the router
  • react-router-dom, which contains the DOM bindings for React Router. In other words, the router components for websites
  • react-router-native, which contains the React Native bindings for React Router. In other words, the router components for an app development environment using React Native

React Router DOM enables you to implement dynamic routing in a web app. Unlike the traditional routing architecture in which the routing is handled in a configuration outside of a running app, React Router DOM facilitates component-based routing according to the needs of the app and platform.

react-icons

Include popular icons in your React projects easily with react-icons, which utilizes ES6 imports that allows you to include only the icons that your project is using.

2. Connect between GraphQL and React client

In order to use state management library Apollo Client, we need to import ApolloProvider,ApolloClient,InMemoryCache from @apollo/client. And make new ApolloClient class with client variable.

  • App.js
import Header from './components/Header';
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:5000/graphql', //backend graphql url
  cache: new InMemoryCache(),
});

function App() {
  return (
    <>
      <ApolloProvider client={client}>
        <Header />
        <div className="container">
          <h1>Hello World</h1>
        </div>
      </ApolloProvider>
    </>
  );
}

export default App;

3. Fetch and display clients

src/components/Clients.jsx has a role to fetch and display clients data. For doing this, we need to import gql from @apollo/clients. The query we want to execute by wrapping it in the gql template literal defined like below.

const GET_CLIENTS = gql`
  query getClinets {
    clients {
      id
      name
      email
      phone
    }
  }
`

Whenever this component renders, the useQuery hook automatically executes our query and returns a result object containing loading, error, and data properties:

  • Apollo Client tracks a query's error and loading state for you, which are reflected in the loading and error properties.
  • When the result of your query comes back, it's attached to the data property.

At this project, we should show up client data like this.

export default function Clients() {
  const { loading, error, data } = useQuery(GET_CLIENTS);

  if (loading) return <p>loading...</p>;
  if (error) return <p>Something Went Wrong</p>;

  return (
    <>
      {!loading && !error && (
        <table className="table table-hover mt-3">
          <thead>
            <tr>
              <th>Name</th>
              <th>Email</th>
              <th>Phone</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {data.clients.map((client) => (
              <ClientRow key={client.id} client={client} />
            ))}
          </tbody>
        </table>
      )}
    </>
  );
}

Then we can see the Project Management App like below.

image

4. Implement react-router-dom

In order to show up the project view page, we need to use react-router-dom on the App.js.

import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'

After that, you can add Router setting like below. Inside of <Router>, we can make several <Route> another inside of <Routes>. Each of route has their own path address and component directed to link. (<Home />,<Project />,<NotFound />).

    <>
      <ApolloProvider client={client}>
        <Router>
          <Header />
          <div className="container">
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="/projects/:id" element={<Project />} />
              <Route path="*" element={<NotFound />} />
            </Routes>
          </div>
        </Router>
      </ApolloProvider>
    </>
  • useParams: The useParams hook returns an object of key/value pairs of the dynamic params from the current URL that were matched by the . Child routes inherit all params from their parent routes. In this project, Project.jsx uses useParams for parsing id data from which is ProjectCard.jsx indicated.

  • useNavigate: The useNavigate hook returns a function that lets you navigate programmatically, for example after a form is submitted. If using replace: true, the navigation will replace the current entry in the history stack instead of adding a new one. In order to move home page after delete project by onClick, we can take useNavigate() with onCompleted key value.

DeleteProjectButton.jsx

export default function DeleteProjectButton({ projectId }) {
  const navigate = useNavigate();

  const [deleteProject] = useMutation(DELETE_PROJECT, {
    variables: { id: projectId },
    onCompleted: () => navigate('/'),
    refetchQueries: [{ query: GET_PROJECTS }],
  });

  return (
    <div className="d-flex mt-5 ms-auto">
      <button className="btn btn-danger m-2" onClick={deleteProject}>
        <FaTrash className="icon" /> Delete Project
      </button>
    </div>
  );
}

Deploy with heroku

1. Setup before deploy.

Before start heroku deploy process, we need to add some codes on server/index.js for production environment.

if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../client/build')));

  app.get('*', (req, res) =>
    res.sendFile(
      path.resolve(__dirname, '../', 'client', 'build', 'index.html')
    )
  );
} else {
  app.get('/', (req, res) => res.send('Please set to production'));
}

Enter npm run build command inside of client folder. Then project will be built and build folder is ready to be deployed.

2. Deploy with heroku

After sign in heroku website, heroku login on the project folder root location. And create new app by using heroku create mernappsh. (mernappsh is a name of heroku application).

You can check heroku app with https://mernappsh.herokuapp.com/.

image

Go to the heroku dashboard, select mernappsh app and select Settings. Add Config Vars like below.

image

Then we can start git push process.

git add .
git commit -m 'Prepare Deploy'
git push heroku master

If there is H10 error, this video clip would be helpful. In order to use graphql in heroku, uri http://localhost:5000 should be deleted related with ApolloClient. You can check this video clip.

References

About

A MERN stack application to manage clients and project data that can make CRUD functionality with simple web page.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published