Skip to content

Gabri-SF/portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Portfolio — Full-Stack Bilingual Template

A bilingual (PT/EN) developer portfolio built with React, Express, and MongoDB. Features a public-facing site with animated pages, dark/light theming, and a protected admin dashboard for managing projects, blog posts, and experience entries — all with drag-and-drop reordering.

This is a template. The placeholder data belongs to the fictional developer "Jon Doe". Fork it, replace the content, and ship your own portfolio.


Tech Stack

Layer Technology
Frontend React 19, Vite, TypeScript, Tailwind CSS 4, React Router 7
Backend Express 5, TypeScript, MongoDB/Mongoose 9
Auth JWT in HttpOnly cookies (SameSite: none; Secure)
Validation Zod schemas on all mutating routes
Admin UI extras @dnd-kit (drag-and-drop), EasyMDE (markdown editor)

Folder Structure

portfolio/
├── frontend/              # React SPA (Vite)
│   ├── public/
│   │   ├── images/        # Hero image and project images
│   │   ├── icons/         # Skill/tech icons (SVG)
│   │   ├── documents/     # CV PDF files
│   │   └── favicon.svg
│   └── src/
│       ├── pages/         # Route-level components (Home, About, CV, Blog, Portfolio)
│       │   └── admin/     # Protected CRUD editors
│       ├── components/    # Shared UI (Navbar, Footer, Projects, …)
│       ├── layouts/       # PublicLayout and AdminLayout wrappers
│       ├── context/       # AppContext — theme (dark/light) and language (pt/en)
│       ├── translations.ts # All static UI strings in both languages
│       └── utils/         # Axios interceptors, progress bar
│
├── backend/               # Express API
│   └── src/
│       ├── models/        # Mongoose schemas (User, Project, BlogPost, Experience)
│       ├── controllers/   # Business logic per resource
│       ├── routes/        # Express routers
│       ├── middleware/     # JWT auth, Zod validation wrapper
│       └── schemas/       # Zod request body schemas
│
├── createAdmin.txt        # Script to create the admin user (see below)
├── Deployment.txt         # Lessons learned from real deployments
└── LICENSE

How to Personalise It

After cloning, make these changes to replace the Jon Doe placeholder with your own information.

1. Static UI text — frontend/src/translations.ts

This file contains all bilingual strings shown on the public pages. Edit both the pt and en objects to match your background:

  • home.hero.role — your job title or student description
  • home.hero.tagline — one-sentence pitch
  • about.p1 / about.p1_span — your bio paragraph (supports a {span} highlight)
  • about.p2 / about.p2_span — your team or organisation paragraph
  • about.values — three value cards describing your work style
  • footer.desc — footer tagline
  • footer.rights — copyright line (update the name)

2. Home page — frontend/src/pages/Home.tsx

  • Name: Change JON and DOE in the hero <h1> tags to your own name.
  • Hero image: Replace frontend/public/images/YourPhoto.jpg with your own photo (the stub file is already there — just overwrite it).
  • Backend tools array (backendTools): Update tool names, descriptions, and icon paths to your actual stack.
  • Frontend tools array (codingTools): Same — update to your stack.
  • Stats section: Edit the three stat cards to reflect your own numbers/jokes.
  • CTA email: Change contact@jondoe.dev in the <a href="mailto:..."> to your email.

3. Footer — frontend/src/components/Footer.tsx

  • Name: Change JON<br/>DOE to your name.
  • Email: Change contact@jondoe.dev.
  • GitHub URL: Change https://github.com/jondoe-dev.
  • LinkedIn URL: Change https://www.linkedin.com/in/jon-doe-dev/.
  • Current focus label: Edit BUILDING SCALABLE WEB SYSTEMS.
  • Location / coordinates: Change Austin, TX and the GPS coordinates to your own city.

4. Navbar — frontend/src/components/Navbar.tsx

  • Name: Change Jon Doe in the <span> inside the logo link.
  • Logo images: Replace frontend/public/YourLogo_Light.svg (shown on dark backgrounds) and YourLogo_Dark.svg (shown on light backgrounds) with your own logo. Both stubs are already there — overwrite them.

5. CV page — frontend/src/pages/CV.tsx

All content here is hardcoded (not in translations.ts). Edit the bilingual strings inline:

  • Professional summary
  • Core competencies
  • Education section (degree, university, GPA, honours)
  • CV download links — overwrite the stub files frontend/public/documents/YourCV_PT.pdf and YourCV_EN.pdf with your actual PDFs.

6. About page — frontend/src/pages/About.tsx

The technical stack grid is hardcoded. Find the array near line 83 and update the four categories and their items to your own skills.

The Professional Journey timeline is fetched from MongoDB via the Experience model — add your entries through the admin dashboard at /admin/experience once the app is running.

7. Skill icons — frontend/public/icons/

Add your own .svg icon files here. Reference them in Home.tsx and About.tsx as /icons/your-tool.svg. Broken icon paths fall back gracefully to a placeholder rectangle.

8. Page title and favicon

  • frontend/index.html — change <title>Jon Doe</title> and update <link rel="icon"> if needed.

9. Binary files to replace

The following placeholder files ship in frontend/public/. Replace each one with your own content — the filenames must stay the same since they are referenced directly in the code.

File What to put there
public/images/YourPhoto.jpg Your hero/profile photo. Used as the full-bleed background on the Home page. Recommended minimum: 1920×1080.
public/documents/YourCV_EN.pdf Your CV in PDF format — English version.
public/documents/YourCV_PT.pdf Your CV in PDF format — Portuguese version (or a second language of your choice).
public/YourLogo_Light.svg Your logo — light variant (white/light colours, shown on dark backgrounds). Referenced in Navbar.tsx.
public/YourLogo_Dark.svg Your logo — dark variant (dark colours, shown on light backgrounds). Referenced in Navbar.tsx.

