A full-stack portfolio website powered by a custom-built Content Management System. All content — projects, skills, education, certificates, services, and messages — is managed dynamically through a JWT-protected admin dashboard. No hardcoded data, no redeployment needed to update anything on the live site.
🔗 Live: afshan-qasim-portfolio.vercel.app
This is not a static site. Every section of the portfolio is driven by a REST API and stored in MongoDB. The admin dashboard lets you create, edit, and delete any content from a browser — without touching code or redeploying.
- Projects — add, edit, delete portfolio projects with title, description, image, live URL, GitHub URL
- Skills — manage tech stack entries per category
- Education — update academic history dynamically
- Certificates — add new certifications as they are earned
- Site Content — edit hero text, about section, and profile details
- Services — update offered services
- Messages — read contact form submissions from visitors
After logging in at /admin/login, the admin has full control over every
section of the live portfolio:
| Section | Operations |
|---|---|
| Projects | Create, Edit, Delete — title, description, image, live URL, GitHub URL |
| Skills | Add, Edit, Delete — tech stack entries per category |
| Education | Update academic history and details |
| Certificates | Add new certifications with credential links |
| Site Content | Edit hero text, about section, profile description |
| Services | Update services offered section |
| Messages | Read contact form submissions from visitors |
All changes reflect on the live portfolio immediately — no redeployment required.
// Project
{
title: String,
description: String,
imageUrl: String,
projectUrl: String,
githubUrl: String,
createdAt: Date
}
// Skill
{
name: String,
category: String, // Frontend, Backend, DevOps
icon: String
}
// Certificate
{
title: String,
issuer: String,
credentialUrl: String,
issuedAt: Date
}
// Message (contact form)
{
name: String,
email: String,
message: String,
createdAt: Date,
read: Boolean
}
// Site Content
{
heroTitle: String,
heroSubtitle: String,
aboutText: String,
cvUrl: String
}- Node.js 20+
- MongoDB Atlas account
git clone https://github.com/Afshan738/portfolio-cms
cd portfolio-cms# backend/.env
MONGO_URI=mongodb+srv://<user>:<pass>@cluster.mongodb.net/portfolio
JWT_SECRET=your-secret-key
PORT=5000
# frontend/.env
VITE_API_URL=http://localhost:5000# Backend
cd backend
npm install
npm run dev
# Frontend
cd frontend
npm install
npm run dev| Variable | Location | Description |
|---|---|---|
MONGO_URI |
backend | MongoDB Atlas connection string |
JWT_SECRET |
backend | Token signing secret |
PORT |
backend | API server port (default 5000) |
VITE_API_URL |
frontend | Backend API base URL |
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, CSS3 |
| Backend | Node.js 20, Express.js |
| Database | MongoDB Atlas, Mongoose ODM |
| Authentication | JWT (jsonwebtoken) |
| HTTP client | Axios |
| Deployment | Vercel |
🔗 afshan-qasim-portfolio.vercel.app
Admin login available on request for demo purposes.