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.
A modern web app to track your daily water intake with a 2L daily goal. Features manual logging, NFC device registration for quick taps, and automatic daily reset at 5 AM UTC.
- β Daily Goal Tracking - Visual progress bar towards 2L daily target
- π± Quick Add Buttons - Log common amounts (250ml, 500ml, 750ml, 1L) with one tap
- π― Custom Amount - Add any custom amount you drank
- π·οΈ Water Log History - View all today's entries with timestamps
- π΄ NFC Integration - Register NFC devices/tags that auto-log water on tap
- π Daily Reset - Automatic reset at 5 AM UTC each day
- π Authentication - Magic link sign-in via Better Auth
- π Stats - Track your water intake over time
βββ config/
β βββ constants.ts # All configuration constants in one place
βββ backend/
β βββ schema.ts # SQLite schema with water & NFC tables
β βββ water-utils.ts # Utility functions for water tracking
β βββ auth.ts # Better Auth configuration
βββ frontend/
β βββ index.html # Main HTML template
β βββ index.tsx # React app with tab-based UI
βββ index.ts # Hono API server with all endpoints
All constants are defined in config/constants.ts:
export const WATER_CONFIG = {
DAILY_TARGET_ML: 2000, // Change daily goal here (in ml)
RESET_HOUR_UTC: 5, // Change reset time here (UTC)
QUICK_ADD_AMOUNTS: [250, 500, 750, 1000],
MIN_ML_PER_TAP: 100, // Minimum per NFC tap
MAX_ML_PER_TAP: 1000, // Maximum per NFC tap
DEFAULT_ML_PER_TAP: 500, // Default amount for new NFC devices
};
-
POST /api/water/log- Log water intake{ "milliliters": 500, "source": "manual" } -
GET /api/water/today- Get today's intake and logs -
GET /api/water/history?days=7- Get intake history -
DELETE /api/water/:id- Delete a log entry
POST /api/nfc/register- Start NFC device registration (returns registration URL)POST /api/nfc/device- Complete NFC device registrationGET /api/nfc/devices- Get user's registered NFC devicesPATCH /api/nfc/device/:id- Update device settingsDELETE /api/nfc/device/:id- Delete a deviceGET /api/nfc/tap/:token- NFC tap endpoint (logs water automatically)
-
Register Device
- Click "Start Registration" in NFC Devices tab
- A QR code is generated with a registration URL
- Share/scan the QR with your NFC device/app
-
Complete Registration
- When the device scans the link, you specify the water amount (default 500ml)
- Device is saved and ready to use
-
Log Water
- Each tap of the registered NFC device logs water automatically
- Shows success page with logged amount
id- Auto-increment primary keyuserId- User who logged the watertimestamp- When water was loggedmilliliters- Amount of water (in ml)source- "manual" or "nfc"createdAt- Record creation time
id- Device UUIDuserId- Owner of the devicetoken- Unique tap tokenmilliliters- Amount logged per tapname- Device namecreatedAt- When registeredupdatedAt- Last update time
token- Registration token (UUID)userId- User registering the devicecreatedAt- Token creation time
The app automatically treats the day as starting at 5 AM UTC and ending at the next 5 AM UTC. This is calculated server-side in getTodayStartTime() so it works regardless of user timezone.
To change the reset time, edit RESET_HOUR_UTC in config/constants.ts.
- Sign in with magic link
- Click quick-add buttons or enter custom amount
- Watch your progress bar fill up
- Optionally register NFC devices for one-tap logging
- Check history anytime
- Backend: Hono (TypeScript)
- Database: SQLite with Val Town blob storage
- Frontend: React with Twind CSS
- Auth: Better Auth with magic links
- Runtime: Deno on Val Town