Emergency Prep Inventory
A self-hosted, lightweight web application for tracking household emergency supplies and planning survival meals. Built with PHP 8.x and vanilla JavaScript — no database required, no frameworks, no build tools.
✨ Features
Inventory Management
Full CRUD operations with auto-calculated days remaining, status indicators, category filtering, sorting, and search.
Admin Authentication
BCrypt password hashing, PHP session-based auth, viewer read-only mode, and .htaccess file protection.
Household Config
Customizable household composition and target days with dynamic recalculation of all supply durations.
Survival Recipes
16 survival-optimized recipes with priority levels, fuel cost indicators, child versions, and print-ready layout.
Multi-Language
English, German, and Romanian with instant switching and persistent preference via localStorage and cookies.
Design & UX
Responsive layout, dark mode support, CSS custom properties, accessible focus outlines, and reduced motion respect.
Inventory Management
- Full CRUD operations — add, edit, and delete inventory items with categories, subcategories, quantities, units, daily consumption rates, and expiry dates
- Auto-calculated days remaining — the system computes how many days each item will last based on current stock and daily consumption per household member
- Status indicators — items are automatically flagged as Critical (below minimum stock), Warning (below target), or Adequate
- Category filtering — click any category pill to instantly filter the table; pills are color-coded by aggregate status
- Sortable table — click any column header to sort ascending/descending
- Search — real-time search across item names, categories, and subcategories
- Export backup — one-click JSON export of your entire inventory for offline safekeeping
Admin Authentication
- Single-admin model — one admin account created during first-time setup; no multi-user accounts needed
- BCrypt password hashing (cost factor 12) — passwords are never stored in plain text
- PHP session-based auth — sessions stored in a protected sessions/ directory, not the system temp folder
- Viewer mode — unauthenticated visitors browse in read-only mode
- Password change — admin can change password from Settings at any time
- .htaccess protection — direct URL access to JSON data files and sessions is blocked
Survival Recipes
- 16 survival-optimized recipes — designed specifically for the ingredients tracked in inventory
- Priority levels — Use First (perishable), Use Soon, or Any Time
- Fuel cost indicators — Zero (no cooking), Low (<10 min), or Medium (10-20 min)
- Emergency-only recipes — clearly marked for critical situations
- Comfort/normalcy recipes — meals that boost morale during extended emergencies
- Child versions — adapted instructions for young children (ages 5+)
- Survival tips — water-saving techniques, ingredient substitution strategies, and cooking shortcuts
- Print-ready — optimized print stylesheet for physical copies or "Save as PDF"
📁 File Structure
Requirements
- Web server — Apache (with .htaccess support) or Nginx
- PHP 8.x — with json and posix extensions (posix is optional but provides better diagnostics)
- Write permissions — the web server user (typically www-data) must be able to write to data/ and sessions/
- No database — all data is stored in JSON files
- No npm/build step — pure HTML, CSS, and JavaScript; no compilation or bundling required
🛠 Installation
Choose the installation method that matches your operating system and setup.
Quick Start
Copy files to your web server directory
Copy the entire project folder to your Apache/Nginx document root.
sudo cp -r ./emergency-prep-inventory /var/www/html/tools/emergency-prep-inventory
Run the permission setup script
This creates data/ and sessions/, sets ownership and permissions, creates .htaccess protection, generates a favicon, and runs a write-verification test.
sudo bash setup-permissions.sh /var/www/html/tools/emergency-prep-inventory
Open your browser
Navigate to your application URL and complete the first-time setup screen.
Manual Permission Setup
If you prefer to set permissions manually instead of using the script:
mkdir -p /var/www/html/tools/emergency-prep-inventory/data
mkdir -p /var/www/html/tools/emergency-prep-inventory/sessions
sudo chown -R www-data:www-data /var/www/html/tools/emergency-prep-inventory
find /var/www/html/tools/emergency-prep-inventory -type d -exec chmod 755 {} \;
chmod 750 /var/www/html/tools/emergency-prep-inventory/data
chmod 700 /var/www/html/tools/emergency-prep-inventory/sessions
chmod 640 /var/www/html/tools/emergency-prep-inventory/*.php
chmod 644 /var/www/html/tools/emergency-prep-inventory/*.html
chmod 644 /var/www/html/tools/emergency-prep-inventory/*.css
chmod 660 /var/www/html/tools/emergency-prep-inventory/data/*.jsonNginx Configuration
If you use Nginx instead of Apache, add these location blocks to your server configuration:
location /data/ {
deny all;
}
location /sessions/ {
deny all;
}XAMPP is a free, all-in-one package that includes Apache, PHP, and everything you need to run this application on Windows. No need to install or configure a web server manually.
Step 1: Install XAMPP
- Download XAMPP for Windows from apachefriends.org
- Run the installer. The default installation path is C:\xampp
- During installation, make sure Apache and PHP are selected (they are by default)
- After installation, open the XAMPP Control Panel and click Start next to Apache — the status should turn green
Step 2: Copy Project Files
- Navigate to the XAMPP web root directory: C:\xampp\htdocs\
- Create a folder for the project, e.g., C:\xampp\htdocs\emergency-prep-inventory\
- Copy all project files into this folder: api.php, index.html, receips.html, style.css, permission.sh, setup-permissions.sh
Step 3: Create Required Directories
Inside your project folder, create these two directories manually:
C:\xampp\htdocs\emergency-prep-inventory\data\C:\xampp\htdocs\emergency-prep-inventory\sessions\
That's it — XAMPP runs Apache under your own Windows user account, so there are no permission issues to worry about. PHP can write to these directories automatically.
Step 4: Open the Application
- Open your browser and go to: http://localhost/emergency-prep-inventory/
- You will see the first-time setup screen — create your admin account and configure your household
- The application is now running locally on your machine
Optional: Local Network Access
If you want other devices on your home network (phone, tablet, another computer) to access the inventory:
- Find your Windows PC's local IP address: open Command Prompt and run: ipconfig — look for "IPv4 Address" (e.g., 192.168.1.100)
- On your other device, open a browser and go to: http://192.168.1.100/emergency-prep-inventory/
- Make sure Windows Firewall allows incoming connections on port 80 (XAMPP usually prompts for this)
The .htaccess files that protect data/ and sessions/ from direct URL access work out of the box with XAMPP because it uses Apache with mod_rewrite enabled by default.
Troubleshooting (Windows / XAMPP)
| Problem | Solution |
|---|---|
| Apache won't start | Another program (often Skype or IIS) is using port 80. In XAMPP Control Panel, click "Config" next to Apache → change port to 8080 → access via http://localhost:8080/... |
| "Access forbidden" error | Make sure the folder name in htdocs matches the URL. No spaces or special characters in the folder name. |
| Blank page / PHP not running | Open XAMPP Control Panel → click "Config" next to Apache → ensure PHP is enabled. Test with in a test.php file. |
| data/ or sessions/ not writable | Right-click the folder → Properties → Security tab → ensure "Users" or "Everyone" has "Write" permission. Rarely needed on XAMPP. |
| .htaccess not working | Open C:\xampp\apache\conf\httpd.conf, find #LoadModule rewrite_module modules/mod_rewrite.so, and remove the #. Restart Apache. |
On macOS you have two popular options for a local PHP server: XAMPP (cross-platform, same as Windows) or MAMP (macOS-focused). Both work well.
XAMPP on macOS
Step 1: Install XAMPP
- Download XAMPP for macOS from apachefriends.org
- Open the .dmg file and drag XAMPP to your Applications folder
- Launch XAMPP from Applications — it may ask for your macOS password to start Apache
- In the XAMPP Control Panel, click Start next to Apache
Step 2: Copy Project Files
The XAMPP web root on macOS is: /Applications/XAMPP/xamppfiles/htdocs/
cp -r ./emergency-prep-inventory /Applications/XAMPP/xamppfiles/htdocs/emergency-prep-inventory
Step 3: Create Required Directories
mkdir -p /Applications/XAMPP/xamppfiles/htdocs/emergency-prep-inventory/data mkdir -p /Applications/XAMPP/xamppfiles/htdocs/emergency-prep-inventory/sessions sudo chown -R daemon:daemon /Applications/XAMPP/.../data sudo chown -R daemon:daemon /Applications/XAMPP/.../sessions
If you get permission errors (XAMPP runs as user 'daemon'), run: sudo chown -R daemon:daemon /Applications/XAMPP/.../data and sessions
Step 4: Open the Application
Open your browser and go to: http://localhost/emergency-prep-inventory/
MAMP on macOS
MAMP (Mac + Apache + MySQL + PHP) is another popular option. The free version is sufficient — you do not need MySQL for this project.
Step 1: Install MAMP
- Download MAMP from mamp.info
- Install by dragging to Applications
- Launch MAMP and click Start Servers — both Apache and MySQL will start (MySQL is not used but doesn't hurt)
Step 2: Copy Project Files
The MAMP web root is: /Applications/MAMP/htdocs/
cp -r ./emergency-prep-inventory /Applications/MAMP/htdocs/emergency-prep-inventory
Step 3: Create Required Directories
mkdir -p /Applications/MAMP/htdocs/emergency-prep-inventory/data mkdir -p /Applications/MAMP/htdocs/emergency-prep-inventory/sessions chmod 777 /Applications/MAMP/htdocs/emergency-prep-inventory/data chmod 777 /Applications/MAMP/htdocs/emergency-prep-inventory/sessions
MAMP runs Apache under your own user account, so permissions should not be an issue. If they are: chmod 777 data/ and sessions/
Step 4: Open the Application
By default, MAMP uses port 8888. Open your browser and go to: http://localhost:8888/emergency-prep-inventory/
You can change MAMP's port to 80 in MAMP → Preferences → Ports → "Set to standard Apache and MySQL ports". Then the URL becomes simply http://localhost/emergency-prep-inventory/.
Optional: Local Network Access (macOS)
- Find your Mac's local IP address: System Settings → Wi-Fi → click "Details" — or in Terminal: ipconfig getifaddr en0
- On your other device: XAMPP: http://192.168.1.50/emergency-prep-inventory/ — MAMP: http://192.168.1.50:8888/emergency-prep-inventory/
- Make sure macOS Firewall allows incoming connections: System Settings → Network → Firewall
Troubleshooting (macOS / XAMPP / MAMP)
| Problem | Solution |
|---|---|
| Apache won't start | macOS has a built-in Apache that may conflict. Stop it: sudo apachectl stop. Also check if another app is using port 80. |
| "Access forbidden" | Check folder permissions. For XAMPP, the daemon user needs read access. For MAMP, your own user should work. |
| data/ not writable | XAMPP runs as daemon — run sudo chown -R daemon:daemon /Applications/XAMPP/.../data. MAMP runs as your user — should work without changes. |
| .htaccess not working (XAMPP) | Open /Applications/XAMPP/xamppfiles/etc/httpd.conf, find #LoadModule rewrite_module and remove the #. Restart Apache. |
| .htaccess not working (MAMP) | MAMP has mod_rewrite enabled by default — should work out of the box. |
| PHP version too old | XAMPP and MAMP bundle recent PHP versions. If you need PHP 8.x, download the latest version from their website. |
🔌 API Reference
The backend API (api.php) uses a simple action-based routing pattern. All requests return JSON responses.
Public Endpoints (No Authentication Required)
| Action | Method | Description |
|---|---|---|
check_setup | GET | setup complete? |
setup | POST | create admin (first-time) |
login | POST | authenticate admin |
logout | GET/POST | destroy session |
session_status | GET | auth state |
get_settings | GET | household config |
inventory | GET | all items |
check_permissions | GET | diagnostic |
Protected Endpoints (Admin Authentication Required)
| Action | Method | Description |
|---|---|---|
save_inventory | POST | save full inventory |
save_settings | POST | update household config |
change_password | POST | change admin password |
Request / Response Examples
Login:
{ "action": "login", "username": "admin", "password": "your-password" }Save inventory:
{ "action": "save_inventory", "data": [{ "itemName": "Rice", "category": "Grains", "currentQuantity": 5, "unit": "kg", "dailyConsumption": 0.1 }] }📖 Usage Guide
First-Time Setup
- Create your admin account — choose a username (minimum 2 characters) and a password (minimum 6 characters)
- Configure your household — set the number of adult males, adult females, children, and your target preparation days
After setup, you will be automatically logged in as admin.
Managing Inventory Items
- Add a new item — click the "Add New Item" button (admin only)
- Edit an item — click the pencil icon in the Actions column (admin only)
- Delete an item — click the trash icon in the Actions column (admin only)
- Add new categories/units — each dropdown has a "+" button to create new categories, subcategories, or units on the fly
- Export backup — click "Export Backup" to download your inventory as a JSON file
Viewing as a Guest
Visitors who do not log in can browse the inventory in read-only mode. They can:
- View all inventory items and their statuses
- Filter by category and search
- Switch languages
- Access the recipes page
They cannot add, edit, or delete items.
Survival Recipes
Click the "Recipes" button to open the survival recipes page. Each recipe includes:
- Priority badge — tells you when to use this recipe based on ingredient perishability
- Fuel cost badge — how much cooking fuel is required
- Water cost — estimated water consumption for the recipe
- Ingredients list — with quantities matched to your inventory
- Step-by-step instructions — numbered cooking steps
- Child version — adapted instructions for feeding young children
- Survival tip — practical advice for conserving resources
Use the "Print / Save as PDF" button to create a physical backup of all recipes.
🔧 Troubleshooting
Permission Errors
If you see errors about file write access:
- Run the permission check endpoint: api.php?action=check_permissions
- This will show the PHP user, file ownership, and permission details
- Re-run the setup script: sudo bash setup-permissions.sh /your/project/path
- If the issue persists, manually check ownership — files should be owned by www-data:www-data with permissions 660 for JSON files
Session Issues
If login does not persist:
- Ensure the sessions/ directory exists and is writable by www-data
- Check that the directory has permissions 700 and is owned by www-data
- Verify that your browser accepts cookies from the domain
API Returns 500 on Setup
This typically means the data/ directory or JSON files are not writable. The API response will include diagnostic information:
- php_user — the user PHP is running as
- file_perms — current file permissions
- file_owner — current file owner
- fix — the exact command to run to resolve the issue
🛡 Security Considerations
- JSON data files are protected from direct HTTP access via .htaccess rules (Apache) or Nginx location blocks
- Admin credentials are stored with BCrypt hashing (cost 12) — passwords are never stored in plain text
- Session files are stored in a dedicated directory with restrictive permissions (700), not in the system-wide /tmp directory
- PHP files have permissions 640 — readable only by the web server user and group, not world-readable
- No CSRF tokens — this application is designed for single-admin household use on a trusted network. If you expose it to the public internet, consider adding CSRF protection
- No rate limiting — brute-force protection is not implemented. Use fail2ban or similar tools if exposed publicly
⚙️ Technology Stack
| Component | Technology |
|---|---|
| Backend | PHP 8.x |
| Frontend | HTML5 CSS3 JS ES6+ |
| Storage | JSON files |
| Auth | Sessions BCrypt |
| Languages | EN DE RO |
Browser Support
- Chrome / Edge (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Mobile browsers (Chrome for Android, Safari for iOS)
📄 License
This project is provided as-is for personal household emergency preparedness use. Contact marundaliliana@gmail.com for custom deployments or inquiries.