Skip to content

sambai-dev/job-tracker-app

Repository files navigation

Job Tracker

A modern, full-stack job application tracking system that transforms your job search chaos into organized success.

Project Status Next.js React TypeScript MongoDB Tailwind CSS

View Live Demo · GitHub Repository · Developer Portfolio


Overview

Job Tracker solves the universal frustration of managing job applications across dozens of tabs, spreadsheets, and sticky notes. Built for job seekers who want to focus on landing their dream role—not on administrative chaos.

Why Job Tracker?

  • Visual Pipeline Management — See your entire job search at a glance with a beautiful Kanban board
  • Zero Friction Workflow — Drag-and-drop interface with keyboard shortcuts for power users
  • Interview Scheduling — Built-in calendar integration with Google Calendar sync and email reminders
  • Job Discovery — Search and import jobs directly within your dashboard
  • Privacy First — Your job search data stays yours with secure authentication

Tech Stack

Frontend

Backend

Developer Experience

  • ESLint 9 - Code linting with flat config
  • Prettier - Code formatting with Tailwind plugin
  • SWR - React data fetching
  • Hybrid Caching - Server Components use cache + Client SWR
  • Path aliases (@/*) for clean imports

Architecture & Performance

Hybrid Caching Strategy

This project utilizes a cutting-edge hybrid data fetching architecture leveraging Next.js 16's experimental cacheComponents and React 19 features:

  • Server-Side: Critical data (like Kanban boards) is pre-fetched on the server using the use cache directive, ensuring instant initial HTML render.
  • Client-Side: Data is passed as fallbackData to SWR hooks, allowing for immediate hydration without layout shift or loading spinners.
  • Optimistic Updates: UI interactions (drag-and-drop) update instantly while validating in the background.

Type Safety & Standards

  • Strict TypeScript: No any types allowed. All MongoDB documents are serialized with generic utilities (serializeDoc<T>) to ensure type safety across the network boundary.
  • React 19 Compliance: All components are refactored for React 19 purity rules (no side effects in render) and proper ref usage.
  • Modular Design: Large features like the Calendar are broken down into sub-components (CalendarHeader, DayCell) for maintainability.
  • Query Projections: All dashboard queries use strict .select() projections to prevent over-fetching heavy text fields (descriptions, notes) — only the 16 fields needed for UI rendering are transferred.

Features

Kanban Dashboard

  • Drag-and-drop job cards between customizable status columns (Applied, Interview, Offer, Rejected, etc.)
  • Smart priority automation — Automatically upgrades priority when moving to high-stakes columns (e.g., Interview → High)
  • Priority tagging system — Mark urgent opportunities as High, Medium, or Low priority
  • Full keyboard navigation — Power user shortcuts for every action (see Keyboard Shortcuts below)
  • Command palette — Lightning-fast search and actions with Cmd/Ctrl + K
  • Quick search — Press / to instantly focus the search bar
  • Real-time optimistic updates — Changes reflect instantly with SWR caching
  • Responsive design — Fully functional on desktop and mobile devices

AI Resume Tailoring

  • Context-Aware Generation — Uses your base profile and the job description to generate highly targeted resumes using the Vercel AI SDK
  • Inline Editor — Preview and edit the generated markdown directly in the browser
  • 1-Click PDF Export — Download print-ready, cleanly formatted resumes instantly
  • Persistent Storage — Tailored resumes are saved directly to the job card in MongoDB

Calendar Integration

  • Interview scheduling with date, time, and timezone support
  • Custom time picker with 30-minute intervals (8 AM - 7 PM) for better UX
  • Monthly calendar view of all upcoming interviews with at-a-glance details
  • Interview conflict detection — See all scheduled interviews on the same day
  • Google Calendar sync — Optional incremental OAuth for seamless two-way integration
  • Automated email reminders via Resend:
    • 24-hour interview reminders
    • 7-day follow-up reminders after application

Job Discovery

  • Integrated Job Search — Find roles without leaving the app
  • Smart Filtering — Filter by Junior, Intermediate, or Senior roles with optimized queries
  • One-Click Import — Add jobs directly to your pipeline
  • Location Presets — Quick toggles for major tech hubs (NZ/AU)
  • Search State Persistence — Your active search, exact results, and UI filters are durably synced to MongoDB, auto-restoring your session across devices. Stale caches automatically trigger a background scrape.

Job Intelligence & Scraping

The system transforms raw job postings into structured, actionable insights using a multi-tiered analysis engine.

1. Scraping Architecture

The app uses Cheerio to parse LinkedIn job postings, employing multiple fallback selectors to ensure resilience against layout changes. It extracts:

  • Title & Company: Basic role identification.
  • Description: The primary source for deep seniority and tech-stack analysis.
  • Search Metadata: Real-time extraction of required years (e.g., "1-3 years") and descriptive "snippets" directly from search result cards.

Note: Scraping relies on public/guest endpoints and replicates a standard browser behavior (User-Agent spoofing) to stay compliant with rate limits. It is designed for low-volume, personal use.

2. Seniority Classification

A tiered decision model combines explicit keywords with numeric experience ranges:

Experience (Avg) Example Assigned Level
< 2 years "0-2 years" Junior
2 – 4.9 years "2-7 years" Intermediate
5 – 9.9 years "5+ years" Senior
10+ years "10+ years" Lead

Keyword Overrides: Explicit titles like "Principal", "Intern", or "Senior" take precedence over numeric ranges to ensure accuracy.

3. Role Type Detection

A weighted scoring function (classifyRoleType) identifies the development track by scanning for exact-word tech keywords with strict word boundaries:

  • Frontend: React, Vue, HTML, CSS, JavaScript, TypeScript, Web Developer.
  • Backend: Node, Python, Java, C#, .NET, SQL, Database, API, Server.
  • Fullstack: High scores across both categories.

4. Smart "Noise" Filtering

The Junior filter is tuned specifically for the tech industry to catch "hidden" junior roles while suppressing senior noise:

  • Auto-Include: Roles with "Junior", "Grad", or "Intern" in the title.
  • Conditional Include: Generic titles (e.g., "Software Engineer") only appear if they mention Frontend Tech (React, JS, etc.) or Low Years in the card snippet.
  • Auto-Exclude: Roles with obvious senior keywords (Lead, Principal, etc.).

5. UI Reflection & Metadata

Results are surfaced as professional, color-coded badges and auto-populated notes in the tracker:

Senior (5-10 years • Frontend) ✓

Confidence Indicators:

  • High: Exact keyword or clear numeric match.
  • ~ Medium: Inferred from partial signals.
  • ? Low: Best guess based on weak evidence.

Authentication

  • Google OAuth — Sign in with your Google account
  • Email/Password — Traditional authentication option
  • Protected routes — Server-side session validation
  • Rate limiting — API protection with Upstash Redis

Modern UI/UX

  • Crisp monochrome theme — Professional, high-contrast aesthetic with Zinc color palette
  • Dark/Light theme — Full theme support that follows system preference
  • Smooth animations — GSAP and Framer Motion powered interactions
  • Accessible components — Built on Radix UI primitives with shadcn/ui
  • Rock-solid layout stability — Custom scroll locking implementation prevents layout shifts
  • Smooth scrolling — Lenis scroll experience

Keyboard Shortcuts

Boost your productivity with comprehensive keyboard shortcuts:

Global Shortcuts

  • Cmd/Ctrl + K — Open command palette
  • / — Focus search bar
  • ? — Show keyboard shortcuts help
  • Shift + T — Toggle dark/light theme
  • ESC — Close dialogs / Clear search
  • Shift + K — Switch to Kanban view
  • Shift + L — Switch to List view
  • Shift + C — Switch to Calendar view
  • Shift + J — Switch to Job Search view
  • C — Create new job
  • Ctrl + Enter — Trigger search (in Search tab)

Navigation

  • Quick view switching without leaving the keyboard
  • Seamless search while browsing jobs
  • Instant dialog dismissal

Demo

Live Application: job-tracker-app-cyan.vercel.app

Screenshots

Landing Page Modern landing page with clean design and clear call-to-action

Dashboard Kanban View Kanban board with drag-and-drop job cards and priority indicators

Calendar View Monthly calendar showing scheduled interviews with company details


Getting Started

Prerequisites

  • Node.js 18.17.0 or higher
  • npm 9.x or higher (or pnpm/yarn)
  • MongoDB Atlas account (free tier available)
  • Google Cloud Console project for OAuth (setup guide)

Installation

  1. Clone the repository

    git clone https://github.com/sambai-dev/job-tracker-app.git
    cd job-tracker-app
  2. Install dependencies

    npm install
  3. Configure environment variables

    cp .env.example .env.local
  4. Edit .env.local with your credentials:

    # MongoDB Connection
    MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database>?retryWrites=true&w=majority
    MONGO_DB_NAME=job-tracker
    
    # Authentication (required)
    BETTER_AUTH_SECRET=<generate with: openssl rand -base64 32>
    BETTER_AUTH_URL=http://localhost:3000
    NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3000
    
    # Google OAuth (required)
    GOOGLE_CLIENT_ID=<from Google Cloud Console>
    GOOGLE_CLIENT_SECRET=<from Google Cloud Console>
    GOOGLE_CALENDAR_ENABLED=true
    
    # Rate Limiting (optional for development)
    UPSTASH_REDIS_REST_URL=<from Upstash Console>
    UPSTASH_REDIS_REST_TOKEN=<from Upstash Console>
    
    # Email Notifications (optional)
    RESEND_API_KEY=re_...
    FROM_EMAIL=reminders@your-domain.com
    
    # Cron Jobs (optional)
    CRON_SECRET=<generate with: openssl rand -hex 32>
  5. Start the development server

    npm run dev
  6. Open your browser at http://localhost:3000


Project Structure

job-tracker-app/
├── src/
│   ├── app/                      # Next.js App Router
│   │   ├── api/                  # API routes
│   │   │   ├── auth/             # Authentication endpoints
│   │   │   ├── boards/           # Board CRUD operations
│   │   │   ├── calendar/         # Calendar & Google sync
│   │   │   ├── columns/          # Column management
│   │   │   ├── cron/             # Scheduled jobs (reminders)
│   │   │   ├── jobs/             # Job application CRUD
│   │   │   ├── job-search/       # Job search API
│   │   │   └── parse-job/        # Job URL parsing
│   │   ├── dashboard/            # Protected dashboard route
│   │   ├── sign-in/              # Authentication pages
│   │   ├── sign-up/
│   │   ├── privacy-policy/
│   │   └── terms-of-use/
│   │
│   ├── components/               # Shared UI components
│   │   ├── ui/                   # shadcn/ui primitives (28 components)
│   │   ├── layout/               # Navbar, footer, wrappers
│   │   ├── dashboard/            # Dashboard-specific components
│   │   └── motion/               # Animation components
│   │
│   ├── features/                 # Feature modules
│   │   ├── dashboard/            # Kanban board & job management
│   │   │   ├── components/       # JobCard, KanbanColumn, Calendar/
│   │   │   ├── data/             # Server-side data fetching (use cache)
│   │   │   ├── hooks/            # useBoards, useJobs
│   │   │   └── actions/          # Server actions
│   │   └── landing/              # Marketing landing page
│   │       └── components/       # Hero, Features, FAQ, etc.
│   │       └── data/             # Landing page static data
│   │
│   ├── lib/                      # Core infrastructure
│   │   ├── auth/                 # better-auth configuration
│   │   ├── db/                   # MongoDB connection
│   │   ├── models/               # Mongoose schemas
│   │   ├── schemas/              # Zod validation schemas
│   │   ├── services/             # Business logic services
│   │   ├── email/                # Email templates & sending
│   │   └── utils/                # Shared utilities
│   │
│   ├── hooks/                    # Global custom hooks
│   └── types/                    # TypeScript definitions
│
├── public/                       # Static assets
├── .env.example                  # Environment template
├── next.config.ts                # Next.js configuration
└── package.json

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                        Frontend                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   Landing   │  │  Dashboard  │  │   Auth Pages        │  │
│  │   (GSAP)    │  │  (Kanban)   │  │   (better-auth)     │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                     API Layer (Next.js)                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────────┐  │
│  │  /auth   │  │  /jobs   │  │ /boards  │  │  /calendar  │  │
│  │          │  │ /search  │  │          │  │             │  │
│  └──────────┘  └──────────┘  └──────────┘  └─────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                     Data Layer                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   MongoDB   │  │   Upstash   │  │       Resend        │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Security & Architecture

We prioritize security best practices, particularly regarding data isolation in a multi-tenant environment.

Secure Authorization (IDOR Prevention)

The application implements strict ownership verification to prevent Insecure Direct Object Reference (IDOR) vulnerabilities. Critical operations, such as column updates, verified that:

  1. The user is authenticated.
  2. The user owns the parent board that the column belongs to.

Implementation Example:

// src/app/api/columns/[columnId]/route.ts

// 1. Verify Authentication
if (!session?.user)
  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

// 2. Lookup Resource & Parent
const column = await Column.findById(columnId);
const board = await Board.findById(column.boardId);

// 3. Strict Ownership Check
// Prevents User A from modifying User B's columns by guessing IDs
if (!board || board.userId !== session.user.id) {
  return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}

Production Logging

We utilize a structured logging system that prevents sensitive internal state (like database connection details) from leaking into production logs, while maintaining observability.

Engineering Highlights

Lazy Authentication Pattern

To optimize build times and prevent connection errors during static generation, the application uses a lazy initialization pattern for the database and auth provider. This ensures MongoDB connections are only established when a request is actually processed at runtime, preventing "ECONNREFUSED" errors during Vercel builds.

O(1) Drag-and-Drop Ordering

Kanban reordering uses a fractional midpoint algorithm instead of the common O(N) approach of shifting all adjacent items:

// Calculate a float exactly between the two neighbors
const prevOrder = filteredTargetJobs[newOrder - 1].order;
const nextOrder = filteredTargetJobs[newOrder].order;
calculatedOrder = (prevOrder + nextOrder) / 2;

// Single document update — O(1) writes, no transactions needed
job.order = calculatedOrder;
await job.save();

This means every drag-and-drop updates exactly one document regardless of column size, eliminating write amplification and the need for multi-document transactions.

Resilient Data Fetching

We utilize SWR with a custom exponential backoff strategy for network resilience:

  • 4xx Errors: Fail fast (e.g., don't retry Unauthorized requests)
  • 5xx Errors: Retry with delays of 1s, 2s, 4s to allow server recovery without overwhelming it.

Key Technical Decisions

Why Better Auth?

Unlike hosted solutions (Auth0/Clerk) that silo user data, Better Auth gives us full ownership of the user database while maintaining strict security standards.

  • Type Safety: End-to-end TypeScript support matches our strict schema requirements.
  • Plugins: Modular architecture allows adding features like "Two Factor" or "Admin" without bloat.
  • Privacy: User data never leaves our controlled MongoDB instance.

Why Upstash Redis?

Traditional Redis requires persistent TCP connections, which are problematic in serverless environments like Vercel. Upstash provides a REST-based Redis compatible with Edge runtimes.

  • Stateless: Perfect for Next.js API rate limiting middleware.
  • Scalable: Per-request pricing fits the traffic pattern of a job tracker (bursty usage).
  • Zero Latency Cold Starts: HTTP-based protocol avoids connection pool handshake overhead.

Why dnd-kit?

We chose dnd-kit over older libraries (react-beautiful-dnd) for its modern, modular architecture.

  • Accessibility: First-class support for keyboard interactions and screen readers.
  • Extensibility: Hook-based API allows custom sensors and modifiers (needed for our column/card nested drag logic).
  • Performance: Minimized re-renders through virtual DOM abstractions.

Why Zod?

We use Zod for runtime schema validation to bridge the gap between static TypeScript types and dynamic API inputs.

  • Single Source of Truth: We infer TypeScript types directly from Zod schemas, ensuring API validation logic and type definitions never drift out of sync.
  • Developer Experience: "Fail-fast" error messages make backend debugging significantly easier.

Database Schema

Collections

boards

{
  _id: ObjectId,
  userId: string,           // Owner reference
  name: string,             // Board name
  columns: ObjectId[],      // Ordered column references
  isDefault: boolean,       // Default board flag
  createdAt: Date,
  updatedAt: Date
}

columns

{
  _id: ObjectId,
  boardId: ObjectId,        // Parent board reference
  name: string,             // e.g., "Applied", "Interview", "Offer"
  order: number,            // Display order
  createdAt: Date,
  updatedAt: Date
}

jobapplications

{
  _id: ObjectId,
  userId: string,           // Owner reference
  columnId: ObjectId,       // Parent column reference
  company: string,
  position: string,
  location?: string,
  salary?: string,
  url?: string,
  notes?: string,
  priority: "high" | "medium" | "low",
  order: number,            // Position within column
  interviewDate?: Date,
  interviewTime?: string,
  interviewTimezone?: string,
  reminderSent?: boolean,
  followUpSent?: boolean,
  createdAt: Date,
  updatedAt: Date
}

API Routes

Method Endpoint Description
GET/POST /api/auth/* Authentication (better-auth)
GET /api/boards List user's boards
POST /api/boards Create new board
GET /api/jobs List jobs (with column filter)
POST /api/jobs Create job application
PATCH /api/jobs/[id] Update job application
DELETE /api/jobs/[id] Delete job application
GET /api/columns List columns for a board
POST /api/columns Create new column
GET /api/calendar/events Get calendar events
POST /api/calendar/sync Sync with Google Calendar
POST /api/parse-job Parse job details from URL
POST /api/cron/reminders Trigger email reminders

Development

Available Scripts

Script Command Description
Development npm run dev Start dev server at localhost:3000
Build npm run build Create production build
Start npm run start Run production server
Lint npm run lint Run ESLint checks
Lint Fix npm run lint:fix Auto-fix ESLint issues
Format npm run format Format with Prettier
Format Check npm run format:check Check code formatting
Test npm run test Run Vitest in watch mode
Test CI npm run test:ci Run tests with coverage report

Code Quality

This project uses:

  • ESLint 9 with flat config for modern linting
  • Prettier with Tailwind CSS plugin for consistent formatting
  • TypeScript strict mode for type safety
  • Zod for runtime validation of API inputs
  • Vitest with v8 coverage for unit and integration testing (96%+ model coverage)

Path Aliases

// Instead of relative imports:
import { Button } from "../../../components/ui/button";

// Use path aliases:
import { Button } from "@/components/ui/button";

Deployment

Vercel (Recommended)

  1. Push to GitHub

    git add .
    git commit -m "Initial commit"
    git push origin main
  2. Import to Vercel

    • Visit vercel.com/new
    • Import your GitHub repository
    • Vercel auto-detects Next.js settings
  3. Configure Environment Variables In Vercel dashboard, go to Settings > Environment Variables and add:

  4. Update Google OAuth In Google Cloud Console, add your Vercel domain to authorized redirect URIs: https://your-domain.vercel.app/api/auth/callback/google

  5. Deploy Vercel automatically deploys on every push to main.

Cron Jobs (Email Reminders)

For automated email reminders, configure a cron job to call: POST https://your-domain.vercel.app/api/cron/reminders Header: Authorization: Bearer <CRON_SECRET>

Vercel Cron or external services like cron-job.org work well.


Contributing

Contributions are welcome for bug fixes and improvements. Please follow these guidelines:

  1. Getting Started

    • Fork the repository
    • Create a feature branch: git checkout -b feature/your-feature
    • Make your changes
    • Run linting and formatting: npm run lint && npm run format
    • Commit with conventional commits: git commit -m "feat: add new feature"
    • Push and open a Pull Request
  2. Code Standards

    • Follow existing code patterns and conventions
    • Write TypeScript with proper types (avoid any)
    • Use Zod for API input validation
    • Keep components small and focused
    • Add comments for complex logic
  3. Pull Request Process

    • Ensure your code passes linting and type checks
    • Update documentation if needed
    • Provide a clear description of changes
    • Reference any related issues

Changelog

Recent Updates (March 2026)

AI Tailored Resume Generator

  • Vercel AI SDK Integration: Added a powerful streaming AI generator to tailor resumes specifically to scraped job descriptions.
  • Data Context Viewer: AI strictly uses facts from your base UserProfile.resumeText to prevent hallucinations and enforce factual accuracy.
  • Inline Editing & Markdown: Generated resumes are editable directly in the UI with a markdown toggle powered by @tailwindcss/typography.
  • PDF Export: Added seamless 1-click PDF exporting and clipboard copying for generated resumes.
  • Save-on-Complete: Tailored resumes are non-blockingly saved directly to their respective JobApplication documents.

Job Search State Persistence

  • MongoDB Auto-Search: Refactored the "Find Roles" tab to durably sync job search results and UI filters (Remote, Experience, Age) to the UserProfile schema.
  • Hydration Engine: The useJobSearch hook natively bridges MongoDB state down to the UI dropdowns, instantly restoring search contexts across devices.
  • Stale Cache Auto-Trigger: Automatically fires off a fresh background scrape if the local database cache is older than 6 hours.

Recent Updates (February 2026)

Security & Performance Hardening

  • Fixed Unbounded Array Vulnerability: Removed the jobApplications array from the Column schema to prevent document bloat and potential MongoDB 16MB document limit crashes at scale.
  • O(1) Drag-and-Drop: Replaced O(N) transactional $inc shifting with fractional midpoint ordering — each reorder now updates exactly one document.
  • Query Projections: Added strict .select() projections to all board-fetching queries, excluding heavy text fields (description, notes) from dashboard payloads.
  • Removed Unnecessary Transactions: Simplified single-document operations (job delete, column move) by removing costly transaction wrappers.

Dual-Filtering & UI Modernization

Core Architecture

  • Dual-Filtering System: Separated "Raw" job data vs "Inferred" seniority data with confidence scores.
  • Strict Schema: Updated Job schema for strict seniority levels (Junior, Intermediate, Senior, Lead) and structured years (min/max).
  • Modular Refactor: Extracted JobSearchPanel into 6 sub-components (Bar, Filters, Stats, Results, Card, EmptyState) and centralized regex patterns.

UI/UX Overhaul

  • Smart Components: Added MismatchBadge for data discrepancies and "Smart Empty States" with context-aware suggestions.
  • Visual Polish:
    • Increased truncation limits (300px) and added location deduplication.
    • Refined seniority badge colors with optimized dark-mode contrast.
    • Unified search bar into a single elevated unit.
    • Swapped "View" (Primary) and "Import" (Secondary) button hierarchy.

Kanban Board Enhancements

  • Horizontal Scrolling Layout: Replaced rigid grid with a flexible horizontal scroll workflow (standard Kanban UX).
  • Responsive Columns: Fixed layout issues where column headers (e.g., "Rejected") were cut off. Implemented smart truncation with tooltips and minimum column widths (280px).
  • Mobile Experience: Improved touch responsiveness and layout stability.

Performance & Polish

  • Logo Carousel Optimization: Replaced glitched GSAP ticker with a robust, fade-in enabled implementation that handles resizing gracefully.
  • Scraping Engine: Refined job parser execution to safely use public endpoints, avoiding potential rate limits for personal use.

Recent Updates (January 2026)

Keyboard Shortcuts & Navigation

  • Added comprehensive keyboard shortcut system for power users
  • / key now focuses search bar instantly (no need to click)
  • Shift + K/L/C for quick view switching (Kanban/List/Calendar)
  • ESC key dismisses dialogs and clears search
  • C shortcut for creating new jobs
  • Improved command palette (Cmd/Ctrl + K) with better search

Calendar & Interview Scheduling

  • Custom time picker with 30-minute intervals (8 AM - 7 PM)
  • Interview conflict detection on calendar view
  • At-a-glance interview details showing company name and time on calendar cells
  • Enhanced interview scheduler UX with better timezone support

Performance Optimizations

  • Reduced re-renders in dashboard components
  • Optimized board data fetching with proper SWR configuration
  • Improved Kanban column rendering performance
  • Faster search with optimized filtering logic

UI/UX Improvements

  • Enhanced search bar styling and visibility
  • Better visual feedback for active keyboard shortcuts
  • Improved dialog transitions and animations
  • More consistent button hover states
  • Better empty state messaging

Roadmap

Planned Features

  • Stale Application Indicator — Visual badge for applications inactive 14+ days
  • Upcoming This Week Widget — Quick glance at imminent interviews without opening calendar
  • Quick Notes Inline Edit — Jot down notes without opening full edit dialog
  • Tags/Labels System — Categorize jobs beyond status (Remote, FAANG, Referral)
  • Quick Stats Dashboard — Response rates, weekly/monthly application counts
  • Job Status Auto-Archive — Automatically archive old rejected applications

Known Limitations

  • Google Calendar sync requires manual OAuth flow per user
  • Email reminders require external cron service on free Vercel tier
  • Mobile drag-and-drop has limited touch support

License

This project is source-available, not open source.

You MAY:

  • View and study the source code for learning purposes
  • Fork the repository for educational experimentation
  • Use small code snippets (<50 lines) with attribution in non-commercial projects

You MAY NOT:

  • Use this code for any commercial purpose without written permission
  • Copy, reproduce, or redistribute substantial portions of the codebase
  • Create derivative commercial products based on this code
  • Remove or modify copyright notices and attributions
  • Sell or sublicense this code or derivatives

Author

Sam Bai — Full-Stack Software Engineer

Built with Next.js 16, React 19, and modern web technologies

About

Track your job applications with a beautiful Kanban board | Next.js 16 + TypeScript + MongoDB

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages