Open In App

Note-Taking App with Status Tracker using MERN Stack

Last Updated : 04 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will be creating a simple note-taking application with functionalities to create a note, delete a note, edit a note, and view the note. The project uses NodeJS as a backend server with Postman API to post and get the notes from the HTTP request. It uses ExpressJS as a framework in the backend and MongoDB to create a database and store the notes. The frontend setup can be created using ReactJS.

Preview of Final Output :

Note-Taking-Application---Google-Chrome-2024-02-24-09-41-39

Edit, Delete, View Note

Prerequisites :

Approach to Create Note-Taking App With NodeJS and ExpressJS :

  • Create a .env file to store the value of PORT on which the backend application will run and also add the mongoDB URL where all data of notes will be stored. The significance of .env file is that it stores all configuration settings for the application and private data that can be accessed in the files but is inaccessible to other people.
  • Create an index.js file where express and node.js will be used to handle servers and routes. Also use CORS Policy (Cross Origin Resource Sharing) that enables the use of other applications on the current one being used. Use a middleware element to parse the request to the body and finally return a response when the server is connected to the backend.
  • Create a function to connect to the database of mongodb using the url specified in the .env file. On successful connection with the database, send a response of a successful message.
  • Create a routes.js file which connects to the Mongoose Model and creates several routes to get, post, delete, update the notes. With each functionality we have also added a response message along with the status code.
  • Create a model.js file and within the file create a Schema model using mongoose and mention the required details you want for the website, such as the topic of the note, the status of the note, the different timestamps, such as when the note was created and when edited, along with the note you would want to phrase.
  • On running the frontend application, the backend successfully connects to the application on creating routes and BrowserRouter in the App.jsx and Main.jsx file respectively. To run the frontend application, you may use Create React Application, or Create Vite Project.
  • In frontend code, we will be creating several components to post, get, delete and update a book using POSTMAN API. We will also give two options to view the notes, one in the table format & the other one in cards format.

Steps to Create a Backend Server:

Step 1: Create a project using the following command.

npm init -y

Step 2: Navigate to the root directory of your project.

cd backend

Step 3: Install the necessary package in your server using the following command.

npm install express cors dotenv mongodb mongoose nodemon

Project Structure:

Screenshot-(361)

Backend Project Structure

package.json:

"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.4.1",
"express": "^4.18.2",
"mongodb": "^6.3.0",
"mongoose": "^8.1.1",
"nodemon": "^3.0.3"
},

Example: Below is an example of creating a server.

Javascript




// server.js
//Express helps manage servers and routes
import 'dotenv/config'
import { mongoose } from 'mongoose';
import express from "express";
import NotesRoute from './Routes/routes.js'
import cors from 'cors'
 
const app = express();
 
app.use(cors());
 
//Middleware to parse the request body
 
app.use(express.json());
 
app.get('/', (request, response) => {
    console.log(request);
    return response.status(202).send(
        `Welcome to my Note Making Application`);
});
 
app.use('/notes', NotesRoute)
 
//Connecting to a Database (MongoDB)
const connectToDatabase = async () => {
    try {
        await mongoose.connect(process.env.mongoDBURL);
        console.log('Connected to Database');
        app.listen(process.env.PORT, () => {
            console.log(`App is listening to PORT
             ${process.env.PORT}`);
        })
    } catch (error) {
        console.log(error.message);
    }
}
 
connectToDatabase();


Javascript




// Routes/routes.js
import express from "express";
import {
    Notes
} from '../Notes Model/model.js'
const router = express.Router();
 
//Routes to save a new note
 
router.post('/', async (req, resp) => {
    try {
        if (!req.body.topic || !req.body.status
            || !req.body.notes) {
            return resp.status(400).send({
                message: "Enter all details!"
            });
        }
        const notesVariable = {
            topic: req.body.topic,
            status: req.body.status,
            notes: req.body.notes
        };
        const notes = await Notes.create(notesVariable);
        return resp.status(201).send(notes);
    } catch (error) {
        console.log(error.message);
        return resp.status(500).send({
            message: error.message
        });
    }
});
 
//Routes to get notes
 
