Skip to content

derrickqin/AdoptPaws

Repository files navigation

🐾 AdoptPaws

A full-stack pet adoption web application that connects loving families with pets waiting for their forever homes. Built with React 19, Express.js, and Firebase Firestore.

Features

  • Pet Browsing β€” Browse adoptable pets with filters for species, size, gender, and age category
  • Pet Details β€” View detailed profiles with image galleries, bios, vital stats, and related pets
  • Adoption Applications β€” Multi-section form (personal info, home environment, pet experience) submitted to Firestore
  • Favorites β€” Save and view favorite pets in a bento-grid layout
  • Sign In / Profile β€” Authentication page with Google and Apple social login options
  • Responsive Design β€” Mobile-first layout with Material Design 3 inspired theming and organic/asymmetric card shapes

Tech Stack

Layer Technology
Frontend React 19, TypeScript, Vite 6
Styling Tailwind CSS v4, custom MD3 theme tokens
Routing React Router v7
Animations Motion (Framer Motion)
Icons Material Symbols, Lucide React
Backend Express.js 4
Database Firebase Firestore (via firebase-admin)
Auth Firebase Authentication (Google provider)
Validation Zod
Deployment Docker, Google Cloud Run, Cloud Build

Project Structure

β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.tsx              # App entry point
β”‚   β”œβ”€β”€ App.tsx               # Router configuration
β”‚   β”œβ”€β”€ index.css             # Global styles, MD3 theme tokens, custom utilities
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── pets.ts           # Frontend API client (fetchPets, fetchPet, submitApplication)
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ Navbar.tsx         # Fixed top navigation bar
β”‚   β”‚   └── Footer.tsx         # Site footer with links
β”‚   β”œβ”€β”€ data/
β”‚   β”‚   └── pets.ts           # Pet type definition and seed data (6 pets)
β”‚   β”œβ”€β”€ layouts/
β”‚   β”‚   └── MainLayout.tsx     # Navbar + Outlet + Footer wrapper
β”‚   └── pages/
β”‚       β”œβ”€β”€ Home.tsx           # Landing page with hero, how-it-works, featured pets, CTA
β”‚       β”œβ”€β”€ PetList.tsx        # Browsable pet grid with sidebar filters
β”‚       β”œβ”€β”€ PetDetails.tsx     # Individual pet profile with gallery and adoption CTA
β”‚       β”œβ”€β”€ Favorites.tsx      # Saved pets in bento-grid layout
β”‚       β”œβ”€β”€ Apply.tsx          # Adoption application form
β”‚       └── Profile.tsx        # Sign-in / authentication page
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ server.ts             # Express API server with pet and application routes
β”‚   β”œβ”€β”€ firestore.ts          # Firebase Admin SDK initialization
β”‚   └── seed.ts               # Database seeder script
β”œβ”€β”€ Dockerfile                # Multi-stage build (Node 20)
β”œβ”€β”€ cloudbuild.yaml           # Google Cloud Build CI/CD pipeline
β”œβ”€β”€ deploy.sh                 # One-command Cloud Run deployment script
β”œβ”€β”€ vite.config.ts            # Vite config with proxy to backend
β”œβ”€β”€ tsconfig.json             # Frontend TypeScript config
└── tsconfig.server.json      # Server TypeScript config

Prerequisites

  • Node.js 20+
  • Google Cloud Project with Firestore enabled
  • gcloud CLI authenticated (gcloud auth application-default login)

Getting Started

1. Install dependencies

npm install

2. Configure environment

Copy the example env file and fill in your values:

cp .env.example .env.local
GOOGLE_CLOUD_PROJECT=your-gcp-project-id
PORT=3001

# Firebase Web SDK (frontend) β€” NOT secret, identifies the project
VITE_FIREBASE_API_KEY=your-firebase-web-api-key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-gcp-project-id

Firebase Authentication

