SKILL DETAIL

Building with AI

Semantic HTML, CSS, responsive layouts, and Apps Script web apps.

Two mobile-first web apps I built and shipped end-to-end — from data model to UI to AI-assisted automation. Both are open-source on GitHub.

💸
Expense Tracker
Dual-pane finance tracker · Gmail auto-sync · Gemini AI
View on GitHub →

An elegant, dual-pane personal finance tracker for logging daily, weekly, and monthly expenses and savings. The standout feature is automatic transaction capture: it connects to Gmail (read-only OAuth) to detect DBS Bank alert emails, then uses the Gemini API to parse each alert into a structured transaction — amount, category, and description — so I don't have to manually enter every purchase.

How I use it
  • Log a daily expense or saving entry in seconds via the dual-pane add form
  • Let bank SMS/email alerts auto-populate transactions via Gmail sync
  • Gemini AI reads each bank alert and classifies category + amount automatically
  • Check today / this-week / this-month / all-time totals at a glance
  • Browse spending by category — Food, Transport, Bills, Rent, and more
  • Track savings sources separately — Salary, Investments, Side Hustle, Refunds
  • Switch between multiple country/currency formats and locales
  • Export the full transaction history to Excel (.xlsx) for records
  • Works fully offline with local persistence; syncs to Firebase when online
  • Dark mode built in for low-light daily use
App Preview — Mobile
9:41●●●●
Expense Tracker
ExpenseSavings
Today
$42
This Month
$1,180
Food & Dining
Today · Hawker lunch
-$8.50
Transportation
Today · Grab ride
-$14.20
Bills & Subscriptions
Yesterday
-$19.30
+
Home — dual-pane summary
9:41●●●●
Gmail Sync
🔗 Connected to Gmail (read-only) — scanning for DBS Bank alerts…
DBS Alert · Parsed
Gemini AI: Shopping
-$56.00
DBS Alert · Parsed
Gemini AI: Salary
+$3,200.00
DBS Alert · Parsing…
Awaiting classification
···
Gmail → Gemini auto-sync
Tech Stack
React 19TypeScriptViteTailwind CSS 4 FirebaseGemini APIGmail OAuthRecharts SheetJS (xlsx)Express
Data Model — src/types.ts
src/types.tsTypeScript
export type TransactionType = 'saving' | 'expense';

export interface Transaction {
  id: string;
  type: TransactionType;
  amount: number;
  category: string;
  description: string;
  date: string; // YYYY-MM-DD local format
  createdAt: string; // ISO format Timestamp
}

export interface SummaryStats {
  today: number;
  thisWeek: number;
  thisMonth: number;
  total: number;
}
📈
Invest Tracker
Portfolio & savings-scheme tracker · offline-first
View on GitHub →

A mobile-first tracker for logging investment payments, managing multiple savings schemes, and monitoring portfolio growth over time — built to handle the mixed basket of instruments I actually use: recurring deposits, SSY, stocks, mutual funds, and chit funds, all in one place, with full offline persistence.

How I use it
  • Set up a "scheme" for each instrument — RD, SSY, Stocks, MF, Chit, or Custom
  • Record the monthly SIP amount and the platform/provider for each scheme
  • Log a monthly entry per scheme — amount invested vs. current value
  • See return % calculated automatically per entry and per scheme
  • Add notes and payment mode (bank transfer, UPI, auto-debit, etc.) per entry
  • Review portfolio P&L across every scheme in one consolidated view
  • Keep logging and reviewing fully offline — data persists locally on-device
  • Sync across devices via Firebase when back online
App Preview — Mobile
9:41●●●●
Portfolio
Invested
$18,400
Current Value
$21,150
HDFC Flexicap MFMF
SIP $120/mo+14.2%
SSY — DaughterSSY
SIP $80/mo+7.6%
Axis Bank StockStocks
SIP $60/mo-2.1%
+
Portfolio overview
9:41●●●●
Add Entry
RDSSYChit
Month
Jul 2026
Amount Invested
Bank transfer
$120.00
Current Value
Auto-fetched
$137.00
Return
This entry
+14.2%
Log a monthly entry
Tech Stack
React 19TypeScriptViteTailwind CSS 4 FirebaseGemini APIFramer MotionLucide Icons
Data Model — src/types.ts
src/types.tsTypeScript
export type SchemeType = 'RD' | 'SSY' | 'Stocks' | 'MF' | 'Chit' | 'Custom';

export interface Scheme {
  id: string;
  name: string;
  type: SchemeType;
  sip: number;
  plat: string;
  userId?: string;
  createdAt?: string;
}

export interface Entry {
  id: string;
  month: string;          // YYYY-MM
  date: string;           // YYYY-MM-DD
  schemeId: string;
  schemeName: string;
  schemeType: SchemeType;
  amount: number;
  currentValue: number;
  returnPct?: number;
  mode: string;
  notes: string;
  userId?: string;
  createdAt: string;      // ISO timestamp
}