router.get('/', async (req, resp) => {
    try {
        const notes = await Notes.find({});
        return resp.status(200).json({
            count: notes.length,
            data: notes
        });
    } catch (error) {
        console.log(error.message);
        return resp.status(400).send({
            message: error.message
        });
    }
});
 
//Route to get one note
router.get('/:id', async (req, res) => {
    try {
        //fetch data from database
        const { id } = req.params;
        const note = await Notes.findById(id);
        return res.status(201).json(note);
 
    } catch (error) {
        console.log(`Error message : ${error.message}`);
        return res.status(500).send({
            message: error.message
        });
    }
});
 
//Routes to update a note
router.put('/:id', async (req, res) => {
    try {
        if (!req.body.topic || !req.body.status
            || !req.body.notes) {
            return res.status(500).send({
                message: 'Send all the required details!'
            });
        }
        const { id } = req.params;
        const result = await Notes.findByIdAndUpdate(id, req.body);
        if (!result) {
            return res.status(500).json({
                message: 'Notes not found!'
            })
        }
        return res.status(200).send({
            message: 'Notes updated successfully'
        });
    }
    catch (err) {
        console.log(`Error message : ${err.message}`);
        return res.status(500).send({
            message: err.message
        });
    }
});
 
//Deleting a note
router.delete('/:id', async (req, res) => {
    try {
        const { id } = req.params;
        const result = await Notes.findByIdAndDelete(id);
        if (!result) {
            return res.send(400).json({
                message: 'Note could not be deleted!'
            });
        }
        return res.status(200).send({
            message: 'Note deleted successfully!'
        });
    } catch (error) {
        console.log(error.message);
        return res.status(404).send({
            message: error.message
        });
    }
});
 
export default router;


Javascript




// Notes Modal/model.js
import mongoose from 'mongoose';
const { Schema } = mongoose;
 
const noteSchema = new Schema(
    {
        topic: {
            type: String,
            required: true,
        },
        status: {
            type: String,
            required: true,
        },
        notes: {
            type: String,
            required: true
        }
    },
    {
        timestamps: true,
    }
);
 
export const Notes = mongoose.model('Cat',noteSchema);


Steps To Create Frontend Application:

Step 1: Create a react application using the following command.

npm create vite@latest my-react-app --template

Step 3: Select a framework: select the React framework here using the downward arrow key.

Vanilla
Vue
React
Preact
Lit
Svelte
Solid
Qwik
Others

Step 4: Select Variant: choose any variant of your choice using the downward arrow key,i.e: choose JavaScript

TypeScript
TypeScript + SWC
JavaScript
JavaScript + SWC

Step 5: Now, switch to my-react-app directory

cd my-react-app

Step 6: Install Dependencies

npm install

Project Structure:

Screenshot-(363)

package.json:

"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}


Example: Below is an example of creating frontend for Note-Taking App.

CSS




 
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}
 
.image {
  background-repeat: no-repeat;
  background-size: cover;
}
 
.submitBTN {
  width: -webkit-fill-available;
}
 
@tailwind base;
@tailwind components;
@tailwind utilities;


Javascript




// App.jsx
import React from 'react';
import {
    BrowserRouter as Router,
    Route,
    Routes
} from 'react-router-dom';
import Heading from './components/Heading';
import AddNotes from './components/AddNotes';
import DeleteNotes from './components/DeleteNotes';
import EditNotes from './components/EditNotes';
 
const App = () => {
    return (
        <Router>
            <Routes>
                <Route path='/'
                    element={<Heading />} />
                <Route path='/notes/create'
                    element={<AddNotes />} />
                <Route path='/notes/delete/:id'
                    element={<DeleteNotes />} />
                <Route path='/notes/edit/:id'
                    element={<EditNotes />} />
            </Routes>
        </Router>
    );
};
 
export default App;


Javascript




//AddNotes.jsx
import React, { useState } from "react";
import {
  Link,
  useNavigate
} from "react-router-dom";
import {
  IoChevronBackCircle
} from "react-icons/io5";
import Spinner
  from "../Components/Spinner.jsx";
import "../index.css";
import axios from "axios";
 