Sign-in uses Firebase Authentication with the Google provider.

  1. In the Firebase console, open your project β†’ Authentication β†’ Sign-in method β†’ enable Google.
  2. Open Project settings β†’ General β†’ "Your apps" β†’ register a Web app and copy the apiKey, authDomain, projectId into .env.local using the VITE_FIREBASE_* variables above.
  3. To gate admin-only routes (pet CRUD, listing all applications), sign in once to create your user, then grant yourself the admin custom claim:
tsx server/scripts/grantAdmin.ts <your-uid>

The user must sign out and back in for the claim to take effect on the client.

3. Seed the database

Populate Firestore with sample pet data (6 pets β€” dogs and cats):

npm run seed

4. Run locally

Starts both the Vite dev server (port 3000) and Express API server (port 3001) concurrently:

npm run dev

The frontend proxies /api requests to the backend automatically.

Available Scripts

Script Description
npm run dev Start frontend + backend concurrently
npm run dev:client Start Vite dev server only (port 3000)
npm run dev:server Start Express server with hot reload (port 3001)
npm run build Build frontend with Vite
npm run build:server Compile server TypeScript
npm run build:all Build both frontend and server
npm run start Start production server
npm run seed Seed Firestore with sample pet data
npm run lint Type-check with TypeScript
npm run clean Remove build artifacts

API Endpoints

Mutating and admin endpoints require a Firebase ID token in the Authorization: Bearer <token> header. Admin-only routes additionally require the admin: true custom claim (see Firebase Authentication).

Pets

Method Endpoint Auth Description
GET /api/pets β€” List all pets (supports species, size, gender, ageCategory query filters)
GET /api/pets/:id β€” Get a single pet by ID
POST /api/pets admin Create a new pet
PUT /api/pets/:id admin Update a pet
DELETE /api/pets/:id admin Delete a pet

Applications

Method Endpoint Auth Description
POST /api/applications user Submit an adoption application (server stamps userId)
GET /api/applications admin List all applications

Favorites

Method Endpoint Auth Description
GET /api/favorites user List the current user's favorited pet IDs
PUT /api/favorites/:petId user Add a pet to favorites
DELETE /api/favorites/:petId user Remove a pet from favorites

Deployment

Option A: Deploy script

./deploy.sh <GCP_PROJECT_ID> [REGION] [SERVICE_NAME]

# Example:
./deploy.sh my-gcp-project us-central1 adoptpaws

Required GCP APIs:

  • Cloud Run
  • Cloud Build
  • Artifact Registry
  • Firestore

Enable them with:

gcloud services enable run.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  firestore.googleapis.com

Option B: Cloud Build

gcloud builds submit --config cloudbuild.yaml \
  --substitutions=_REGION=us-central1,_SERVICE_NAME=adoptpaws

Docker (manual)

docker build -t adoptpaws .
docker run -p 8080:8080 \
  -e NODE_ENV=production \
  -e GOOGLE_CLOUD_PROJECT=your-project-id \
  adoptpaws

The Dockerfile uses a multi-stage build: stage 1 builds the Vite frontend and compiles the server TypeScript, stage 2 copies only production artifacts and dependencies.

Design System

The app uses a custom Material Design 3 inspired theme defined in src/index.css with:

  • Fonts: Plus Jakarta Sans (headings), Be Vietnam Pro (body)
  • Color tokens: Full MD3 surface/primary/secondary/tertiary/error palette
  • Custom utilities: organic-shape / organic-card / asymmetric-card for distinctive rounded corners (3rem top-left/bottom-right, 1rem top-right/bottom-left)
  • Background: Subtle radial gradient mesh (bg-mesh)

Routes

Path Page Layout
/ Home MainLayout
/pets Pet listing with filters MainLayout
/pets/:id Pet detail page MainLayout
/favorites Saved favorites MainLayout
/apply/:petId Adoption application MainLayout
/profile Sign in / profile Full screen (no layout)

License

Apache-2.0

About

No description or website provided.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors