hotel_pi/CMS_CONFIG.md
2026-04-16 18:19:15 -04:00

214 lines
5.2 KiB
Markdown

# Kiosk Configuration System
## Overview
The kiosk uses a **CMS-managed configuration system** via Directus. Settings are stored in the `settings` collection and can be managed through the Directus admin interface without needing to change environment variables.
## Configuration Fields
### Core Settings
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `key` | String | `general` | Unique identifier for this settings group (should always be "general") |
| `title` | String | `Guest` | Welcome title displayed in idle/home screens |
| `use_ip_location` | Boolean | `false` | If true, uses IP geolocation; if false, uses manual location |
| `manual_location` | String | `` | Manual location string (e.g., "Disneyland, Anaheim, CA") |
| `idle_timeout_seconds` | Integer | `300` | Seconds before returning to idle screen |
| `plex_enabled` | Boolean | `true` | Enable/disable Plex integration |
| `restaurants_enabled` | Boolean | `true` | Show/hide restaurants section |
| `attractions_enabled` | Boolean | `true` | Show/hide attractions section |
| `brand_color` | String | `#1f2937` | Primary brand color (hex) |
| `metadata` | JSON | `{}` | Extensible JSON for custom settings |
## Setup Instructions
### 1. Create the Settings Collection in Directus
Access Directus admin at `http://localhost:8055` and:
1. Create a new collection called `settings`
2. Add the fields listed above with their types
3. Create the initial record with `key: "general"`
Alternatively, if using Directus auto-migrations, the schema should be applied automatically.
### 2. Seed Initial Configuration
Insert the default settings into the database:
```sql
INSERT INTO directus_collections.settings (id, key, title, use_ip_location, manual_location, idle_timeout_seconds, plex_enabled, restaurants_enabled, attractions_enabled, brand_color)
VALUES (
gen_random_uuid(),
'general',
'Guest',
false,
'Your Hotel Location',
300,
true,
true,
true,
'#1f2937'
);
```
### 3. Frontend Integration
#### Option A: Using Config Store (Recommended)
In your Svelte components:
```svelte
<script>
import { config, welcomeTitle, location, configLoading, initConfig } from '$lib/configStore.js';
import { onMount } from 'svelte';
onMount(() => {
initConfig();
});
</script>
{#if $configLoading}
<p>Loading configuration...</p>
{:else}
<h1>Welcome, {$welcomeTitle}!</h1>
<p>Location: {$location}</p>
{/if}
```
#### Option B: Using Config Module Directly
```javascript
import { fetchConfig, getLocation } from '$lib/config.js';
const config = await fetchConfig();
console.log('Welcome title:', config.title);
const location = await getLocation();
console.log('Location:', location);
```
## Location Options
### Using IP Geolocation
```javascript
// In Directus, set:
// use_ip_location: true
// manual_location: "" (can be empty)
// The system will use ipapi.co to determine location
// Returns format: "City, Region, Country"
```
### Using Manual Location
```javascript
// In Directus, set:
// use_ip_location: false
// manual_location: "Disneyland, Anaheim, CA"
// Returns exactly what you set in manual_location
```
## Updating App.svelte
Replace environment variable usage with config store:
**Before:**
```javascript
const welcomeName = import.meta.env.VITE_WELCOME_NAME || 'Guest';
const IDLE_TIMEOUT = (import.meta.env.VITE_IDLE_TIMEOUT || 5) * 60 * 1000;
```
**After:**
```javascript
import { welcomeTitle, idleTimeoutMs, initConfig } from './lib/configStore.js';
import { onMount } from 'svelte';
onMount(() => {
initConfig();
});
let welcomeName = 'Guest';
let IDLE_TIMEOUT = 300000;
welcomeTitle.subscribe(val => welcomeName = val);
idleTimeoutMs.subscribe(val => IDLE_TIMEOUT = val);
```
## Caching
The config is cached for **5 minutes** to reduce database queries. To force a refresh:
```javascript
import { refreshConfig } from '$lib/configStore.js';
await refreshConfig();
```
## Extending Configuration
To add custom settings without modifying the schema, use the `metadata` field:
**In Directus:**
```json
{
"customFeature": true,
"apiKey": "abc123",
"theme": "dark"
}
```
**In JavaScript:**
```javascript
const config = await fetchConfig();
const customFeature = config.metadata.customFeature;
```
## API Endpoints
The config module doesn't require backend changes—it queries Directus directly:
```
GET /items/settings?filter={"key":"general"}
```
Response format:
```json
{
"data": [
{
"id": "uuid",
"key": "general",
"title": "Guest",
"use_ip_location": false,
"manual_location": "Disneyland, Anaheim, CA",
...
}
]
}
```
## Environment Variables
No environment variables needed! Everything is managed via Directus. However, you still need:
- `VITE_API_URL`: Points to Directus instance (default: `http://localhost:8055`)
## Troubleshooting
### Config not loading
- Check Directus is running and accessible
- Verify `settings` collection exists with `key: "general"` record
- Check browser console for errors
### Location not updating
- If using IP geolocation, check ipapi.co is accessible
- If using manual location, verify `use_ip_location: false` and `manual_location` is set
### Stale config after updates
- Config is cached for 5 minutes
- Force refresh with `refreshConfig()` or wait for cache to expire