ApplicationTracker is a portfolio-ready job application tracker: one place to capture roles, follow-ups, and pipeline status while your search is in motion.
The UI does not talk to localStorage directly for applications. All load/save goes through a small repository so you can point the app at a real backend with minimal surgery.
| Situation | What happens |
|---|---|
VITE_API_BASE_URL unset (normal clone) |
Applications use localStorage only. Nothing to configure. |
| Env set, API reachable | Load/save go to your HTTP API. |
| Env set, API fails on load (network, 4xx/5xx, bad JSON) | App switches to localStorage, loads saved data from the browser, and keeps using local storage for the rest of the session. |
Env set, save (PUT) fails |
App switches to localStorage and retries persist there so edits are not lost. |
Theme (light/dark) is always stored locally in localStorage until you connect it to a backend.
| What | Where |
|---|---|
Contract (loadAll / persistAll) |
src/data/applicationRepository.contract.ts |
| localStorage implementation | src/data/localStorageApplicationRepository.ts |
| HTTP reference adapter | src/data/httpApplicationRepository.ts |
| Active repository + HTTP vs local choice | src/data/applicationDataSource.ts |
| Bootstrap + fallback logic | src/main.ts → initApplicationState() → src/composables/useApplications.ts |
Optional HTTP: copy .env.example to .env (gitignored) and set:
VITE_API_BASE_URL=https://your-api.example.comThe bundled HttpApplicationRepository expects (customize the class if your API differs):
| Method | Path | Body | Notes |
|---|---|---|---|
GET |
{base}/applications |
— | JSON array of Application |
PUT |
{base}/applications |
JSON array of Application |
Full-list replace (matches current UI behavior) |
Requests use credentials: 'include' so you can add cookies / session auth on the server later.
Production APIs often expose CRUD per application instead of one PUT for the whole list. In that case, replace or extend HttpApplicationRepository and update useApplications to call create / patch / delete—keep persistence behind the repository interface, not in views.
Commit hygiene: .env and .env.* are gitignored (.env.example is committed). Use a local .env for API experiments so nothing accidental lands in git.
Job searches sprawl across spreadsheets, notes apps, and browser tabs. ApplicationTracker keeps the signal in one structured workspace—dashboard for momentum, a filterable list for administration, and a kanban board for pipeline thinking. Out of the box application data stays on the device; optionally the same UI can talk to your server when you set VITE_API_BASE_URL, with localStorage as the safety net if the API is not ready or fails.
- Vue 3 (Composition API,
<script setup>) - Vite + TypeScript
- Tailwind CSS (v4 via
@tailwindcss/vite) - Vue Router for client-side navigation
- SortableJS for the kanban board (direct integration, no Vue wrapper)
- Persistence: repository pattern — localStorage by default and on failure, optional HTTP when configured
- Dashboard — Summary stats, recent applications, follow-ups (with overdue emphasis), status mix, quick export; welcome panel when you have no data yet
- Applications — Search, filters, sort; table + mobile cards; detail drawer; add/edit modal with validation; archive and delete with confirmation
- Board — Columns per status; drag-and-drop between columns; per-card status dropdown
- Settings — Light/dark theme (persisted locally), JSON export/import, clear all data with confirmation
- Persistence — Applications come from the active repository (local or HTTP, with automatic fallback)
- UX — Toasts, confirm dialogs, empty states with clear next steps
Add screenshots after you run the app (dashboard, applications, board, settings).
| Area | Suggested capture |
|---|---|
| Dashboard | Stat cards + welcome or recent list |
| Applications | Table with filters |
| Board | Multiple columns with cards |
| Settings | Theme + data section |
Example paths: docs/screenshots/dashboard.png, etc.
Requirements: Node.js 20+ (or current LTS) and npm.
cd "JobApplication Tracker"
npm install
cp .env.example .env # optional; only if you are wiring an API (file is gitignored)npm run dev
npm run build
npm run previewEach application includes: id, company, role, location, status (Wishlist → Ghosted), priority (Low/Medium/High), dateApplied, followUpDate, jobUrl, salary, contactName, contactEmail, notes, resumeVersion, createdAt, updatedAt, archived.
localStorage keys (applications when using the local adapter, and theme always):
application-tracker:data:v1— JSON array of applicationsapplication-tracker:theme:v1—"light"or"dark"
Legacy applyflow:* keys are removed on read so old installs do not leave stale entries beside the current namespace.
src/
components/ # ApplicationForm, StatCard, ui/* primitives
composables/ # useApplications (uses repository + fallback), useToast, useTheme
data/ # applicationRepository contract, local + HTTP adapters, dataSource
layouts/ # AppShell (nav + layout chrome)
router/ # Vue Router setup
types/ # Application model + constants
utils/ # storage (theme + local app JSON), dates, import/export helpers
views/ # Dashboard, Applications, Board, Settings
- Auth (session/JWT) + align
HttpApplicationRepositorywith your real routes - Per-resource REST or GraphQL instead of full-list
PUT - Attachments, reminders, tags, custom stages, analytics, PWA
There is no bundled server. If you do not set VITE_API_BASE_URL, the app behaves like a solid local-first tracker. If you do set it, the app tries your API first and falls back to localStorage when load or save fails, so you can develop the UI and API in parallel without bricking usage. Use Export JSON before clearing site data if you rely on local storage.
Built as a portfolio-quality frontend; extend or adapt as you like.