A complete portfolio website built with React (Create React App structure) and an Express.js backend for contact form submissions. Tailwind CSS powers responsive UI.
- React functional components only (no direct DOM calls)
- React Router v6 with multiple pages and a shared Navbar
- Mobile-responsive UI with Tailwind CSS + an extra App.css file
- Projects list rendered via .map()
- Controlled Contact form posting to Express backend (/api/contact)
- CORS enabled on backend
- Env-based backend URL (REACT_APP_API_BASE_URL)
- Firebase Hosting config for frontend deploy
- Dark-mode design with gradient charcoal → deep blue → violet
- Theme toggle in Navbar (Light/Dark)
- client/ — React app (CRA-like)
- server/ — Node.js Express backend
- Backend
- cd server
- npm install
- copy .env.example .env (Windows)
- npm run dev (or npm start)
- Frontend
- cd client
- npm install
- copy .env.example .env (Windows) and edit if needed
- npm start
- Build client: npm run build (inside client)
- Deploy: firebase login, firebase init hosting (public: client/build), firebase deploy
- No direct DOM APIs are used; all UI updates are via React state/props.
- Tailwind is configured via postcss.config.js and tailwind.config.js.
- For production contact handling, wire /api/contact to an email service or database.
- Dark mode is enabled via Tailwind
darkMode: 'class'and toggled by React state in App.
To enable Nodemailer and ensure messages reach your inbox:
- Configure server env: see server/.env.example for required variables (SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS, MAIL_TO, PORT). For Gmail, use an App Password with 2FA.
- Configure client env: set REACT_APP_API_BASE_URL in client/.env (e.g., http://localhost:4000 or your deployed API URL).
# In one terminal
cd server
npm install
copy .env.example .env
# edit .env with real SMTP credentials
npm run dev
# In another terminal
cd client
npm install
copy .env.example .env
npm startcurl http://localhost:4000/api/health
curl http://localhost:4000/api/health/email/api/health/email returns { ok: true } when SMTP credentials are valid.
curl -X POST http://localhost:4000/api/contact \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"email": "test.sender@example.com",
"message": "Hello from cURL"
}'On success, an email is sent to MAIL_TO (defaults to shamelbaje525@gmail.com). If deployment uses Firebase Hosting for the frontend, ensure REACT_APP_API_BASE_URL points to the backend domain (e.g., https://api.your-domain.com).