const AddNotes = () => {
  const [topic, setTopic] = useState("");
  const [status, setStatus] = useState("");
  const [notes, setNotes] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const navigate = useNavigate("");
 
  const data = { topic, status, notes };
  const handleSubmit = async () => {
    try {
      await axios.post("https://notes-tracker.onrender.com/notes", data);
      setIsLoading(false);
      navigate("/");
    } catch (error) {
      console.log(error.message);
      console.log(error.response);
    }
  };
 
  return (
    <div>
      <div className="absolute left-8 top-11">
        <Link to="/">
          <IoChevronBackCircle
            className="-mt-6 text-5xl
          float-left cursor-pointer hover:shadow-outline"
          />
        </Link>
      </div>
      {isLoading ? (
        <Spinner />
      ) : (
        <div className="flex-wrap flex m-10 min-[500px]">
          <div
            className="bg-green-100 flex min-w-[460px]
          items-center justify-center p-10 flex-col
           w-[450px] m-auto mt-20 mb-20 rounded-md"
          >
            <div className="mt-6">
              <label className="text-3xl font-bold float-left"
                htmlFor="Topic">
                Topic :
              </label>
              <div>
                <input
                  type="text"
                  id="Topic"
                  className="border-black w-[416px]
                   mt-6 border-2 outline-none p-2
                   rounded-md focus:ring
                   focus:border-purple-800"
                  placeholder="Enter topic"
                  value={topic}
                  onChange={(e) => setTopic(e.target.value)}
                />
              </div>
            </div>
            <div className="mt-6">
              <label className="text-3xl font-bold float-left"
                htmlFor="Status">
                Status :{" "}
              </label>
              <div>
                <input
                  type="text"
                  id="Status"
                  className="border-black w-[416px]
                   mt-6 border-2 p-2 rounded-md
                    focus:ring focus:border-purple-800
                     outline-none"
                  placeholder="Enter status"
                  value={status}
                  onChange={(e) => setStatus(e.target.value)}
                />
              </div>
            </div>
            <div className="mt-6">
              <label className="text-3xl font-bold float-left"
                htmlFor="Notes">
                Notes :
              </label>
              <div>
                <textarea
                  type="text"
                  id="Notes"
                  className="border-black w-[416px]
                   mt-6 border-2 outline-none
                    p-2 rounded-md h-[105px]
                    focus:ring focus:border-purple-800 "
                  placeholder="Enter notes"
                  value={notes}
                  onChange={(e) => setNotes(e.target.value)}
                />
              </div>
            </div>
            <button
              className="p-2 border-2
            border-purple-900 text-2xl m-2
            rounded-md font-bold text-green-950
             transition duration-100 hover:bg-violet-300
              hover:text-black delay-75 w-[416px]"
              onClick={handleSubmit}
            >
              Submit
            </button>
          </div>
        </div>
      )}
    </div>
  );
};
 
export default AddNotes;


Javascript




//EditNotes.jsx
import React, {
    useState,
    useEffect
} from 'react';
import {
    useNavigate,
    useParams
} from 'react-router-dom';
import axios from 'axios';
import Spinner
    from '../Components/Spinner.jsx';
import { Link } from 'react-router-dom';
import {
    IoChevronBackCircle
} from 'react-icons/io5';
 
