Skip to content

jyancey/job-tracker-frontend

Repository files navigation

Job Tracker

Build Stats Deploy Badge Latest Release

A local-first, privacy-focused job application tracker built with Next.js, React, TypeScript, and SQLite.

Track your search like a pipeline, not a spreadsheet. Manage opportunities, follow-ups, and monitor momentum from one workspace—all without leaving your browser.

Features

  • Local-First Storage — All data stays on your device in a real SQLite file (data/job-tracker.sqlite by default)
  • Privacy — No cloud dependencies, data remains local on disk
  • Full CRUD — Add, edit, view, and delete job applications
  • Smart Filtering — Status, date range, salary range, and contact person filters
  • Sortable Columns — Click headers to sort by company, role, status, dates
  • Bulk Operations — Select multiple jobs, delete across filters with visibility controls
  • Multiple Views — Analytics (default), Table, Kanban board, Calendar, Today, and This Week
  • AI Re-Analyze — Re-run AI scoring directly from the job detail modal when you want a refreshed analysis
  • Import/Export — JSON, CSV export; JSON import with merge strategies (append/upsert/replace)
  • Pagination — Configurable page sizes (5/10/20) for large datasets
  • Overdue Tracking — Quick metric shortcut to find jobs requiring follow-up
  • Storage Logging — Debug visibility with console logs and downloadable .log files
  • Refined UI Theme — Clean, paper-toned interface with productivity-focused layout

Getting Started

Prerequisites

  • Node.js 20+ and pnpm

Installation

# Install dependencies
pnpm install

# Start development server (http://127.0.0.1:4173)
pnpm dev

# Run tests
pnpm test:run

# Build for production
pnpm build

# Preview/serve the production build (requires pnpm build first)
pnpm serve

You can also run as a macOS daemon. See docs/DAEMON_SETUP.md for instructions.

Development

Project Structure

app/
  ├── layout.tsx              # Next.js root layout
  ├── page.tsx                # Root page (renders AppClient)
  ├── AppClient.tsx           # 'use client' bridge to src/App
  ├── globals.css             # Global styles
  └── api/
      ├── config/route.ts     # POST /api/config
      ├── profile/route.ts    # POST /api/profile
      ├── jobs/route.ts       # GET/PUT /api/jobs
      └── database/
          ├── create/route.ts # POST /api/database/create
          ├── info/route.ts   # GET /api/database/info
          └── test/route.ts   # GET /api/database/test

backend/
  ├── data/                   # SQLite schema and default profile/config data
  ├── jobStore.ts             # Lazy-init SQLite store proxy (used by API routes)
  ├── sqliteStore.ts          # Public SQLite facade used by the rest of the app
  ├── sqlite/                 # DB connection, schema, and repository modules
  └── jobValidation.ts        # Backend job payload validation

src/
  ├── App.tsx                 # Main app orchestrator
  ├── domain.ts               # Core types: Job, JobDraft, JobStatus, JobPriority
  ├── components/             # Reusable UI components (table, kanban, form, toast, AI config)
  ├── hooks/                  # Custom state and behavior hooks (~20 specialized hooks)
  ├── services/               # Business logic (scoring, notifications, storage, AI, import/export)
  ├── storage/                # Storage adapters (API client, localStorage fallback, logger)
  ├── views/                  # Page-level view components (Analytics, Table, Calendar, etc.)
  │   ├── settings/           # Extracted settings sections
  │   └── table/              # Table-specific view pieces
  ├── features/               # Self-contained feature modules (analytics, backup, savedViews, search, tasks)
  ├── types/                  # Shared TypeScript types (ai, filters, errors, componentProps)
  ├── utils/                  # Date, accessibility, drag/drop, formatting helpers
  └── test/setup.ts           # Vitest setup

docs/
  ├── ARCHITECTURE.md         # Technical architecture overview
  ├── DAEMON_SETUP.md         # macOS daemon setup guide
  ├── PERFORMANCE_BASELINE.md # Performance measurement framework
  ├── REFACTORING_ANALYSIS.md # Code quality audit
  ├── REFACTORING_STATUS.md   # Refactoring progress tracker
  ├── releases/               # Historical release notes (latest: v2.7.4)
  ├── planning/               # Roadmaps and release plans (v2.7, v2.8)
  └── safari-plugin/          # Safari browser plugin architecture and planning

scripts/
  ├── generate-version.ts     # Auto-generates src/version.ts from git metadata
  ├── require-pnpm.mjs        # Fails installs launched without pnpm
  ├── withColor.ts            # Forces colored CLI output for repo scripts
  ├── package-standalone.sh   # Builds standalone deployment bundle
  └── launchd/                # macOS launchd helpers (plist template, install/uninstall scripts)

e2e/                          # Playwright end-to-end tests
sample-data/                  # Demo JSON files for import testing
public/                       # Static assets (favicon, logo)

Testing

Tests are run with Vitest, React Testing Library, and Playwright:

# Run tests in watch mode
pnpm test

# Run tests once
pnpm test:run

# Run coverage
pnpm test:coverage

# Run end-to-end tests
pnpm test:e2e

