A modern blogging platform built with Node.js, React, Express, Prisma, and PostgreSQL. Features an admin dashboard for managing posts and comments, plus a public blog interface for readers.
Quick Links: Features | Setup | API Docs | Learnings
demo.mp4
- User Registration & Login with secure JWT-based authentication
- Role-Based Access Control (AUTHOR & USER roles)
- Protected Routes ensuring only authenticated users can access specific features
- Secure Password Hashing using bcrypt
- Create & Edit Posts with rich content support
- Publish/Unpublish posts with one-click toggle
- Delete Posts with cascading comment removal
- View Author-Specific Posts in admin dashboard
- Manage Post Metadata (title, content, published status)
- Add Comments to published posts
- View Comments with commenter information
- Delete Comments (by comment owner or post author)
- Comment Moderation for post owners
- Edit Comments with a beautiful modal interface
- Real-time Updates when comments are modified
- Self-Service Registration with automatic session establishment
- Admin Dashboard with post management interface
- Public Blog Page showcasing published posts
- Login Page with session management
- Responsive Design built with Tailwind CSS
- Smooth Navigation using React Router v7
- Real-Time UI Updates without page reloads
- Node.js & Express.js β Server runtime and framework
- Prisma ORM β Type-safe database access
- PostgreSQL β Relational database
- JWT (jsonwebtoken) β Authentication tokens
- bcrypt β Password hashing
- Nodemon β Development server auto-reload
- React 19 β UI library
- React Router v7 β Client-side routing
- Tailwind CSS v4 β Utility-first styling
- Vite β Fast build tool
- ESLint β Code quality
- React 19 β UI library
- React Router v7 β Navigation
- Tailwind CSS v4 β Styling
- Vite β Build system
User (id, username, email, password, role, posts[], comments[])
Post (id, title, content, published, authorId, author, comments[], createdAt, updatedAt)
Comment (id, content, postId, post, userId, user, createdAt, editedAt)- Node.js (v18 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
cd Blog-APIcd api
npm installcd ../admin
npm installcd ../client
npm installCreate .env file in the api directory:
DATABASE_URL="postgresql://user:password@localhost:5432/blog_db"
JWT_SECRET="your-secret-key-here"
PORT=5000Initialize Prisma and run migrations:
cd api
npx prisma migrate dev --name init
npm run seed # Populate with demo dataTerminal 1 β Backend API
cd api
npm run dev
# Runs on http://localhost:5000Terminal 2 β Admin Dashboard
cd admin
npm run dev
# Runs on http://localhost:5173Terminal 3 β Client Blog
cd client
npm run dev
# Runs on http://localhost:5174POST /auth/register
Content-Type: application/json
{
"username": "john_doe",
"email": "john@example.com",
"password": "SecurePass123",
"role": "AUTHOR"
}POST /auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "SecurePass123"
}
Response: { token: "jwt-token", username, role }GET /posts
Authorization: Bearer {token} (optional)GET /posts/my-posts
Authorization: Bearer {token}POST /posts
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "My First Blog Post",
"content": "This is the content...",
"published": true
}PUT /posts/:id
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "Updated Title",
"content": "Updated content...",
"published": true
}PATCH /posts/:id/publish
Authorization: Bearer {token}DELETE /posts/:id
Authorization: Bearer {token}GET /commentsPOST /comments
Authorization: Bearer {token}
Content-Type: application/json
{
"content": "Great post!",
"postId": 1
}DELETE /comments/:id
Authorization: Bearer {token}Blog-API/
βββ api/ # Backend server
β βββ controllers/
β β βββ authController.js # Authentication logic
β β βββ postController.js # Post CRUD operations
β β βββ commentController.js # Comment management
β βββ middleware/
β β βββ authMiddleware.js # JWT verification
β β βββ optionalAuthMiddleware.js
β β βββ roleMiddleware.js # Role-based access
β βββ routes/
β β βββ authRoutes.js
β β βββ postRoutes.js
β β βββ commentRoutes.js
β βββ prisma/
β β βββ schema.prisma # Database schema
β β βββ migrations/ # Database migrations
β βββ lib/
β β βββ prisma.js # Prisma client setup
β βββ scripts/
β β βββ seed.js # Demo data seeding
β βββ app.js # Express app configuration
β βββ package.json
β
βββ admin/ # Admin dashboard (React)
β βββ src/
β β βββ components/
β β β βββ CreatePost.jsx # Create post form
β β β βββ EditPost.jsx # Edit post form
β β β βββ MyPosts.jsx # Dashboard with posts & comments
β β β βββ LoginPage.jsx # Admin login
β β βββ App.jsx # Root component
β β βββ main.jsx
β β βββ index.css # Tailwind + custom styles
β βββ index.html
β βββ vite.config.js
β βββ package.json
β
βββ client/ # Client blog (React)
β βββ src/
β β βββ components/
β β β βββ LoginPage.jsx
β β β βββ PostsPage.jsx
β β βββ App.jsx
β β βββ main.jsx
β β βββ index.css
β βββ index.html
β βββ vite.config.js
β βββ package.json
β
βββ README.md
- β Express & Middleware β Request/response pipeline, error handling
- β Prisma ORM β Database queries, relationships, transactions
- β JWT Authentication β Token generation and validation
- β Role-Based Access Control β Permission management
- β React Hooks β useState, useEffect, custom hooks
- β React Router v7 β Client-side routing and navigation
- β Fetch API β HTTP requests with proper headers
- β Tailwind CSS β Responsive design and utility classes
- β Form Handling β Controlled components and validation
- β State Management β Lifting state and functional updates
- JWT tokens stored in localStorage
- Passwords hashed with bcrypt
- Role-based access control on all endpoints
- Input validation on client and server
- SQL injection protection via Prisma ORM
Security & Production Notes
-
Rate limiting: added route- and action-specific limits to reduce abuse. See
api/middleware/rateLimiters.js.authLimiterβ stricter login limiter (5 login attempts per minute).commentLimiterβ comment creation limiter (10 comments per minute).- A global limiter is also configured on the API to throttle general traffic (e.g. 100 requests / 15 minutes).
-
Pagination: server-side pagination implemented for public posts (
GET /posts) and author posts (GET /posts/my-posts) usingpageandlimitquery parameters. API responses include apaginationobject. Frontend UIs inclientandadminwere updated to use paged requests. -
Delete confirmations: replaced native
confirm()dialogs with a reusable styled modal on both frontends to avoid accidental deletions and improve UX. Seeclient/src/components/ConfirmDeleteModal.jsxandadmin/src/components/ConfirmDeleteModal.jsx. -
Disable source maps in production: Vite configs for both frontends now disable source maps for production builds to avoid publishing original source mappings. See
client/vite.config.jsandadmin/vite.config.js(build.sourcemap toggled bymode === "production").
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit changes (
git commit -m 'Add feature') - Push to the branch (
git push origin feature/your-feature) - Open a Pull Request
ISC License
Mohamed Mosilhy β Full-Stack Developer
Built with β€οΈ using Node.js, React, and PostgreSQL









