A full-stack MERN (MongoDB, Express, React, Node.js) application for managing notes with a modern UI built using React, Tailwind CSS, and Radix UI components.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Endpoints
- Known Issues & Fixes
- Contributing
- β Create, Read, Update, and Delete (CRUD) notes
- β User-specific notes with userId filtering
- β Real-time note updates
- β Responsive design with Tailwind CSS
- β Modal dialogs for creating notes
- β Inline editing for existing notes
- β Timestamps for note creation and updates
- β Modern UI components using Radix UI
- React (v19.1.1) - UI library
- Vite (v7.1.7) - Build tool and dev server
- Tailwind CSS (v4.1.14) - Utility-first CSS framework
- Radix UI - Accessible UI components
- Axios (v1.12.2) - HTTP client
- Class Variance Authority - Component variant management
- Node.js - Runtime environment
- Express (v5.1.0) - Web framework
- MongoDB - NoSQL database
- Mongoose (v8.19.1) - ODM for MongoDB
- CORS - Cross-origin resource sharing
- dotenv - Environment variable management
week4-notes/
βββ backend/
β βββ src/
β β βββ config/
β β β βββ db.js # Database connection
β β βββ models/
β β β βββ Notes.js # Note schema/model
β β βββ routes/
β β β βββ notes.js # API routes
β β βββ server.js # Express server setup
β βββ package.json
β
βββ frontend/
β βββ src/
β β βββ assets/ # Static assets
β β βββ components/
β β β βββ ui/ # Reusable UI components
β β β β βββ button.jsx
β β β β βββ card.jsx
β β β β βββ input.jsx
β β β β βββ textarea.jsx
β β β βββ NewNoteDialog.jsx # Create note modal
β β β βββ NoteCard.jsx # Note display card
β β βββ lib/
β β β βββ api.js # API client
β β β βββ utils.js # Utility functions
β β βββ pages/
β β β βββ Dashboard.jsx # Main dashboard
β β βββ App.jsx # Root component
β β βββ main.jsx # Entry point
β β βββ index.css # Global styles
β βββ vite.config.js # Vite configuration
β βββ package.json
β
βββ README.md
Before you begin, ensure you have the following installed:
- Node.js (v16 or higher)
- npm or yarn
- MongoDB (local installation or MongoDB Atlas account)
git clone https://github.com/PLP-MERN-Stack-Development/Week-4-MERN-Notes-App.git
cd Week-4-MERN-Notes-Appcd backend
npm installcd ../frontend
npm install- Create a
.envfile in thebackenddirectory:
cd backend
touch .env- Add the following environment variables:
# MongoDB Connection String
MONGODB_URI=mongodb://localhost:27017/notes-app
# or for MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/notes-app
# Server Port
PORT=5000
# Allowed Frontend Origin
ALLOWED_ORIGIN=http://localhost:5173- Create a
.envfile in thefrontenddirectory:
cd frontend
touch .env- Add the following environment variable:
VITE_API_URL=http://localhost:5000cd backend
npm run devThe backend server will start on http://localhost:5000
In a new terminal:
cd frontend
npm run devThe frontend will start on http://localhost:5173
Open your browser and navigate to:
http://localhost:5173
| Method | Endpoint | Description | Request Body |
|---|---|---|---|
GET |
/api/notes |
Get all notes (optionally filtered by userId) | Query: ?userId=demo-abc-123 |
POST |
/api/notes |
Create a new note | { title, content, userId } |
PUT |
/api/notes/:id |
Update a note by ID | { title, content } |
DELETE |
/api/notes/:id |
Delete a note by ID | - |
GET http://localhost:5000/api/notes?userId=demo-abc-123POST http://localhost:5000/api/notes
Content-Type: application/json
{
"title": "My First Note",
"content": "This is the content of my note",
"userId": "demo-abc-123"
}PUT http://localhost:5000/api/notes/65f1234567890abcdef12345
Content-Type: application/json
{
"title": "Updated Title",
"content": "Updated content"
}DELETE http://localhost:5000/api/notes/65f1234567890abcdef12345Error: Failed to resolve import "@/lib/utils"
Fix: Ensure vite.config.js has the path alias configured:
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import path from 'path'
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})Error: The requested module does not provide an export named 'default'
Fix: Import UI components as named exports:
// β
Correct
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Textarea } from "./ui/textarea";
// β Wrong
import Button from "./ui/button";Error: Update/Delete requests fail
Fix: Add missing slashes in frontend/src/lib/api.js:
// Line 24 - Update endpoint
const res = await client.put(`/api/notes/${id}`, payload);
// Line 29 - Delete endpoint
const res = await client.delete(`/api/notes/${id}`);Error: GET /api/notes returns no data or 500 error
Fix: Change req.body to req.query in backend/src/routes/notes.js:
// Line 8
const { userId } = req.query; // β
Correct
// NOT: const { userId } = req.body; // β WrongError: Server crashes on database errors
Fix: Wrap all async route handlers in try-catch blocks:
router.get("/", async (req, res) => {
try {
const { userId } = req.query;
const filter = userId ? { userId } : {};
const notes = await Note.find(filter).sort({ createdAt: -1});
res.json(notes);
} catch (error) {
res.status(500).json({ message: error.message });
}
});- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is part of the PLP MERN Stack Development course.
- PLP MERN Stack Development Team
- PLP Academy for the MERN Stack curriculum
- Radix UI for accessible component primitives
- Tailwind CSS for the utility-first CSS framework
Happy Coding! π