const EditNotes = () => {
 
    const [topic, setTopic] = useState('');
    const [status, setStatus] = useState('');
    const [notes, setNotes] = useState('');
    const [isLoading, setIsLoading] = useState(false);
 
    const navigate = useNavigate();
    const { id } = useParams();
    const URL = `https://notes-tracker.onrender.com/notes/${id}`;
    const data = { topic, status, notes };
 
    //Get book of specific Id
 
    useEffect(() => {
        const fetchDetails = async () => {
            try {
                setIsLoading(true);
                const response = await axios.get(URL);
                // console.log(response.data);
                setTopic(response.data.topic);
                setStatus(response.data.status);
                setNotes(response.data.notes);
                setIsLoading(false);
            } catch (error) {
                console.log(error.message);
                setIsLoading(false);
            }
        }
        fetchDetails();
    }, [])
 
    /*
    Handle Edit button after
    getting book of particular ID
    */
 
    const handleEdit = async () => {
        try {
            setIsLoading(true);
            await axios.put(URL, data);
            setIsLoading(false);
            navigate('/');
        } catch (error) {
            setIsLoading(false);
            console.log(error.message);
        }
    }
    return (
        <div>
            <div className='absolute left-8 top-11'>
                <Link to='/'>
                    <IoChevronBackCircle
                        className='-mt-6 text-5xl
            float-left cursor-pointer
            hover:shadow-outline' />
                </Link>
            </div>
            {isLoading ? (
                <Spinner />
            ) : (
                <div className="bg-green-100 flex min-w-[460px]
                               items-center justify-center p-10
                               flex-col w-[450px] m-auto mt-20 mb-20
                               rounded-md">
                    <div className="text-left text-2xl bold">
                        Edit Notes
                    </div>
                    <input type="text"
                        className='border-black w-[416px]
                                   mt-6 border-2 outline-none
                                   p-2 rounded-md focus:ring
                                   focus:border-purple-800 '
                                   value={topic}
                        onChange={(e) => setTopic(e.target.value)} />
                    <input type="text"
                        className='border-black w-[416px]
                                   mt-6 border-2 outline-none p-2
                                   rounded-md focus:ring
                                   focus:border-purple-800 '
                        value={status}
                        onChange={(e) => setStatus(e.target.value)} />
                    <textarea
                        type='text'
                        className='border-black w-[416px]
                                   mt-6 border-2 outline-none p-2
                                   rounded-md h-[105px] focus:ring
                                   focus:border-purple-800 resize-none'
                                   value={notes}
                        onChange={(e) => setNotes(e.target.value)}
                    />
                    <button className='p-2 border-2
                                       border-purple-900 text-2xl m-2
                                       rounded-md font-bold text-green-950
                                       transition duration-100
                                       hover:bg-violet-300 hover:text-black
                                       delay-75 w-[416px] mt-6'
                        onClick={handleEdit}
                    >
                        Save
                    </button>
                </div>
            )}
 
        </div>
    )
}
 
export default EditNotes


Javascript




//DeleteNotes.jsx
import React from 'react';
import '../index.css';
import {
    useNavigate,
    useParams
} from 'react-router-dom';
import axios from 'axios';
import Spinner
    from '../Components/Spinner';
import { useState } from 'react';
import { Link } from 'react-router-dom';
import {
    IoChevronBackCircle
} from 'react-icons/io5';
 
const DeleteNotes = () => {
    const [isLoading, setIsLoading] = useState(false);
    const navigate = useNavigate();
    const { id } = useParams();
    // console.log(id);
 
    const handleDelete = async () => {
        setIsLoading(true);
        try {
            await axios.delete(
                `https://notes-tracker.onrender.com/notes/${id}`);
            setIsLoading(false);
            navigate('/');
        } catch (error) {
            setIsLoading(false);
            console.log(error.message);
        }
    }
 
    return (
        <div className='flex items-center
             justify-center min-h-screen'>
            {isLoading ? (
                <Spinner />
            ) : (
                <div className="flex flex-col
                                items-center justify-center">
                    <div className='absolute left-8 top-11'>
                        <Link to='/'>
                            <IoChevronBackCircle
                                className='-mt-6 text-5xl float-left
                             cursor-pointer hover:shadow-outline' />
                        </Link>
                    </div>
                    <div className="md:w-[50%] lg:w-[40%] p-8">
                        <p className="text-3xl text-center font-bold mb-6">
                            Do you really want to delete the note you created?
                            Rethink and then click the button below!
                        </p>
                        <button
                            type="submit"
                            className='w-full outline-none
                                border-purple-950 border-2
                                rounded-md bg-blue-100
                                text-purple-800 hover:text-cyan-50
                                hover:bg-slate-950 duration-100
                                text-3xl submitBTN'
                            onClick={handleDelete}
                        >
                            Delete
                        </button>
                    </div>
                </div>
            )}
        </div>
    );
};
 
export default DeleteNotes;


Javascript




//Heading.jsx
import React, {
    useState
} from 'react';
import NotesCard
    from '../Components/NotesCard';
import NotesTable
    from '../Components/NotesTable';
import {
    Link
} from 'react-router-dom';
import {
    FaSquarePlus
} from 'react-icons/fa6';
 
