# Services Homepage - Features Documentation ## Overview This services homepage provides a modern, feature-rich interface for managing and monitoring your self-hosted services. All features include persistent storage using browser localStorage. --- ## 🎯 Core Features ### 1. **Custom Health Check Endpoints** Health checks now support custom endpoints for services that don't respond on the root path. #### Configuration Add the `health-path` attribute to any service in `services.xml`: ```xml ``` **Supported attributes:** - `health-path`: Custom path to ping (e.g., `/api/health`, `/ping`, `/status`) - If not specified, defaults to root path (`/`) #### How It Works The health-proxy service: 1. Parses `services.xml` and finds the service by `id` 2. Uses `local-ip` > `tailscale-ip` > `host` for the target 3. Appends the custom `health-path` to the URL 4. Performs a HEAD request to check availability --- ### 2. **Drag-and-Drop Service Reordering** 🖱️ Reorganize your services within each group by dragging and dropping cards. #### Usage 1. Click and hold any service card 2. Drag it to the desired position within the same group 3. Release to drop 4. Order is automatically saved to localStorage #### Features - ✅ Reordering within groups only (maintains organization) - ✅ Visual feedback during drag (opacity, border highlight) - ✅ Persistent across browser sessions - ✅ Per-group order tracking #### Reset Order To reset to default XML order: ```javascript localStorage.removeItem('services-order'); location.reload(); ``` --- ### 3. **Collapsible Service Groups** 📁 Collapse and expand service groups to focus on what matters. #### Usage 1. Click on any group header (or the ▼ icon) 2. The group will collapse/expand 3. State is saved automatically #### Features - ✅ Animated collapse/expand - ✅ Persistent state per group - ✅ Visual indicator (rotating arrow) - ✅ Keyboard accessible #### Reset State ```javascript localStorage.removeItem('collapsed-groups'); location.reload(); ``` --- ### 4. **Theme System** 🎨 Choose from 5 built-in themes or customize your own. #### Available Themes 1. **Dark** (Default) - Deep blue-gray tones 2. **Light** - Clean white and blue 3. **Ocean** - Deep teal and aqua 4. **Sunset** - Purple and pink gradient 5. **Forest** - Green and earth tones #### Usage 1. Click the 🎨 icon in the top-right corner 2. Select a theme from the menu 3. Theme is applied immediately and saved #### Custom Themes Themes are defined in `js/themes.js`. To add a custom theme: ```javascript customTheme: { name: 'My Theme', primary: '#hexcolor', secondary: '#hexcolor', accent: '#hexcolor', text: '#hexcolor', textMuted: '#hexcolor', border: '#hexcolor', cardBg: 'rgba(...)', headerBg: 'rgba(...)', overlayBg: 'rgba(...)' } ``` Add your theme to the `themes` object and rebuild. --- ### 5. **Export/Import Configuration** 💾 Backup and restore your service configurations with JSON export/import. #### Export Configuration 1. Click **📥 Export** button in the top-left 2. Downloads `services-config-YYYY-MM-DD.json` file 3. Contains all services, groups, and settings #### Import Configuration 1. Click **📤 Import** button 2. Select a previously exported JSON file 3. Downloads a new `services.xml` file 4. Replace your existing `services.xml` and rebuild containers #### Export Format ```json { "version": "1.0", "exportDate": "2025-11-24T...", "tailscaleIp": "100.124.17.41", "groups": [ { "name": "Management", "services": [ { "id": "portainer", "name": "Portainer", "proto": "https", "port": "9443", "logo": "portainer.svg" } ] } ] } ``` --- ### 6. **Dashboard Widgets** 📊 Add live widgets to your homepage header. #### Available Widgets ##### ⏰ Clock Widget - Real-time clock with date - Updates every second - Always enabled by default ##### 🌤️ Weather Widget - Current weather for your location - Temperature, conditions, wind, humidity - Requires **OpenWeatherMap API key** (free) - Auto-location or custom city ##### 💭 Daily Quote Widget - Random inspirational quotes - Fetched from quotable.io API - Changes on each page load #### Configuration 1. Click **⚙️ Widgets** button 2. Enable/disable widgets with checkboxes 3. For weather: - Get API key from [OpenWeatherMap](https://openweathermap.org/api) - Enter API key - Set location to `auto` or city name (e.g., `Toronto`) 4. Click **Save & Reload** #### Settings Storage All widget settings stored in localStorage: ```javascript { "clock": {"enabled": true}, "weather": { "enabled": true, "apiKey": "your-api-key", "location": "auto" }, "quote": {"enabled": false} } ``` --- ## 🛠️ Technical Details ### Architecture ``` ┌─────────────────┐ │ Browser │ │ (HTTPS) │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Nginx │◄── Serves static files │ (Port 8088) │◄── Reverse proxy /healthcheck └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Health Proxy │ │ (Flask:8081) │◄── Server-side health checks │ │◄── Parses services.xml └─────────────────┘ ``` ### Files Structure ``` services-homepage/ ├── index.html # Main HTML ├── styles.css # Styles with CSS variables ├── services.xml # Service configuration ├── nginx.conf # Nginx config with resolver ├── docker-compose.yml # Multi-container setup ├── backend/ │ └── health-proxy.py # Flask health check service └── js/ ├── galaxy-background.js # 3D background ├── services-loader.js # Core service rendering ├── drag-drop.js # Drag-and-drop module ├── collapsible-groups.js # Group collapse module ├── themes.js # Theme system ├── export-import.js # Config backup/restore ├── widgets.js # Dashboard widgets ├── search.js # Search functionality ├── keyboard-nav.js # Arrow key navigation └── readme-loader.js # Markdown rendering ``` ### localStorage Keys | Key | Purpose | Format | |-----|---------|--------| | `services-order` | Drag-drop order | `{"GroupName": ["id1", "id2"]}` | | `collapsed-groups` | Collapsed state | `{"GroupName": true/false}` | | `selected-theme` | Active theme | `"dark"/"light"/"ocean"/...` | | `enabled-widgets` | Widget settings | `{clock: {...}, weather: {...}}` | --- ## 📋 services.xml Reference ### Root Element ```xml ``` **Attributes:** - `tailscale-ip`: Default IP for local services (optional) ### Service Element ```xml ``` **Attributes:** | Attribute | Required | Description | Example | |-----------|----------|-------------|---------| | `id` | Recommended | Unique identifier | `portainer` | | `name` | **Required** | Display name | `Portainer` | | `proto` | Optional | Protocol (default: `http`) | `https` | | `port` | Optional | Port number | `9443` | | `host` | Optional | Custom hostname/URL | `cloud.example.com` | | `logo` | Optional | Logo filename in `/logos/` | `portainer.svg` | | `status` | Optional | Manual status override | `maintenance` | | `check-health` | Optional | Enable health check (default: `true`) | `false` | | `health-path` | Optional | Custom health endpoint | `/api/health` | | `local-ip` | Optional | Override IP for health checks | `192.168.1.100` | --- ## 🔧 Troubleshooting ### Health Checks Return 502 **Problem:** Nginx can't resolve the health-proxy container. **Solution:** Ensure nginx.conf contains: ```nginx resolver 127.0.0.11 valid=30s; ``` ### Widgets Not Appearing **Problem:** Widgets enabled but not showing. **Solutions:** 1. Check browser console for errors 2. For weather: Verify API key is correct 3. Clear localStorage and reconfigure: ```javascript localStorage.removeItem('enabled-widgets'); location.reload(); ``` ### Drag-and-Drop Not Working **Problem:** Cards won't drag. **Solutions:** 1. Ensure JavaScript is enabled 2. Check browser console for errors 3. Verify cards have `draggable="true"` attribute 4. Try different browser ### Theme Not Persisting **Problem:** Theme resets after reload. **Solutions:** 1. Check browser allows localStorage 2. Try incognito/private mode to test 3. Clear site data and reconfigure --- ## 🚀 Future Enhancement Ideas - [ ] Custom widget creation API - [ ] Service groups reordering (drag groups) - [ ] Dark mode auto-switch (time-based) - [ ] Service uptime statistics - [ ] Notification system for service outages - [ ] Mobile app (PWA) - [ ] Multi-user configurations - [ ] Service tags and filtering - [ ] Global search across all services - [ ] Service dependencies visualization --- ## 📝 Changelog ### v2.0.0 - 2025-11-24 **Added:** - ✨ Custom health check endpoints support - ✨ Drag-and-drop service reordering - ✨ Collapsible service groups - ✨ Theme system (5 themes) - ✨ Export/import configuration - ✨ Dashboard widgets (clock, weather, quote) - 🐛 Fixed nginx DNS resolver for health-proxy - 🐛 Fixed services.xml mount in health-proxy container ### v1.0.0 - Previous - ✅ Basic service listing from XML - ✅ Automatic health checks - ✅ Search functionality - ✅ Keyboard navigation - ✅ 3D galaxy background - ✅ README rendering --- ## 🤝 Contributing To add features: 1. Create new module in `/js/` 2. Export functions via `window.moduleName` 3. Import in `index.html` 4. Initialize in DOMContentLoaded listener 5. Add styles to `styles.css` 6. Document in this file --- ## 📄 License This project is open source. See LICENSE file for details. --- **Questions or Issues?** Check the README.md or open an issue.