2026-02-19 17:02:39 -06:00
2026-01-02 02:01:02 +00:00
2025-06-12 19:14:33 -05:00

Portfolio (Vite + React + Tailwind)

Personal portfolio site built with React + TypeScript and styled with Tailwind. Includes a light/dark theme toggle and an optional “Professional Reviews” section backed by Firebase Firestore.

Features

  • Responsive single-page app (SPA) with multiple portfolio sections.
  • Light/Dark theme with persisted preference (localStorage).
  • Professional Reviews
    • Read reviews from Firestore on page load.
    • Add review modal (name, position, rating, review text).
    • If Firebase env vars are missing, reading returns an empty list and adding is disabled.

Tech Stack

  • Vite (build + dev server)
  • React 19 + TypeScript
  • Tailwind CSS v4 (via @tailwindcss/vite)
  • Firebase (Firestore) for reviews
  • Docker + Nginx for production container

Getting Started (Local Dev)

Prerequisites

  • Node.js (recommended: Node 22 to match the Docker build image)
  • pnpm (recommended) or npm

If you dont have pnpm yet:

corepack enable
corepack prepare pnpm@latest --activate

Install

pnpm install

Run dev server

pnpm dev

Vite will print the local URL (typically http://localhost:5173).

Environment Variables (Firebase)

Firebase is optional, but required to use the Reviews feature.

Create a .env file in the project root:

VITE_FIREBASE_API_KEY=...
VITE_FIREBASE_AUTH_DOMAIN=...
VITE_FIREBASE_PROJECT_ID=...
VITE_FIREBASE_STORAGE_BUCKET=...
VITE_FIREBASE_MESSAGING_SENDER_ID=...
VITE_FIREBASE_APP_ID=...

# Optional
VITE_FIREBASE_MEASUREMENT_ID=...

Vite only exposes environment variables prefixed with VITE_.

Firestore data model

Reviews are stored in a Firestore collection named reviews.

Document shape:

interface Review {
	name: string;
	rating: number; // 1..5
	position: string;
	text: string;
};

Firebase / Firestore Setup (for Reviews)

  1. Create a Firebase project.
  2. Enable Firestore Database.
  3. (Recommended for development) Start with permissive rules, then tighten before production.
  4. Copy your Firebase web app config values into .env.local.

Notes:

  • If Firebase is not configured, the app still runs normally—reviews will simply be empty and adding is disabled.

Scripts

  • pnpm dev — start Vite dev server
  • pnpm build — typecheck (tsc -b) then build (vite build)
  • pnpm preview — preview the production build locally
  • pnpm lint — run ESLint

Production (Docker + Nginx)

This repo includes a multi-stage Docker build:

  1. Node build stage runs npm install + npm run build
  2. Nginx stage serves the dist/ folder and provides SPA routing (try_files ... /index.html)

Build the image

You must pass Firebase values as build args (theyre embedded at build time by Vite):

docker build \
	--build-arg VITE_FIREBASE_API_KEY=... \
	--build-arg VITE_FIREBASE_AUTH_DOMAIN=... \
	--build-arg VITE_FIREBASE_PROJECT_ID=... \
	--build-arg VITE_FIREBASE_STORAGE_BUCKET=... \
	--build-arg VITE_FIREBASE_MESSAGING_SENDER_ID=... \
	--build-arg VITE_FIREBASE_APP_ID=... \
	--build-arg VITE_FIREBASE_MEASUREMENT_ID=... \
	-t portfolio:latest .

Run the container

docker run --rm -p 8080:80 portfolio:latest

Then open http://localhost:8080.

Docker Compose

docker-compose.yml is provided and forwards Firebase env vars as build args.

docker compose up --build

Note: the compose file currently uses ports: - "80" (short syntax). That exposes container port 80, for use with reverse proxy services, like Traefik, or more complex deployment methods, like Dokploy or Coolify. If you want a stable port, change it to something like:

ports:
	- "8080:80"

Project Structure

.
├─ src/
│  ├─ main.tsx              # React entrypoint
│  ├─ App.tsx               # Main page composition + reviews modal
│  ├─ firebase.ts           # Firebase + Firestore initialization
│  ├─ reviewsApi.ts         # Firestore read/write helpers
│  ├─ contexts/
│  │  └─ ThemeContext.tsx   # Theme state + CSS variables
│  └─ components/           # Page sections (Hero, Tech, Reviews, Footer, ...)
├─ nginx.conf               # SPA routing for production container
├─ Dockerfile               # Vite build → Nginx serve
└─ vite.config.ts           # Vite config (React + Tailwind)

Customization Notes

  • Some sections accept an isOutOfCollege prop and are currently disabled by default in src/App.tsx. If you want those sections to render, pass isOutOfCollege={true} into the relevant components.
  • Contact links are in the Hero section and Footer.

Troubleshooting

  • Reviews dont show up: confirm Firestore is enabled and your Firebase env vars are set (VITE_FIREBASE_*).
  • “Firestore is not configured” error: youre missing one or more required Firebase variables.
  • Docker build doesnt pick up env vars: ensure you pass them as --build-arg ... (Vite embeds them during build).
Description
This is created using the TS framework "React." This app utilizes tailwind with dark and light mode.
Readme 4 MiB
Languages
TypeScript 94.9%
Dockerfile 1.6%
CSS 1.5%
JavaScript 1.4%
HTML 0.6%