const Heading = () => {
    const [tableNotes, setTableNotes] = useState(false);
    const [cardNotes, setCardNotes] = useState(false);
 
    return (
        <div>
            <h2 className="font-bold text-2xl
                 max-md:ml-28 max-md:w-[300px]
                 text-center pt-4">
                Note Taking Application
            </h2>
            <div className="max-md:ml-[385px]
                            flex items-center
                            justify-center
                            max-sm:ml-[100px]">
                <div className="flex items-center
                        justify-center pt-8 gap-4">
                    <button
                        className="shadow-lg p-1.5 w-20
                                   text-lg rounded border-2
                                   bg-indigo-200 font-semibold
                                   border-purple-600
                                   transition duration-100
                                   hover:bg-violet-800
                                   hover:text-white delay-75"
                        onClick={() => {
                            setTableNotes(true);
                            setCardNotes(false);
                        }}
                    >
                        Table
                    </button>
                    <button
                        className="shadow-lg p-1.5 w-20
                                   text-lg rounded border-2
                                   bg-indigo-200 font-semibold
                                   border-purple-600
                                   transition duration-100
                                   hover:bg-violet-800
                                   hover:text-white delay-75"
                        onClick={() => {
                            setCardNotes(true);
                            setTableNotes(false);
                        }}
                    >
                        Card
                    </button>
                </div>
            </div>
            <div className="max-md:float-right
                       pr-12 float-right mt-6">
                <Link to="/notes/create">
                    <FaSquarePlus
                        className="text-5xl cursor-pointer
                                   hover:shadow-outline" />
                </Link>
            </div>
            {tableNotes ? <NotesTable /> : <NotesCard />}
        </div>
    );
};
 
export default Heading;


Javascript




//NotesCard.jsx
import React, {
    useState,
    useEffect
} from 'react';
import {
    Link
} from 'react-router-dom';
import axios from 'axios';
import {
    FaNoteSticky
} from 'react-icons/fa6';
import {
    MdEdit
} from 'react-icons/md';
import Spinner from './Spinner';
import {
    MdDelete
} from 'react-icons/md';
import {
    CiCalendarDate
} from 'react-icons/ci';
import NotesModal
    from '../Modals/NotesModal';
import DatesModal
    from '../Modals/DatesModal';
 
