ice/README.md
Claude Code aea0426529 Fix i18n for form placeholders and make snowflake emoji clickable
- Add data-i18n-placeholder support to i18n.js for dynamic placeholder translation
- Update form inputs with proper i18n attributes for placeholders and labels
- Make snowflake emoji (❄️) clickable on all pages to return to homepage
- Remove snowflake from translation strings since it's now a separate element
- Add i18n support to README features list

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-07 19:10:02 -04:00

293 lines
9.7 KiB
Markdown

# Great Lakes Ice Report
A community-driven web application for tracking winter road conditions and icy hazards in the Great Lakes region. Reports automatically expire after 48 hours to maintain current information.
## Features
- 🗺️ **Interactive Map** - Real-time location tracking centered on Grand Rapids
-**Fast Geocoding** - Lightning-fast address lookup with Mapbox API
- 📱 **Progressive Web App** - Install on mobile home screen, works offline
- 🚫 **JavaScript-Free Mode** - Complete functionality without JavaScript via server-side rendering
- 🖼️ **Static Maps** - Auto-generated Mapbox static images for non-JS users
- 🔄 **Auto-Expiration** - Reports automatically removed after 48 hours
- 👨‍💼 **Admin Panel** - Manage and moderate location reports
- 📱 **Responsive Design** - Works on desktop and mobile devices
-**Accessibility First** - Progressive enhancement with noscript fallbacks
- 🔒 **Privacy-Focused** - No user tracking, community safety oriented
- 🛡️ **Enhanced Security** - Coordinate validation, rate limiting, and content filtering
- 🌐 **Internationalization** - Full i18n support with English and Spanish (Mexico) languages
## Quick Start
### Prerequisites
- Node.js 18+
- Mapbox API token (free tier available)
- **Important**: For server-side static maps, use an unrestricted token (no URL restrictions)
### Local Development
1. **Clone the repository:**
```bash
git clone https://git.deco.sh/deco/ice.git
cd ice
```
2. **Install dependencies:**
```bash
npm install
```
*Note: CSS is automatically built via the `postinstall` script*
3. **Configure environment variables:**
```bash
cp .env.example .env
# Edit .env with your Mapbox token
```
4. **Start the server:**
```bash
npm start # Production mode
npm run dev # Development mode
npm run dev-with-css # Development with CSS watching
```
## Development Commands
### Code Quality
```bash
# Run ESLint to check code style and quality
npm run lint
# Auto-fix ESLint issues where possible
npm run lint:fix
```
### Testing
```bash
# Run all tests (128+ tests with TypeScript)
npm test
# Run tests with coverage report (76% overall coverage)
npm run test:coverage
```
5. **Visit the application:**
```
http://localhost:3000
```
### CSS Development
This project uses SCSS for styling. The CSS is **generated** and should not be committed to git.
- **Build CSS once:** `npm run build-css`
- **Build CSS (dev mode):** `npm run build-css:dev`
- **Watch CSS changes:** `npm run watch-css`
- **Dev with CSS watching:** `npm run dev-with-css`
SCSS files are organized in `src/scss/`:
- `main.scss` - Main entry point
- `_variables.scss` - Theme variables and colors
- `_mixins.scss` - Reusable SCSS mixins
- `pages/` - Page-specific styles
- `components/` - Component-specific styles
## Environment Variables
```bash
# Required for geocoding and static map generation
MAPBOX_ACCESS_TOKEN=pk.your_mapbox_token_here
# Admin panel access
ADMIN_PASSWORD=your_secure_password
# Server configuration
PORT=3000
```
**Mapbox Token Requirements:**
- For interactive geocoding: Token can have URL restrictions
- For server-side static maps: Must use unrestricted token (no URL restrictions)
- Recommended: Use one unrestricted token for both features
## Deployment
### Deployment Scripts
The `scripts/` directory contains all deployment-related files:
- `deploy.sh` - Automated deployment script for Debian 12 (ARM64/x86_64)
- `icewatch.service` - Systemd service file for the application
- `Caddyfile` - Caddy reverse proxy configuration
- `generate-icons.js` - Script to generate PWA icons
### Quick Deployment (Recommended)
See `docs/deployment-quickstart.md` for a simplified deployment guide.
### Automated Deployment (Debian 12 ARM64/x86_64)
1. **Run the deployment script on your server:**
**Option A: Use the local deployment script (Recommended)**
```bash
# Clone the repository first
git clone https://git.deco.sh/deco/ice.git
cd ice
# Run the local deployment script
sudo bash scripts/deploy.sh
```
**Option B: Download from S3**
```bash
# Default: Downloads config from S3
curl -sSL https://ice-puremichigan-lol.s3.amazonaws.com/scripts/deploy.sh | bash
# Alternative: Use local files only (no S3)
curl -sSL https://ice-puremichigan-lol.s3.amazonaws.com/scripts/deploy.sh | S3_BUCKET_NAME=none bash
```
The deployment script (`scripts/deploy.sh`) automates the entire setup process including:
- Installing required dependencies (Node.js, Git, Caddy)
- Creating system user and directories
- Setting up systemd services
- Configuring Caddy reverse proxy
2. **Deploy your application:**
```bash
sudo git clone https://git.deco.sh/deco/ice.git /opt/icewatch
cd /opt/icewatch
sudo chown -R $USER:$USER /opt/icewatch
npm install # This automatically builds CSS via postinstall
npm run build:ts # Compile TypeScript to JavaScript
```
3. **Configure environment:**
```bash
cp .env.example .env
nano .env # Add your API keys
```
4. **Create databases and set permissions:**
```bash
touch icewatch.db profanity.db
sudo chown -R icewatch:icewatch /opt/icewatch
```
5. **Start services:**
```bash
sudo systemctl enable icewatch
sudo systemctl start icewatch
sudo systemctl enable caddy
sudo systemctl start caddy
```
### Manual Deployment
See `docs/deployment.md` for detailed manual deployment instructions.
## API Endpoints
### Public Endpoints
- `GET /api/locations` - Get active location reports
- `POST /api/locations` - Submit new location report (rate limited: 10/15min per IP)
- `GET /api/config` - Get API configuration
### Progressive Enhancement Routes
- `GET /` - Main application page with JavaScript-enhanced features
- `GET /table` - Non-JavaScript table view with static map and HTML forms
- `POST /submit-report` - Server-side form submission for non-JavaScript users
- `GET /map-image.png` - Dynamic static map generation using Mapbox Static Images API
- Query parameters: `?width=800&height=600&padding=50` for customization
- Auto-fit positioning centers on actual location coordinates
- Color-coded pins: red for regular reports, orange for persistent
### Admin Endpoints (Authentication Required)
- `GET /admin` - Admin panel (password protected)
- `GET /api/admin/locations` - Get all location reports
- `PUT /api/admin/locations/:id` - Update location report
- `PATCH /api/admin/locations/:id/persistent` - Toggle persistent status
- `DELETE /api/admin/locations/:id` - Delete location report
- `GET /api/admin/profanity-words` - Manage profanity filter
- `POST /api/admin/profanity-words` - Add custom profanity word
- `PUT /api/admin/profanity-words/:id` - Update profanity word
- `DELETE /api/admin/profanity-words/:id` - Delete profanity word
### API Documentation
Interactive API documentation available at `/api-docs` when running the server.
## PWA Installation
### Mobile Devices
1. Open the app in your mobile browser
2. Look for the "Add to Home Screen" prompt
3. Tap "Add" to install the app on your home screen
4. The app will work offline and behave like a native app
### Desktop Browsers
1. Visit the app in Chrome, Edge, or Safari
2. Look for the install icon in the address bar
3. Click "Install" to add the app to your desktop
4. Launch from your applications folder or start menu
### PWA Features
- **Offline Access:** View cached reports when disconnected
- **App-like Experience:** Standalone window, no browser UI
- **Home Screen Icon:** Quick access like native apps
- **Automatic Updates:** Always stay current when online
## Technology Stack
- **Backend:** Node.js, Express.js, SQLite, TypeScript
- **Frontend:** Progressive Web App with Progressive Enhancement
- **PWA:** Installable, offline-capable, service worker caching
- **Enhanced:** Leaflet.js interactive maps with real-time updates
- **Fallback:** Server-side HTML tables with static Mapbox images
- **Geocoding:** Mapbox API (with Nominatim fallback)
- **Maps:** Leaflet.js (interactive) + Mapbox Static Images API (server-side)
- **Security:** Rate limiting, input validation, authentication
- **Testing:** Jest, TypeScript, 128+ tests with 76% coverage
- **Reverse Proxy:** Caddy (automatic HTTPS)
- **Database:** SQLite (lightweight, serverless)
- **Accessibility:** Full progressive enhancement with noscript support
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test thoroughly
5. Submit a pull request
## Security
- **Authentication:** Admin routes protected with bearer token authentication
- **Rate Limiting:** Public endpoints limited to prevent abuse (10 requests/15min per IP)
- **Input Validation:** Strict length limits and type checking on all user inputs
- **Data Protection:** API keys stored in environment variables only
- **Database Security:** Parameterized queries prevent SQL injection
- **Content Filtering:** Built-in profanity filter with custom word management
- **HTTPS:** Enforced in production via Caddy reverse proxy
- **Audit Logging:** Suspicious activity and abuse attempts are logged
### Input Limits
- **Address:** Maximum 500 characters
- **Description:** Maximum 1000 characters
- **Latitude:** Must be between -90 and 90 degrees
- **Longitude:** Must be between -180 and 180 degrees
- **Submissions:** 10 per 15 minutes per IP address
## License
MIT License - see LICENSE file for details
## Support
This is a community safety tool. For issues or questions:
- Create an issue on our git repository
- Check existing documentation
- Review security guidelines
---
**⚠️ Safety Notice:** This tool is for community awareness. Always prioritize personal safety and know your rights.