• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
figleaf

figleaf

whenwasthelasttime

Public
Like
whenwasthelasttime
Home
Code
8
.claude
1
backend
2
frontend
5
public
4
.vtignore
README.md
VALTOWN_SQLITE_GUIDE.md
spec.md
Branches
1
Pull requests
Remixes
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
README.md

When Was The Last Time

A single-user Progressive Web App (PWA) for tracking when events and activities last occurred.

Overview

Keep track of when things last happened - from personal activities like "Went to the gym" to general events like "It rained" or home maintenance tasks like "Changed air filter". The app displays time elapsed since the last occurrence and maintains a complete historical record with statistics.

Features

Core Functionality

  • Track Items: Record when specific events or activities occur
  • Time Elapsed Display: See how long it's been since each item last occurred (e.g., "2 years, 3 months, 5 days")
  • Historical Record: View complete history of all occurrences with dates and optional notes
  • Statistics:
    • Average interval between occurrences
    • Longest/shortest intervals
    • Frequency (occurrences per month/year)
    • Total occurrence count

Organization

  • Categories: Organize items into customizable categories
  • Search & Filter: Find items by name/description or filter by category
  • Archive: Soft delete items (can be restored) to keep your active list clean

Progressive Web App

  • Offline Capable: Works without internet connection
  • Installable: Add to home screen on mobile/desktop
  • Fast Loading: Optimized caching for quick startup

Technology Stack

  • Backend: Hono web framework, SQLite database (Turso/libSQL)
  • Frontend: React 18, Tailwind CSS
  • Platform: Val Town (Deno-based serverless)
  • PWA: Service worker with offline support

Project Structure

├── backend/
│   ├── index.ts          # Hono server & API endpoints
│   └── db.ts             # Database schema & queries
├── frontend/
│   ├── index.html        # HTML shell
│   ├── index.tsx         # React root
│   ├── App.tsx           # Main app component with routing
│   ├── components/
│   │   ├── ItemList.tsx
│   │   ├── ItemDetail.tsx
│   │   ├── AddItem.tsx
│   │   ├── CategoryManager.tsx
│   │   └── ArchiveView.tsx
│   └── utils/
│       ├── api.ts        # API client
│       └── timeCalc.ts   # Time calculation utilities
├── public/
│   ├── manifest.json     # PWA manifest
│   ├── sw.js             # Service worker
│   ├── icon-192.svg      # App icon (192x192)
│   └── icon-512.svg      # App icon (512x512)
└── README.md

Database Schema

Categories

  • id (text/UUID): Primary key
  • name (text): Unique category name
  • created_at (text): ISO 8601 timestamp

Items

  • id (text/UUID): Primary key
  • category_id (text): Foreign key to categories
  • name (text): Item name
  • description (text): Optional description
  • created_at (text): ISO 8601 timestamp
  • archived (integer): 0 = active, 1 = archived

Occurrences

  • id (text/UUID): Primary key
  • item_id (text): Foreign key to items (cascade delete)
  • occurrence_date (text): Date in YYYY-MM-DD format
  • note (text): Optional note
  • created_at (text): ISO 8601 timestamp

API Endpoints

Categories

  • GET /api/categories - List all categories
  • GET /api/categories/:id - Get category by ID
  • POST /api/categories - Create new category
  • PUT /api/categories/:id - Update category
  • DELETE /api/categories/:id - Delete category (fails if has items)

Items

  • GET /api/items - List items (query params: include_archived, category_id, search)
  • GET /api/items/:id - Get item by ID
  • POST /api/items - Create new item
  • PUT /api/items/:id - Update item
  • DELETE /api/items/:id - Permanently delete item
  • POST /api/items/:id/archive - Archive item
  • POST /api/items/:id/restore - Restore archived item

Occurrences

  • GET /api/items/:id/occurrences - List occurrences for an item
  • GET /api/items/:id/statistics - Get statistics for an item
  • POST /api/occurrences - Create new occurrence
  • PUT /api/occurrences/:id - Update occurrence
  • DELETE /api/occurrences/:id - Delete occurrence

Usage

Getting Started

  1. Visit the app URL
  2. Create your first category (e.g., "Health", "Home", "Activities")
  3. Add items you want to track
  4. Record occurrences when events happen

Recording Occurrences

  1. Click on an item to view details
  2. Click "Record New Occurrence"
  3. Select the date (defaults to today)
  4. Optionally add a note
  5. Click "Add"

Viewing Statistics

  • Click any item to see detailed statistics
  • View time elapsed, frequency, and patterns
  • See complete historical timeline

Managing Categories

  • Click "Categories" from the main screen
  • Add, edit, or delete categories
  • Note: Categories with items cannot be deleted

Archiving Items

  • Edit an item and click "Archive"
  • View archived items from the "Archive" screen
  • Restore or permanently delete archived items

Security Considerations

  • Single-User Design: No authentication required (keep your URL private)
  • SQL Injection Protection: All queries use parameterized statements
  • Input Validation: All user input is validated on the server

Val Town Specific Notes

  • Uses lowercase SQL keywords (Val Town convention)
  • UUIDs generated via crypto.randomUUID()
  • Dates stored as ISO 8601 strings
  • No build step required - ESM imports from CDN
  • Service worker provides offline capability

Development

The app is built for Val Town and uses:

  • Import maps from esm.sh for npm packages
  • React 18.2.0 with pinned dependencies
  • Tailwind CSS via CDN (twind)
  • SQLite via Val Town's sqlite utility

License

MIT

Support

For issues or questions, please refer to the Val Town documentation or create an issue in the project repository.

FeaturesVersion controlCode intelligenceCLI
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.