Software Engineer
Frontend & Angular
Modern client-side engineering with Angular 22: standalone components and signals, computed-derived state persisted through effects, dependency-free SVG, hand-rolled SCSS design tokens, and live deployed demos.
Back to ProjectsJohn's AI Lab Live
An Angular 22 front-end for three Google Gemini agents — a review analyst whose tool calls stream into the UI as they run, a grounded portfolio concierge, and a math-mission generator whose schema-validated JSON becomes a playable game. The API key never reaches the browser: Angular talks to Vercel serverless functions that run the agents server-side.
- Signals everywhere: per-agent chat state (messages, busy, model, draft) lives in a service as
signals keyed by agent id — each tab keeps its own conversation, including a half-typed draft. - Streaming without a library: a hand-rolled NDJSON reader over
fetchstreams parsestool-start/tool-end/deltaevents and updates the pending message live — spinning-gear trace steps, then a typing caret. - Reusable chat shell: one
agent-chatcomponent (signalinput()s) powers both chat agents; the mission stage is a separate playable state machine (setup → loading → play → done). - Dev ergonomics:
ng serveproxies/apito a local Node stand-in for the Vercel functions, so onenpm run devruns the whole stack.
Personal Budget Planner Live
A client-side personal-finance tracker built with Angular 22 — standalone components
and signals. Track income and expenses, set per-category monthly budgets, and watch a
live dashboard with a custom SVG donut chart, all stored in the browser via
localStorage. No backend.
- Signal-driven state: a single store holds transactions and budgets as
signals, derives every total viacomputed, and persists each change through aneffect. - Live dashboard: total balance, monthly income / expenses / net, savings rate, a dependency-free SVG donut of spending by category, and budget bars that turn red when you go over.
- Transactions & budgets: add / edit / delete income and expenses with filter and search; set per-category monthly limits with live spent-vs-limit bars.
- Persistence: everything saved to
localStoragethrough a fail-safe JSON wrapper and reloaded on return; sample data is seeded on first run.
A signals-driven dashboard — the totals, the SVG donut, and the budget bars all recompute live as you add transactions.
Hangman Encyclopedia Live
Hangman with a collection meta-game, built with Angular 22 — every word you solve
unlocks a real “did you know” entry in your personal encyclopedia: 434
fact-checked entries across 12 volumes, all stored client-side in
localStorage, wrapped in a vintage-encyclopedia design with light and dark themes.
- Collection meta-game: pick from 12 volumes, including the new Mythology, Music, Inventions, and Human Body. Win and the word joins My Encyclopedia with its fun fact; lose and the fact is shown but not collected. Streaks, best streak, and win/loss record persist between visits.
- Light & dark themes: a “lamplight” dark palette with WCAG AA contrast. It follows your OS until you choose, remembers the choice, is applied before first paint so there’s no flash, and crossfades with the View Transitions API.
- Signal-driven game: a single
GameStoreholds the round as signals, derives misses and letter tiles viacomputed, and persists stats + collection througheffects. - Thoughtful rules: six misses, an on-screen keyboard plus full physical-keyboard support, and a hint that costs one miss — but is never allowed to be the losing one.
- Hand-built UI: a dependency-free ink-style SVG gallows (one body part per miss), a self-coloring keyboard, and vintage-parchment SCSS design tokens.
Open the live demo — pick a volume, solve the word, and watch the entry join your encyclopedia. The sun/moon button switches themes.