The test suite covers app workflows, hooks, backend repositories and API flows, services, and end-to-end profile/settings persistence scenarios. For one-off runs, use pnpm exec vitest run src/path/to/file.test.ts or pnpm exec playwright test e2e/path/to/spec.ts.

Building

# Production build (optimized, minified, tree-shaken)
pnpm build

# Next.js outputs server/client artifacts in .next/
# Start production server with:
pnpm start

CI/CD Pipeline (Gitea Actions)

Workflow files are located in .gitea/workflows/:

1. Build & Test (build-test.yml)

Triggers on: push to main/develop, pull_request against main/develop

Steps:

  • Build frontend CI images with Podman Compose
  • Run lint, tests, and build inside each container build pipeline
  • Package standalone and OCI artifacts from generated images
  • Upload build artifacts (7-day retention)

2. Release (release.yml)

Triggers on: git tag (e.g., git tag v1.0.0 && git push origin v1.0.0)

Steps:

  • Build and test frontend service inside Podman using Podman Compose
  • Package source tarball (.tar.gz)
  • Package frontend standalone distribution archives (.zip and .tar.gz)
  • Export frontend OCI image archives (.tar.gz)
  • Generate release notes
  • Upload packaged artifacts for download from workflow run

Artifacts:

  • job-tracker-vX.Y.Z-source.tar.gz — Source code archive
  • job-tracker-vX.Y.Z-standalone.zip — Standalone Next.js deployment bundle with server.js, .next/static, public/, and macos/ startup helpers
  • job-tracker-vX.Y.Z-standalone.tar.gz — Tarball version of the standalone deployment bundle
  • job-tracker-vX.Y.Z-oci-image.tar.gz — Podman-built OCI image archive for frontend runtime deployment

Manual local release packaging with Podman:

pnpm run release:podman -- vX.Y.Z

3. Deploy (deploy.yml)

Triggers on: Successful Build & Test workflow on main, or manual workflow_dispatch

Steps:

  • Build deployment image with Podman Compose
  • Extract deployment bundle from the image with metadata
  • Upload to artifacts (30-day retention)

Status: Produces a standalone Next.js deployment artifact for a Node-capable target or the included macOS launchd helper scripts

Manual local deployment bundle packaging with Podman:

pnpm run deploy:podman -- vX.Y.Z deploy

Usage Tips

Adding a Job

  1. Fill out the "Add Job" form (Company, Role, Status, etc.)
  2. Click Add Job to add to pipeline
  3. Metric cards update instantly

Re-Analyzing a Job

  1. Open a job from table/kanban/calendar
  2. In the job modal, click Re-Analyze
  3. AI scoring runs again in the background and refreshes the score fields

Smart Filtering

  • Status Filter — Quick drop-down for All statuses, Overdue Follow-ups, Applied, Phone Screen, Interview, Offer, Rejected, Withdrawn
  • Advanced Filters — Click "Filters" to refine by:
    • Application date range
    • Salary range
    • Contact person name
  • Overdue Follow-ups — Click "View" in the overdue metric card to see jobs past their due date

Bulk Operations

  1. Select jobs via checkboxes (or select-all)
  2. Manage selections across pagination
  3. Click "Delete Selected on Page" — only visible selected rows are removed
  4. Hidden selections preserved and reported

Import/Export

  • Export — JSON or CSV from toolbar; CSV opens in Excel/Sheets
  • Import — JSON file with merge strategy:
    • Append — Add imported jobs to existing
    • Upsert — Update existing by ID, add new ones
    • Replace — Clear all, keep only imported

Storage & Debugging

  • Job data is stored in data/job-tracker.sqlite (or JOB_TRACKER_DB_PATH if set)
  • The SQLite file can be opened with DB Browser for SQLite, sqlite3, and other compatible readers
  • Click Export DB Logs in form panel to download debug logs
  • Logs include: API operations, timing, error details
  • Enable debug mode: localStorage.setItem('job-tracker.debug', 'true') in console

Version Metadata

  • src/version.ts is auto-generated by scripts/generate-version.ts
  • Generation runs before dev, build, test:run, and test:coverage
  • App UI shows current version badge for quick runtime verification

Browser Compatibility

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 15+

Tech Stack

Layer Technology
UI Framework React 19
Language TypeScript 5
Build Tool Next.js 16 (App Router)
Database SQLite (file-backed via better-sqlite3)
Testing Vitest + React Testing Library + userEvent
Linting ESLint 9
CI/CD Gitea Actions

Performance

  • Bundle Size: App bundle only (SQLite engine runs server-side)
  • Startup: <1s (network) + storage hydration
  • Page Transitions: Instant (React in-browser)
  • Pagination: Optimized for 1000+ jobs

Privacy & Data Ownership

  • No analytics tracking — Zero telemetry
  • No cloud sync — Data stays on your device
  • Full export capability — JSON, CSV at any time
  • SQLite portability — Open the .sqlite file with standard SQLite tools

License

This project is licensed under a custom non-commercial license.

See LICENSE for details. Commercial use is not permitted without prior written permission.

Support & Contribution

Report issues, suggest features, or contribute pull requests on the project repository.


Last Updated: March 24, 2026
Current Release Tag: v2.7.4

About

A local-first, privacy-focused job application tracking dashboard built with React, TypeScript, and SQLite.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors