A professional portfolio web app built with a modern full-stack architecture:
- Frontend: React + TailwindCSS + Framer Motion
- Backend: FastAPI (Python) + Motor (MongoDB async driver)
- Database: MongoDB Atlas
- Deployment: Netlify (Frontend) + Railway (Backend)
showcasing projects, certifications, and professional experience. This portfolio also integrates Google Drive-hosted CV viewing and downloading, along with real-time click analytics via Google Analytics 4 (GA4).
Live Demo: My-Portfolio
- ⚡ Responsive, dark-themed UI with TailwindCSS
- ⚡Animated transitions via Framer Motion
- 🎖️ Project filtering by category (Certifications, Projects, Badges)
- 🎖️ Modal popups for badges and projects
- 📄 View and Download CV buttons (Google Drive integrated)
- 🔸 Toast notifications
- 📊 Google Analytics 4 tracking (CV clicks, page views)
- 🌐 Deployed to Netlify and Railway (CI/CD-ready)
- RESTful API for portfolio data (CV, certs, badges)
- Contact form POST handler (optional email alert support via SMTP)
- MongoDB integration using Motor (Async driver)
- CORS configured for frontend communication
- Stores contact form submissions (
status_checkscollection) - Easily extensible for storing project/cert data dynamically
my-portfolio-websites
│
│── frontend #React app
│ ├── build/
│ │── public/ # Logos, images, etc.
│ │ ├── index.html
│ │ ├── logo.png
│ │ └── ...
│ │── .env # REACT_APP_API_URL
│ │── src/
│ │── App.css
│ │── App.js
│ │── components.js # All page components
│ ├── index.css
│ ├── index.js
│ ├── Modal.js # Custom modal popup
│ ├── package.json
│ ├── craco.config.js
│ ├── netlify.toml
│ ├── Dockerfile #Frontend Dockerfile
│ └── ...
├── backend #FastAPI backend
│ ├── server.py # Main FastAPI app
│ ├── email_utils.py # Optional: contact email handler
│ │── .env # MongoDB URI, etc.
│ ├── venv/ #Virtual Env
│ ├── Dockerfile # Backend Dockerfile
│ └── requirements.txt # Python dependencies
│── nginx.conf
├── .gitignore
├── render.yaml
│── docker-compose.yml
└── README.md✅ Prerequisites
- Node.js 18+
- Python 3.10+
- MongoDB Atlas (free tier or local MongoDB)
- Railway (or Docker optional)
git clone https://github.com/Pascalpedro/my-portfolio-website.git
cd my-portfolio-website🧪 Requirements
- Python 3.10+
- MongoDB Atlas (free tier or local MongoDB)
- Virtualenv (recommended)
🔌 Installation
cd backend
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install -r requirements.txt🔐 Create .env in backend/:
MONGO_URL=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/?retryWrites=true&w=majority
DB_NAME=portfolio_dbuvicorn server:app --reload --port 8000- Backend will be available at: http://localhost:8000/api
cd frontend
npm installCreate .env in frontend/:
REACT_APP_API_URL=http://localhost:8000/api
REACT_APP_GA_MEASUREMENT_ID=G-XXXXXXXXXX # Replace with your GA4 IDnpm start- Frontend runs on: http://localhost:3000
Could be any of:
- Frontend: Vercel, Netlify, or S3 + CloudFront
- Backend: Render, Railway, or AWS EC2
- Database: MongoDB Atlas (Cloud)
🧪 Netlify (Frontend)
- Push frontend/ to GitHub
- Go to https://netlify.com
- Create new site from Git repo
- Set build command:
npm run build
- and publish directory:
dist or build- Set Environment Variable:
REACT_APP_API_URL=https://your-railway-backend.up.railway.app/api
⚙️ Railway (Backend)
- Push backend/ to GitHub
- Go to https://railway.app
- Create new project → Deploy from GitHub repo
- Set environment variables:
MONGO_URL=...DB_NAME=portfolio
| Location | Key | Description |
|---|---|---|
| Frontend | REACT_APP_API_URL | Base URL for FastAPI backend |
| Backend | MONGO_URL | MongoDB connection string |
| Backend | DB_NAME | MongoDB database name |
- Create GA4 property at analytics.google.com
- Get measurement ID (e.g., G-XXXXXXX)
- Add the GA4 script inside public/index.html:
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>- In React buttons, add:
gtag('event', 'download_cv_clicked');Custom events tracked:
- view_cv_clicked
- download_cv_clicked
You can view them in:
Google Analytics > Reports > Engagement > EventsTo enable contact email submission:
- Add /api/contact endpoint in server.py
- Install SMTP/SendGrid library
- Use email_utils.py to send form data as email
📄 Dynamic Portfolio Data GET /api/portfolio returns:
{
"cv_link": "https://drive.google.com/uc?export=view&id=...",
"projects": [...],
"certifications": [...]
}- You can fetch this on the frontend to keep your CV/projects synced.
🧠 Tech Stack
| Layer | Stack |
|---|---|
| Frontend | React, TailwindCSS, Framer Motion |
| Backend | FastAPI, Motor, Pydantic |
| Database | MongoDB (Atlas or local) |
| Hosting | Netlify (frontend), Railway (backend) |
| Analytics | Google Analytics 4 |
📷 Screenshots
✅ Hero Section with CV Buttons
✅ Google Analytics 4 Events Overview
✅ Google Analytics 4 Reports Snapshot
We welcome contributions! Please follow these steps:
- Fork the repository
- Create your feature branch (git checkout -b feature/YourFeature)
- Commit changes with meaningful messages. (git commit -m 'Add YourFeature')
- Push to the branch (git push origin feature/YourFeature)
- Submit a Pull Request
- Pascal Attama
- Email: Attamapascalpedro@gmail.com
- Portfolio: https://pascalattama.netlify.app/
- Website: https://pedroops.com
- GitHub: @Pascalpedro
