Scope: This README replaces prior selected overview docs
Web application for tracking Gin Rummy games between two players (Brady and Jenny) with real-time score updates. Replaces manual Google Sheets tracking with a modern web interface featuring authentication, offline support, comprehensive statistics, and automated weekly backups.
Now features a Public Demo Mode that allows visitors to explore the application with mock data while protecting real user information.
- π App URL: https://gin.theespeys.com
- π Netlify Dashboard: gintracker
- ποΈ Firebase Console: gintracker-54301 project
- π Firebase Auth: Google OAuth with email restrictions
- π GitHub Repo: https://github.com/bradyespey/gin-tracker
- πΎ Backups: Automated weekly backups via GitHub Actions (data-backups/games.json)
Visitors can access the site without logging in to experience the full UI:
- Mock Data: Uses in-memory mock games to populate the dashboard.
- Privacy First: Real user names are masked as "User 1" and "User 2".
- Sandbox Environment: Visitors can add, edit, and delete games locally without affecting the real database. Changes are reset on refresh.
- Full Scope: Includes access to the Dashboard, New Game form, and Game List with filtering and sorting.
- Real-Time Tracking: Log game results instantly.
- βοΈ Frontend: React 18 + TypeScript + Vite + Tailwind CSS
- ποΈ Backend: Firebase (Firestore + Auth)
- π Auth: Firebase Google OAuth with email restrictions
- π± Offline: IndexedDB + Service Workers for offline functionality
- π Hosting: Netlify (frontend) + Firebase (backend)
- π¨ UI: Lucide React icons + responsive design with dark mode
- π Backups: GitHub Actions + Firebase Admin SDK
git clone https://github.com/bradyespey/gin-tracker
cd GinTracker
npm install
# Install 1Password CLI (if not already installed)
brew install --cask 1password-cli
# Set up 1Password Environment (see Environment section below)
npm run devAll projects use 1Password Developer Environments for local environment variables. This allows seamless setup on any computer without managing local .env files.
-
Enable 1Password Developer:
- Open 1Password desktop app
- Settings β Developer β Turn on "Show 1Password Developer experience"
-
Create Environment:
- Go to Developer β Environments (Espey Family account)
- Create new environment:
GinTracker - Import
.envfile or add variables manually
-
Install 1Password CLI:
brew install --cask 1password-cli
-
Run Project:
npm run dev
- The
devscript usesop run --env-file=.env -- viteto automatically load variables from 1Password - No local
.envfile needed
- The
All variables should be stored in your 1Password Environment:
# Firebase Configuration
VITE_FIREBASE_API_KEY=YOUR_API_KEY
VITE_FIREBASE_AUTH_DOMAIN=YOUR_PROJECT.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=YOUR_PROJECT_ID
VITE_FIREBASE_STORAGE_BUCKET=YOUR_PROJECT.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=YOUR_SENDER_ID
VITE_FIREBASE_APP_ID=YOUR_APP_ID
# Authentication
VITE_ALLOWED_EMAILS=YOUR_EMAIL,YOUR_EMAIL_2,YOUR_EMAIL_3Firebase Setup:
- Create Firebase project and enable Authentication (Google provider)
- Create Firestore database (production mode, us-south1 region)
- Deploy Firestore security rules:
firebase deploy --only firestore:rules - Add authorized domains: localhost, gintracker.netlify.app, gin.theespeys.com
GitHub Secrets (for automated backups):
FIREBASE_SERVICE_ACCOUNT: Full JSON content from Firebase Service Account key
- π Debug Mode:
npm run devwith browser dev tools for local development - π Production Mode: Deployed via Netlify with optimized builds
- π± Offline Mode: Service Worker enables full offline functionality with IndexedDB storage
- π§ Development:
npm run devβ Start local development server (port 5179) - ποΈ Build:
npm run buildβ TypeScript compilation + Vite build - π Lint:
npm run lintβ ESLint code checking - π Preview:
npm run previewβ Preview production build locally - π Sync: Automatic online/offline data synchronization
- π¦ Deploy Watch:
npm run deploy:watchβ Push to GitHub and monitor Netlify build
- π Frontend: Automatic via GitHub integration to Netlify
- π¦ Build Command:
npm run build - π Publish Directory:
dist - π Domains: gin.theespeys.com (primary), gintracker.netlify.app
- π₯ Firestore Rules: Deploy with
firebase deploy --only firestore:rules - πΌοΈ Build Image: Ubuntu Noble 24.04 (upgraded from Focal 20.04)
- π Dashboard (
/gin): Game statistics, recent games, and score summaries - π New Game (
/gin/new): Log new Gin Rummy games with scoring options - π Rules (
/gin/rules): Gin Rummy rules and scoring explanations - π Auth Callback (
/auth/callback): OAuth flow completion handler
GinTracker/
βββ src/
β βββ components/ # UI components (GameList, GameForm, AuthButton)
β βββ pages/ # App pages (Dashboard, NewGame, Rules)
β βββ context/ # AuthContext for Firebase Auth
β βββ hooks/ # Custom hooks (usePagination, useSortedGames)
β βββ lib/ # Core utilities (gameLogic, firebase, syncManager, indexedDB)
β βββ services/ # API services (gameService with offline support)
β βββ types/ # TypeScript type definitions
β βββ utils/ # Helper functions (dateUtils, gameUtils, numberFormat)
βββ scripts/
β βββ backup.js # Firebase backup script (GitHub Actions)
β βββ deploy-and-watch.sh # Netlify build monitoring script
βββ .github/workflows/
β βββ backup.yml # Weekly automated backup workflow
βββ data-backups/ # Automated backup storage (git-tracked)
βββ firestore.rules # Firestore security rules
βββ firebase.json # Firebase project configuration
βββ netlify.toml # Netlify deployment configuration
fetchGames(): Retrieves games from Firestore, merges with local pending gamesaddGame(): Creates new game (online to Firestore, offline to IndexedDB)updateGame(): Updates existing game with sync supportdeleteGame(): Deletes game with offline fallback
syncGames(): Syncs pending local games to Firestore when onlinetriggerSync(): Manually triggers sync operation
calculateScore(): Calculates game score (Gin vs Knock scenarios)calculateStats(): Computes aggregate statistics (wins, averages, percentages)
initDB(): Initializes IndexedDB databasesaveGameLocally(): Saves game to local storagegetLocalGames(): Retrieves all local gamesupdateGameLocally(): Updates local gamedeleteGameLocally(): Deletes local gamegetNextGameNumber(): Calculates next game number for offline games
Weekly automated backups run via GitHub Actions every Monday at midnight Central Time:
- Location:
data-backups/games.json(committed to Git) - Manual Trigger: GitHub Actions β Weekly Data Backup β Run workflow
- Verification: Check commit history for "Automated data backup: YYYY-MM-DD"
- Restoration: See
Guides/Firebase Data Backup Guide.mdfor restore process
- π Auth Issues: Verify Firebase authorized domains include deployed URLs
- π± Offline Sync: Check IndexedDB storage and Service Worker registration
- ποΈ Database: Firestore rules require authentication (deploy with
firebase deploy --only firestore:rules) - π¨ Styling: Tailwind CSS with dark mode based on system preferences
- π Game Logic: Scoring calculations handle Gin vs Knock scenarios with undercuts
- π Data Sync: Automatic sync between online Firestore and offline IndexedDB
- πΎ Backups: Verify GitHub Actions workflow runs successfully and commits appear
Read this README, scan the repo, prioritize core functions and env-safe areas, keep env and rules aligned with this file. Focus on game scoring logic, offline sync functionality, Firebase authentication flow, and backup system. Firestore rules enforce authentication-only access (email restrictions handled in app code).