From 08d550b0bde8a7ce62eba586a1214090cfd13a2d Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Tue, 23 Dec 2025 22:23:23 -0500 Subject: [PATCH] Update documentation with all features and learnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated README with all features: spices filter, shopping list export, clickable container legend, category prefixes - Added deployment troubleshooting for file ownership issues - Updated CLAUDE.md with architecture details, filtering logic, common issues and fixes - Added live URL reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 91 +++++++++++++++++++++++++++++------ README.md | 138 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 154 insertions(+), 75 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8a4b561..8ad25c0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,9 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -Pantry is a simple web app for tracking kitchen pantry items. It's a single-page application with no build step, consisting of just two files: +Pantry is a simple web app for tracking kitchen pantry items. It's a single-page application with no build step. + +**Live URL:** https://pantry.kestrelsnest.social + +## File Structure + - `index.html` - Frontend (HTML/CSS/JS all in one file) - `api.php` - Backend API (JSON file-based storage) +- `containers.json` - Container type definitions with categories +- `og-image.png` - OpenGraph image for social sharing +- `deploy` - Rsync deployment script ## Architecture @@ -14,18 +22,24 @@ Pantry is a simple web app for tracking kitchen pantry items. It's a single-page - Vanilla JavaScript, no frameworks - Uses QRCode.js from CDN for QR code generation - Custom CSS with CSS variables for theming (earthy color palette: cream, terracotta, forest green) -- Container types defined in `containerTypes` object (around line 754) - must be kept in sync with backend +- Container types loaded from `containers.json` at startup into `containerTypes` object - All API calls go through the `apiCall()` function which POSTs to `api.php` **Backend (`api.php`)**: - JSON file-based storage in `data/` directory - Endpoints: `get`, `add`, `update`, `delete`, `setPin`, `verifyPin` -- Default inventory defined in `$defaultInventory` array (lines 31-64) -- Container types should match frontend when modified +- `sanitize()` function only trims whitespace - do NOT add HTML encoding (causes double-encoding issues) + +**Container Configuration (`containers.json`)**: +- Defines container types organized by category +- Each container has: `id`, `name`, `color` +- Categories have: `name`, `containers[]` +- Frontend displays as "Category: Container Name" (e.g., "Glass Spice Jars: Hex (Large)") **Data Storage**: - `data/inventory.json` - Inventory items -- `data/pin.txt` - 4-digit PIN for edit mode (plain text, view-only protection) +- `data/pin.txt` - 4-digit PIN for edit mode (plain text) +- `data/` directory must be owned by web server user (my_webapp__2), not admin user ## Development @@ -37,14 +51,63 @@ php -S localhost:8000 Then open `http://localhost:8000` in a browser. -## Key Implementation Details - -- PIN system is view-only protection (anyone can view, PIN required to edit) -- PIN stored in plain text - adequate for household use only -- Items have: `id`, `name`, `container` (type), `outOfStock` (boolean) -- Frontend sorts items: in-stock first, then alphabetically -- 8 container types with color-coded dots in UI - ## Deployment -Designed for YunoHost "My Webapp" deployment. Upload `index.html` and `api.php` to the `www/` folder. The `data/` directory is created automatically and must be writable by the web server. +The `deploy` script uses rsync to push to YunoHost: + +```bash +# Deploy code, pull data from server +./deploy + +# Deploy code AND push local data to server +./deploy --reset-data +``` + +**Important deployment notes:** +- Files in `data/` must be owned by the web server user (`my_webapp__2`) for PHP to write to them +- If deploying with `--reset-data`, the uploaded files get admin ownership - the web server then can't edit them +- Fix with: `sudo chown my_webapp__2:my_webapp__2 /var/www/my_webapp__2/www/data/inventory.json` +- Adding admin to the my_webapp__2 group allows the deploy script to write while keeping web server access + +## Key Implementation Details + +**Data model:** +- Items have: `id`, `name`, `container` (type ID), `outOfStock` (boolean) + +**Filtering:** +- `currentFilter` - Tab filter: 'all', 'in-stock', 'out', 'spices', 'qr' +- `containerFilter` - Container type filter (null or container ID), set by clicking legend items +- Both filters combine with search text + +**Container legend:** +- Clickable - filters inventory by that container type +- Shows count of items per container type +- Active filter highlighted in forest green + +**Shopping list:** +- Tap "Out of Stock" stat to copy all out-of-stock item names to clipboard +- Sorted alphabetically, one per line + +**UI patterns:** +- `renderInventory()` - Re-renders the item list +- `renderContainerLegend()` - Re-renders legend with counts, called from `updateStats()` +- `showToast(message)` - Shows temporary notification +- `escapeHtml(text)` - Escapes text for safe HTML display (used on item names) + +## Common Issues + +**Apostrophes/special characters showing as HTML entities:** +- Caused by double-encoding: API was using `htmlspecialchars()` AND frontend uses `escapeHtml()` +- Fix: `sanitize()` in api.php should only `trim()`, not HTML-encode +- Affected items need to be re-saved through UI + +**Edits not saving:** +- Usually file ownership issue - web server can't write to files owned by admin +- Check ownership of `data/inventory.json` + +## OpenGraph + +Meta tags in `` point to `og-image.png` at: +- `https://pantry.kestrelsnest.social/og-image.png` + +If URL changes, update the `og:image` and `twitter:image` meta tags. diff --git a/README.md b/README.md index 6c038f6..1147e84 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,45 @@ A simple web app for tracking kitchen pantry items across your household. +**Live demo:** https://pantry.kestrelsnest.social + ## Features - **Search** - Instantly filter ingredients by name -- **Container tracking** - 8 container types with color-coded indicators +- **Filter tabs** - View All, In Stock, Out of Stock, or Spices only +- **Container filtering** - Click any container type in the legend to filter by it +- **Container tracking** - Multiple container types organized by category with color-coded indicators - **Stock status** - Mark items as in-stock or out-of-stock +- **Shopping list** - Tap the "Out of Stock" count to copy all out-of-stock items to clipboard - **PIN protection** - Anyone can view, but editing requires a 4-digit PIN - **QR Code** - Generate a scannable code to post on your pantry shelf -- **Shared data** - All household members see the same inventory +- **OpenGraph card** - Nice preview when sharing on social media + +## File Structure + +``` +index.html - Frontend (HTML/CSS/JS, no build step) +api.php - Backend API (reads/writes JSON files) +containers.json - Container type definitions with categories +og-image.png - OpenGraph image for social sharing +deploy - Deployment script (rsync to server) +data/ - Created automatically, excluded from git + inventory.json - Your inventory data + pin.txt - Stored PIN +``` + +## Container Types + +Container types are defined in `containers.json` and organized by category: + +| Category | Types | +|----------|-------| +| Glass Jars | Flip Top (Large/Medium Tall/Medium Squat/Small), Canning Jar (Quart/Pint/Small) | +| Plastic Containers | OXO Large, Flip Top, Clamp Top (Large/Tall) | +| Glass Spice Jars | Hex (Large/Small), Flip Top (Tiny) | +| Other | Original Packaging | + +To add container types, edit `containers.json`. ## Deployment on YunoHost (My Webapp) @@ -19,107 +50,92 @@ In YunoHost admin panel: 1. Go to **Applications** → **Install** 2. Search for "My Webapp" 3. Configure: - - **Label**: Pantry (or whatever you prefer) - - **Domain/Path**: e.g., `yourdomain.com/pantry` + - **Label**: Pantry + - **Domain/Path**: e.g., `pantry.yourdomain.com` - **PHP version**: 8.2 or higher - **Database**: None needed 4. Install ### 2. Upload Files -Connect via SFTP using the credentials shown after installation, then upload to the `www` folder: - -``` -www/ -├── index.html (the main app) -├── api.php (backend API) -└── data/ (created automatically) - ├── inventory.json - └── pin.txt -``` +Upload to the `www` folder: +- `index.html` +- `api.php` +- `containers.json` +- `og-image.png` ### 3. Set Permissions -The `data` folder needs to be writable by the web server. This should happen automatically, but if you have issues: +The `data` folder needs to be writable by the web server user (typically `my_webapp__X`): ```bash # SSH into your YunoHost server -cd /var/www/pantry/www # adjust path as needed +cd /var/www/my_webapp__X/www mkdir -p data -chmod 755 data +sudo chown my_webapp__X:my_webapp__X data +chmod 775 data ``` +**Important:** Files in `data/` must be owned by the web server user, not your admin user, or edits won't save. + ### 4. First Use -1. Visit your app URL (e.g., `https://yourdomain.com/pantry`) -2. The app loads with a pre-populated inventory based on your photos -3. Tap the lock icon → Set a 4-digit PIN for your household +1. Visit your app URL +2. Tap the lock icon → Set a 4-digit PIN +3. Add your pantry items 4. Share the PIN with family members who need edit access -5. Go to the QR Code tab and print it for your pantry +5. Print the QR code for your pantry shelf -## File Structure +## Deploy Script -``` -index.html - Frontend (HTML/CSS/JS, no build step) -api.php - Backend API (reads/writes JSON files) -data/ - inventory.json - Your inventory data - pin.txt - Stored PIN (hashed would be better for production) +If you have SSH access, the `deploy` script uses rsync: + +```bash +# Deploy code only (pulls current data from server) +./deploy + +# Deploy code AND push local data to server +./deploy --reset-data ``` -## Container Types - -The app supports these container types (edit in both index.html and api.php if you want to change them): - -| ID | Name | -|----|------| -| glass-bail-large | Glass Bail Jar (Large) | -| glass-bail-medium | Glass Bail Jar (Medium) | -| glass-bail-small | Glass Bail Jar (Small) | -| oxo-large | OXO Container (Large) | -| oxo-medium | OXO Container (Medium) | -| oxo-small | OXO Container (Small) | -| original-package | Original Package | -| mason-jar | Mason Jar | +Edit the script to set your `HOST` and `DIR` variables. ## Customization ### Adding Container Types -1. In `index.html`, find the `containerTypes` object and add your new type -2. In the `