The current files are SVG/text stubs so the repo stays clean. Overwrite them with your real files.

10. LICENSE

Update the Copyright (c) 2026 Jon Doe line to your name and year.


MongoDB Setup

Create a free Atlas cluster

  1. Go to mongodb.com/atlas and create a free account.
  2. Create a new free (M0) cluster — choose any cloud region.
  3. In Database Access, create a database user with a username and strong password.
  4. In Network Access, add 0.0.0.0/0 (allows all IPs — fine for a portfolio; tighten in production if needed).
  5. Click Connect → Drivers and copy the connection string. It looks like:
mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority
  1. Append your database name before the ?:
mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net/portfolio?retryWrites=true&w=majority

Collections

You do not need to create collections manually. Mongoose creates them automatically on first write. The four collections used are: users, projects, blogposts, experiences.


Create the Admin User

The file createAdmin.txt in the repo root contains a TypeScript script that creates the admin account used to log into /admin. You need to run it once after setting up your database.

Steps

  1. Copy the script into the backend source folder:
cp createAdmin.txt backend/src/createAdmin.ts
  1. Add the admin credentials to backend/.env (they are read by the script, never hardcoded):
ADMIN_EMAIL=your@email.com
ADMIN_PASSWORD=a_very_strong_password
  1. Run the script from inside the backend folder:
cd backend
npx ts-node src/createAdmin.ts
  1. You should see: ✅ Admin user created successfully!

  2. Delete or gitignore backend/src/createAdmin.ts after running it — it's a one-shot utility and should not live in the repo permanently.

You can now log in at /login with those credentials.


Running Locally

Prerequisites

  • Node.js 18 or later
  • npm 9 or later
  • A MongoDB Atlas connection string (see above)

Install dependencies

# Install backend dependencies
cd backend && npm install

# Install frontend dependencies
cd ../frontend && npm install

Configure environment variables

backend/.env (copy from backend/.env.example):

MONGODB_URI=your_atlas_connection_string
JWT_SECRET=a_random_64_character_string
FRONTEND_URL=http://localhost:5173
NODE_ENV=development
PORT=5000
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=your_admin_password

Generate a strong JWT secret with:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

frontend/.env (copy from frontend/.env.example):

VITE_API_URL=http://localhost:5000

Start the dev servers

Run in two separate terminals:

# Terminal 1 — backend (http://localhost:5000)
cd backend && npm run dev

# Terminal 2 — frontend (http://localhost:5173)
cd frontend && npm run dev

Visit http://localhost:5173 to see the site and http://localhost:5173/login to access the admin dashboard.


Deployment

Frontend — Vercel

  1. Push the repo to GitHub.
  2. Go to vercel.comAdd New Project → import your repo.
  3. Set the Root Directory to frontend.
  4. Vercel auto-detects Vite — leave the framework preset as Vite.
  5. Add the environment variable:
    • VITE_API_URL = https://your-backend.onrender.com (your Render URL, no trailing slash)
  6. Deploy.

Gotcha — SPA routing: The frontend/vercel.json already includes the required rewrite rule that sends all paths to index.html. Without it, direct navigation to /admin or /login returns a 404. Do not delete this file.

Gotcha — devDependencies: If the build fails with missing @types/* packages, move them from devDependencies to dependencies in frontend/package.json. Vercel's build environment sometimes skips dev deps.


Backend — Render

  1. Go to render.comNew → Web Service → connect your GitHub repo.
  2. Set:
    • Root Directory: backend
    • Build command: npm install && npm run build
    • Start command: npm start
    • Node version: 18 or later (set in the Environment tab)
  3. Add environment variables (Settings → Environment):
    • MONGODB_URI
    • JWT_SECRET
    • FRONTEND_URL = your Vercel deployment URL (no trailing slash, e.g. https://your-portfolio.vercel.app)
    • NODE_ENV = production
    • PORT = 5000
  4. Deploy. Render will build and start the API automatically.

Gotcha — CORS credentials: Cookies only work when credentials: true is set in the backend CORS config AND credentials: 'include' is set on every Axios request. Both are already configured in this repo via utils/progress.ts. If you see auth failures in production, double-check these.

Gotcha — cross-site cookies: The frontend and backend are on different domains, so the auth cookie is set with SameSite: none; Secure: true. This requires HTTPS — which Render and Vercel both provide. Locally, the Secure flag is relaxed when NODE_ENV=development. If cookies work locally but not in production, this is almost certainly the issue.

Gotcha — ENV variable formatting: A trailing slash on FRONTEND_URL or VITE_API_URL will silently break all API requests. Always double-check: no trailing slash, correct protocol (https://), and the exact variable name.


Admin Dashboard

Once deployed, visit /login with the credentials you set up via createAdmin.ts.

The dashboard at /admin lets you:

  • Projects — create, edit, delete, and drag-and-drop reorder. Each project has bilingual title, description, full description, features, challenges, image URL, repo URL, live URL, and tags.
  • Blog — write posts in Markdown using the embedded editor. Supports bilingual title, excerpt, and content.
  • Experience — manage the professional journey timeline entries shown on the About page.

Security Notes

  • JWT_SECRET must be at least 64 characters and never committed to git. The .gitignore already excludes .env files.
  • Login is rate-limited to 5 attempts per 15 minutes.
  • All request bodies on mutating routes are validated with Zod before hitting the database.
  • MongoDB injection is prevented via mongo-sanitize middleware.
  • HTTP headers are hardened with helmet.

License

MIT — see LICENSE.

About

Bilingual (PT/EN) full-stack portfolio template — React, Express & MongoDB. Fork it and make it yours.

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages