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 :
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:
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.
// 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(); |
// 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;
|
// 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:
package.json:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
Example: Below is an example of creating frontend for Note-Taking App.
* { margin : 0 ;
padding : 0 ;
box-sizing: border-box;
font-family : 'Poppins' , sans-serif ;
} .image { background : url ( 'https://media.geeksforgeeks.org/wp-content/uploads/20240222112312/Windows-11-Introduces-a-New-Sticky-Notes-App---Accessible-Exclusively-from-OneNote.webp' );
background-repeat : no-repeat ;
background- size : cover;
} .submitBTN { width : -webkit-fill-available;
} @tailwind base; @tailwind components; @tailwind utilities; |
// 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;
|
//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 {
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;
|
//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
|
//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;
|
//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;
|
//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 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;
|
//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
|
//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;
|
//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
|
//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
|
//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 :