const NotesCard = () => {
    const [notes, setNotes] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [selectedIndex, setSelectedIndex] = useState(null);
    const [notesModal, setNotesModal] = useState(false);
    const [datesModal, setDatesModal] = useState(false);
 
    const API_URL = 'https://notes-tracker.onrender.com/notes';
 
    const getNotes = async () => {
        setIsLoading(true);
        try {
            const response = await axios.get(API_URL);
            setNotes(response.data.data);
        } catch (error) {
            console.log(error.message);
        } finally {
            setIsLoading(false);
        }
    };
 
    useEffect(() => {
        getNotes();
    }, []);
 
    const openNotesModal = (index) => {
        setSelectedIndex(index);
        setNotesModal(true);
    };
 
    const closeNotesModal = () => {
        setSelectedIndex(null);
        setNotesModal(false);
    };
 
    const openDatesModal = (index) => {
        setSelectedIndex(index);
        setDatesModal(true);
    };
 
    const closeDatesModal = () => {
        setSelectedIndex(null);
        setDatesModal(false);
    };
 
    return (
        <div>
            {isLoading ? (
                <Spinner />
            ) : (
                <div className="flex items-center
                                justify-between mt-[100px]">
                    <div className="grid ">
                        <div className='grid mt-10 ml-10 mr-4
                                        grid-cols-2 gap-8
                                        min-w-[400px]
                                        sm:grid-cols-4
                                        lg:grid-cols-4
                                        xl:grid-cols-4'>
                            {notes.map((note, index) => (
                                <div key={note.id}
                                    className='border-cyan-600 hover:shadow-2xl
                                               text-[20px] text-pretty
                                               text-2xl bg-blue-50
                                               border-4 rounded-md p-6'>
                                    <div className='text-2xl text-purple-950'>
                                        <span className='font-bold'>S.No :</span>
                                        {index + 1}
                                    </div>
                                    <div className='mt-6'>
                                        <span className='font-bold '>Topic :</span>
                                        {note.topic}
                                    </div>
                                    <div className='mt-4'>
                                        <span className='font-bold '>Status :</span>
                                        {note.status}
                                    </div>
                                    <div className='mt-4'>
                                        <span className='font-bold '>Date : </span>
                                        {new Date(note.createdAt).toDateString()}
                                    </div>
                                    <div className='flex items-center
                                                    justify-evenly mt-6
                                                    mr-2 text-4xl'>
                                        <FaNoteSticky className='text-purple-950
                                                                  cursor-pointer'
                                            onClick={() => openNotesModal(index)} />
                                        <Link to={`/notes/edit/${note._id}`}>
                                            <MdEdit className='text-green-800
                                                               cursor-pointer' />
                                        </Link>
                                        <Link to={`/notes/delete/${note._id}`}>
                                            <MdDelete className='text-red-800
                                                                 cursor-pointer' />
                                        </Link>
                                        <CiCalendarDate className='text-yellow-500
                                                                   text-5xl
                                                                   cursor-pointer'
                                            onClick={() => openDatesModal(index)} />
                                    </div>
                                    {notesModal && selectedIndex === index && (
                                        <NotesModal
                                            onClose={closeNotesModal}
                                            note={note}
                                        />
                                    )}
                                    {datesModal && selectedIndex === index && (
                                        <DatesModal
                                            onClose={closeDatesModal}
                                            note={note}
                                        />
                                    )}
                                </div>
                            ))}
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
};
 
export default NotesCard;


Javascript




//NotesTable.jsx
import React from 'react';
import {
    FaEdit
} from "react-icons/fa";
import {
    MdDelete
} from "react-icons/md";
import {
    useState,
    useEffect
} from 'react';
import axios from 'axios';
import Spinner from './Spinner.jsx';
import {
    Link
} from 'react-router-dom';
 
const NotesTable = () => {
    const [notes, setNotes] = useState([]);
    const [isLoading, setIsLoading] = useState(true);
    const URL = `https://notes-tracker.onrender.com/notes`;
 
    const fetchNotes = async () => {
        try {
            const notesData = await axios.get(URL);
            setNotes(notesData.data.data);
            setIsLoading(false);
        } catch (error) {
            console.log(error.message);
        }
    }
 
    useEffect(() => {
        fetchNotes();
    }, [])
 
    return (
        <div>
            {isLoading ? (
                <Spinner />
            ) : (
                <table className='w-full border-separate
                              border-spacing-4 p-4 mt-4'>
                    <thead>
                        <tr>
                            <th className="border-purple-600 text-xl
                                           border-2 rounded-md p-2">
                                S.No
                            </th>
                            <th className="border-purple-600 text-xl
                                           border-2 rounded-md p-2">
                                Topic
                            </th>
                            <th className="border-purple-600 text-xl
                                           border-2 rounded-md p-2
                                           max-md:hidden">
                                Status
                            </th>
                            <th className="border-purple-600 text-xl
                                           border-2 rounded-md
                                           p-2 max-md:hidden">
                                Date
                            </th>
                            <th className="border-purple-600 text-xl
                                           border-2 rounded-md p-2">
                                Notes
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {notes.map((item, index) =>
                            <tr key={item.id}>
                                <td className='text-center border-purple-600
                                               border-2 rounded-md p-2 '>
                                    {index + 1}
                                </td>
                                <td className='border-purple-600 border-2
                                               rounded-md p-2'>
                                    {item.topic}
                                </td>
                                <td className='max-md:hidden outline-none
                                               border-purple-600 border-2
                                               rounded-md p-2'>
                                    {item.status}
                                </td>
                                <td className='max-md:hidden border-purple-600
                                               border-2 rounded-md p-2'>
                                    {new Date(item.createdAt).toString()}
                                </td>
                                <td>
                                    <p className='border-purple-600 min-h-[116px]
                                                  border-2 outline-none
                                                  rounded-md p-2'>
                                        {item.notes}
                                    </p>
                                </td>
                                <td className='flex items-center
                                               justify-around p-2'>
                                    <Link to={`/notes/edit/${item._id}`}>
                                        <FaEdit className='cursor-pointer
                                                           text-3xl ' />
                                    </Link>
                                    <Link to={`/notes/delete/${item._id}`}>
                                        <MdDelete className='cursor-pointer
                                                             text-3xl ' />
                                    </Link>
                                </td>
                            </tr>
                        )}
                    </tbody>
 
                </table>
            )}
        </div>
    )
}
 
export default NotesTable


Javascript




//DatesModal.jsx
import React from "react";
import {
    CiCalendarDate
} from "react-icons/ci";
import {
    RxCrossCircled
} from "react-icons/rx";
 
const DatesModal = ({ onClose, note }) => {
    return (
        <div
            className="fixed bg-black bg-opacity-60
       top-0 left-0 right-0
       bottom-0 flex justify-center
        items-center"
        >
            <div
                onClick={(event) => event.stopPropagation()}
                className="w-[600px] max-w-full
                           bg-white h-fit rounded-xl p-4
                           flex flex-col relative"
            >
                <RxCrossCircled
                    className="absolute right-6 top-6
                               text-3xl text-red-600
                               cursor-pointer"
                    onClick={onClose}
                />
                <h4
                    className="mt-5 text-2xl
                               font-bold underline"
                >
                    {note.topic}
                </h4>
                <div
                    className="flex items-center
                               gap-3 my-8"
                >
                    <CiCalendarDate
                        className="text-red-500
                                   text-3xl"
                    />
                    <h2>{new Date(note.createdAt).toDateString()}</h2>
                </div>
                <p>
                    Created at:
                    <span className="mt-4">
                        {new Date(note.createdAt).getFullYear()}-
                        {new Date(note.createdAt).getMonth() + 1}-
                        {new Date(note.createdAt).getDate()}
                        {new Date(note.createdAt).toTimeString().split(" ")[0]}
                    </span>
                </p>
                <p>
                    Updated at :
                    <span className="mt-4">
                        {new Date(note.updatedAt).getFullYear()}-
                        {new Date(note.updatedAt).getMonth() + 1}-
                        {new Date(note.updatedAt).getDate()}
                        {new Date(note.updatedAt).toTimeString().split(" ")[0]}
                    </span>
                </p>
            </div>
        </div>
    );
};
 
export default DatesModal;


Javascript




//NotesModal.jsx
import React from 'react';
import {
    RxCrossCircled
} from "react-icons/rx";
import {
    FaBook
} from "react-icons/fa";
 
const NotesModal = ({ onClose, note }) => {
    return (
        <div className='flex bg-black bg-opacity-60
                        items-center justify-center
                        top-0 left-0 right-0
                        bottom-0 fixed'>
            <div
                onClick={(event) => event.stopPropagation()}
                className='bg-white max-w-full
                           h-fit flex flex-col
                           p-4 w-[500px]
                           rounded-md relative'>
                <RxCrossCircled
                    onClick={onClose}
                    className='text-4xl
                               cursor-pointer
                               text-red-600
                               absolute right-4' />
                <p className='text-2xl
                              font-bold'>
                    {note.topic}
                </p>
                <p className='text-2xl
                              font-bold mt-6' >
                    Status :
                    <span className='text-purple-900'>
                        {note.status}
                    </span>
                </p>
                <p className='flex justify-center'>
                    <FaBook className='mr-[11px] -mt-[38px]
                                       text-yellow-500
                                       text-[200px]' />
                    <span className="text-xl mt-10">
                        {note.notes}
                    </span>
                </p>
            </div>
 
        </div>
    )
}
 
export default NotesModal


Javascript




//Spinner.jsx (Animation Effect)
import React from 'react'
 
const Spinner = () => {
    return (
        <div className='animate-ping absolute
                        top-[150px] left-32 h-14
                        w-14 flex items-center
                        rounded-full
                        bg-purple-800'>
        </div>
    )
}
 
export default Spinner


Javascript




//Main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './index.css';
import {BrowserRouter} from 'react-router-dom'
 
 
ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
)


Start your application using the following command.

npm start


Output :

NoteTakingApplication-GoogleChrome2024-02-2409-43-35-ezgifcom-video-to-gif-converter

Output



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads