Main Dashboard
Overview
The main dashboard is the central interface of the Notes App where authenticated users can view, create, edit, delete, and search their notes. It serves as the primary workspace after successful login, providing a comprehensive note management experience.
What is a Dashboard?
A dashboard is the main user interface that:
- Displays all user data in an organized, accessible format
- Provides primary actions like creating, editing, and deleting content
- Offers navigation and search functionality
- Manages user sessions and authentication state
- Coordinates multiple components to create a cohesive experience
Home Component
File: frontend/notes-app/src/pages/Home/Home.jsx
The Home component is the main dashboard that orchestrates all note-related functionality and user interactions.
Component Structure and Imports
import React, { useState, useEffect } from 'react'
import Navbar from '../../components/Navbar/Navbar'
import NoteCard from '../../components/Cards/NoteCard'
import { MdAdd } from "react-icons/md";
import AddEditNotes from './AddEditNotes';
import Modal from "react-modal";
import { useNavigate } from 'react-router-dom';
import axiosInstance from '../../utils/axiosInstance';
import Toast from '../../components/ToastMessage/Toast';
import EmptyCard from '../../components/EmptyCard/EmptyCard';
Import Breakdown
- React hooks:
useState
for state management,useEffect
for side effects - Components: Navigation, note cards, modals, and empty states
- Icons: Add button icon from React Icons
- Navigation: React Router for programmatic navigation
- API: Configured Axios instance for backend communication
- UI feedback: Toast notifications for user actions
State Management
The Home component manages multiple pieces of state to coordinate the dashboard functionality:
const [userInfo, setUserInfo] = useState(null);
const [allNotes, setAllNotes] = useState([]);
const [isSearch, setIsSearch] = useState(false);
const [openAddEditModal, setOpenAddEditModal] = useState({
isShown: false,
type: "add",
data: null,
});
const [showToastMsg, setShowToastMsg] = useState({
isShown: false,
message: "",
type: "add",
});
State Variables Explained
userInfo
: Stores current user's profile informationallNotes
: Array containing all user's notesisSearch
: Boolean flag indicating if search results are displayedopenAddEditModal
: Object controlling the add/edit note modal stateshowToastMsg
: Object managing toast notification display
Authentication and User Data
const navigate = useNavigate();
const getUserInfo = async () => {
try {
const response = await axiosInstance.get("/get-user");
if (response.data && response.data.user) {
setUserInfo(response.data.user);
}
} catch (error) {
if (error.response.status === 401) {
localStorage.clear();
navigate("/login");
}
}
};
useEffect(() => {
getUserInfo();
getAllNotes();
}, []);
Authentication Flow
- Component mounts:
useEffect
runs on initial render - Fetch user info: Calls
/get-user
endpoint with stored token - Handle success: Updates
userInfo
state with user data - Handle auth failure: Clears storage and redirects to login
- Load notes: Fetches all user notes simultaneously
Note Management Functions
Fetching Notes
const getAllNotes = async () => {
try {
const response = await axiosInstance.get("/get-all-notes");
if (response.data && response.data.notes) {
setAllNotes(response.data.notes);
}
} catch (error) {
console.log("An unexpected error occurred. Please try again.");
}
};
Deleting Notes
const deleteNote = async (data) => {
const noteId = data._id;
try {
const response = await axiosInstance.delete("/delete-note/" + noteId);
if (response.data && !response.data.error) {
showToastMessage("Note Deleted Successfully", "delete");
getAllNotes();
}
} catch (error) {
console.log("An unexpected error occurred. Please try again.");
}
};
Pinning/Unpinning Notes
const updateIsPinned = async (noteData) => {
const noteId = noteData._id;
try {
const response = await axiosInstance.put("/update-note-pinned/" + noteId, {
isPinned: !noteData.isPinned,
});
if (response.data && response.data.note) {
showToastMessage("Note Updated Successfully");
getAllNotes();
}
} catch (error) {
console.log(error);
}
};
Search Functionality
const onSearchNote = async (query) => {
try {
const response = await axiosInstance.get("/search-notes", {
params: { query: query },
});
if (response.data && response.data.notes) {
setIsSearch(true);
setAllNotes(response.data.notes);
}
} catch (error) {
console.log(error);
}
};
const handleClearSearch = () => {
setIsSearch(false);
getAllNotes();
};
Search Features
- Real-time search: Searches through note titles and content
- Search state tracking:
isSearch
flag manages search vs. normal view - Clear functionality: Returns to full note list when search is cleared
- Query parameters: Uses URL parameters for search terms
Modal Management
const handleEdit = (noteDetails) => {
setOpenAddEditModal({ isShown: true, data: noteDetails, type: "edit" });
};
const showToastMessage = (message, type) => {
setShowToastMsg({
isShown: true,
message,
type,
});
};
const handleCloseToast = () => {
setShowToastMsg({
isShown: false,
message: "",
});
};
AddEditNotes Component
File: frontend/notes-app/src/pages/Home/AddEditNotes.jsx
A modal component that handles both creating new notes and editing existing ones.
Component Props and State
const AddEditNotes = ({ noteData, type, getAllNotes, onClose, showToastMessage }) => {
const [title, setTitle] = useState(noteData?.title || "");
const [content, setContent] = useState(noteData?.content || "");
const [tags, setTags] = useState(noteData?.tags || []);
const [error, setError] = useState(null);
Props Explained
noteData
: Existing note data for edit mode (null for add mode)type
: String indicating "add" or "edit" operationgetAllNotes
: Function to refresh the notes list after changesonClose
: Function to close the modalshowToastMessage
: Function to display success/error notifications
Note Operations
Adding New Notes
const addNewNote = async () => {
try {
const response = await axiosInstance.post("/add-note", {
title,
content,
tags,
});
if (response.data && response.data.note) {
showToastMessage("Note Added Successfully");
getAllNotes();
onClose();
}
} catch (error) {
if (error.response && error.response.data && error.response.data.message) {
setError(error.response.data.message);
}
}
};
Editing Existing Notes
const editNote = async () => {
const noteId = noteData._id;
try {
const response = await axiosInstance.put("/edit-note/" + noteId, {
title,
content,
tags,
});
if (response.data && response.data.note) {
showToastMessage("Note Updated Successfully");
getAllNotes();
onClose();
}
} catch (error) {
if (error.response && error.response.data && error.response.data.message) {
setError(error.response.data.message);
}
}
};
Form Validation and Submission
const handleAddNote = () => {
if (!title) {
setError("Please enter the title");
return;
}
if (!content) {
setError("Please enter the content");
return;
}
setError("");
if (type === "edit") {
editNote();
} else {
addNewNote();
}
};
Navigation Components
Navbar Component
File: frontend/notes-app/src/components/Navbar/Navbar.jsx
The navigation bar provides search functionality, user profile display, and logout capability.
const Navbar = ({userInfo, onSearchNote, handleClearSearch}) => {
const [searchQuery, setSearchQuery] = useState("");
const navigate = useNavigate();
const onLogout = () => {
localStorage.clear();
navigate("/login");
};
const handleSearch = () => {
if(searchQuery){
onSearchNote(searchQuery);
}
};
const onClearSearch = () => {
setSearchQuery("");
handleClearSearch();
};
Navbar Features
- App branding: Displays "Notes" title
- Search integration: Embedded search bar with clear functionality
- User profile: Shows user information and logout option
- Logout functionality: Clears local storage and redirects to login
SearchBar Component
File: frontend/notes-app/src/components/SearchBar/SearchBar.jsx
A reusable search input component with clear and search actions.
const SearchBar = ({ value, onChange, handleSearch, onClearSearch }) => {
return (
<div className="w-80 flex items-center px-4 bg-slate-100 rounded-md">
<input type="text"
placeholder='Search Notes'
className="w-full text-xs bg-transparent py-[11px] outline-none"
value={value}
onChange={onChange}
/>
{value && (
<IoMdClose
className="text-xl text-slate-500 cursor-pointer hover:text-black"
onClick={onClearSearch}
/>
)}
<FaMagnifyingGlass className="text-slate-400 cursor-pointer hover:text-black" onClick={handleSearch} />
</div>
)
}
SearchBar Features
- Controlled input: Value managed by parent component
- Conditional clear button: Shows close icon only when there's text
- Visual feedback: Hover effects on interactive elements
- Accessibility: Proper cursor indicators for clickable elements
User Experience Flow
Dashboard Loading
- Component mounts: Home component initializes
- Authentication check: Verifies user token and fetches user info
- Data loading: Retrieves all user notes from backend
- UI rendering: Displays navbar, notes grid, and add button
Note Creation
- Click add button: Opens modal in "add" mode
- Fill form: Enter title, content, and tags
- Submit: Validates and sends to backend
- Success feedback: Shows toast, refreshes list, closes modal
Note Editing
- Click edit on note: Opens modal in "edit" mode with existing data
- Modify fields: Update title, content, or tags
- Submit: Validates and sends updated data to backend
- Success feedback: Shows toast, refreshes list, closes modal
Search Operations
- Enter search term: Type in navbar search bar
- Execute search: Click search icon or press enter
- Display results: Shows filtered notes matching query
- Clear search: Click clear button to return to all notes
State Management Patterns
Lifting State Up
The Home component manages state for child components, following React's "lifting state up" pattern:
- Search state: Managed in Home, passed to Navbar
- Notes data: Centralized in Home, passed to NoteCard components
- Modal state: Controlled by Home, affects AddEditNotes component
Callback Functions
Parent-to-child communication through callback props:
getAllNotes
: Passed to AddEditNotes for refreshing dataonSearchNote
: Passed to Navbar for search functionalityshowToastMessage
: Passed to AddEditNotes for user feedback
Connection to Other Components
Backend Integration
- Authentication: Validates user tokens and handles auth failures
- CRUD operations: Create, read, update, delete notes via API
- Search functionality: Server-side search through note content
Component Hierarchy
- Home (main container)
- Navbar (search and user info)
- NoteCard (individual note display)
- AddEditNotes (modal for note operations)
- Toast (user feedback notifications)
- EmptyCard (empty state display)
State Flow
- Top-down data flow: State flows from Home to child components
- Event bubbling: User actions bubble up through callback functions
- Centralized updates: All state changes coordinated through Home component