222 lines
6.2 KiB
JavaScript
222 lines
6.2 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Setup script to initialize the settings collection in Directus
|
||
* Usage: node directus/setup-settings.js
|
||
*
|
||
* This script:
|
||
* 1. Creates the 'settings' collection
|
||
* 2. Adds all required fields
|
||
* 3. Seeds initial data with default values
|
||
*
|
||
* Note: Local dev only - no authentication
|
||
*/
|
||
|
||
const API_URL = process.env.VITE_API_URL || 'http://localhost:8055';
|
||
|
||
async function createCollection() {
|
||
console.log('📦 Creating settings collection...');
|
||
try {
|
||
const response = await fetch(`${API_URL}/collections`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
collection: 'settings',
|
||
icon: 'settings',
|
||
note: 'Global kiosk configuration and settings',
|
||
fields: [
|
||
{
|
||
field: 'id',
|
||
type: 'uuid',
|
||
data_type: 'uuid',
|
||
primary_key: true,
|
||
readonly: true,
|
||
},
|
||
{
|
||
field: 'key',
|
||
type: 'string',
|
||
data_type: 'string',
|
||
required: true,
|
||
note: 'Unique key identifying this setting group',
|
||
},
|
||
{
|
||
field: 'title',
|
||
type: 'string',
|
||
data_type: 'string',
|
||
required: true,
|
||
default_value: 'Guest',
|
||
note: 'Displayed welcome title',
|
||
},
|
||
{
|
||
field: 'use_ip_location',
|
||
type: 'boolean',
|
||
data_type: 'boolean',
|
||
default_value: false,
|
||
note: 'Use IP geolocation or manual location',
|
||
},
|
||
{
|
||
field: 'manual_location',
|
||
type: 'string',
|
||
data_type: 'string',
|
||
note: 'Manual location string',
|
||
},
|
||
{
|
||
field: 'idle_timeout_seconds',
|
||
type: 'integer',
|
||
data_type: 'integer',
|
||
default_value: 300,
|
||
note: 'Seconds before idle screen',
|
||
},
|
||
{
|
||
field: 'plex_enabled',
|
||
type: 'boolean',
|
||
data_type: 'boolean',
|
||
default_value: true,
|
||
note: 'Enable Plex integration',
|
||
},
|
||
{
|
||
field: 'restaurants_enabled',
|
||
type: 'boolean',
|
||
data_type: 'boolean',
|
||
default_value: true,
|
||
note: 'Show restaurants section',
|
||
},
|
||
{
|
||
field: 'attractions_enabled',
|
||
type: 'boolean',
|
||
data_type: 'boolean',
|
||
default_value: true,
|
||
note: 'Show attractions section',
|
||
},
|
||
{
|
||
field: 'brand_color',
|
||
type: 'string',
|
||
data_type: 'string',
|
||
default_value: '#1f2937',
|
||
note: 'Primary brand color',
|
||
},
|
||
{
|
||
field: 'metadata',
|
||
type: 'json',
|
||
data_type: 'json',
|
||
note: 'Custom metadata and settings',
|
||
},
|
||
],
|
||
}),
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const error = await response.json();
|
||
// Collection might already exist, which is fine
|
||
if (error.errors?.[0]?.message?.includes('already exists')) {
|
||
console.log('ℹ️ Collection already exists');
|
||
return true;
|
||
}
|
||
throw new Error(`Failed to create collection: ${error.errors?.[0]?.message || response.statusText}`);
|
||
}
|
||
|
||
console.log('✅ Collection created');
|
||
return true;
|
||
} catch (error) {
|
||
console.error('❌ Collection creation failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async function seedData() {
|
||
console.log('🌱 Seeding settings data...');
|
||
try {
|
||
// First check if data already exists
|
||
const checkResponse = await fetch(`${API_URL}/items/settings?filter={"key":"general"}`, {
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
|
||
if (checkResponse.ok) {
|
||
const checkData = await checkResponse.json();
|
||
if (checkData.data?.length > 0) {
|
||
console.log('ℹ️ Settings already exist, updating...');
|
||
// Update existing
|
||
const settingId = checkData.data[0].id;
|
||
const updateResponse = await fetch(`${API_URL}/items/settings/${settingId}`, {
|
||
method: 'PATCH',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
title: 'Guest',
|
||
use_ip_location: false,
|
||
manual_location: 'Your Hotel',
|
||
idle_timeout_seconds: 300,
|
||
plex_enabled: true,
|
||
restaurants_enabled: true,
|
||
attractions_enabled: true,
|
||
brand_color: '#1f2937',
|
||
metadata: {},
|
||
}),
|
||
});
|
||
|
||
if (!updateResponse.ok) {
|
||
throw new Error(`Failed to update settings: ${updateResponse.statusText}`);
|
||
}
|
||
console.log('✅ Settings updated');
|
||
return true;
|
||
}
|
||
}
|
||
|
||
// Create new settings record
|
||
const response = await fetch(`${API_URL}/items/settings`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
key: 'general',
|
||
title: 'Guest',
|
||
use_ip_location: false,
|
||
manual_location: 'Your Hotel',
|
||
idle_timeout_seconds: 300,
|
||
plex_enabled: true,
|
||
restaurants_enabled: true,
|
||
attractions_enabled: true,
|
||
brand_color: '#1f2937',
|
||
metadata: {},
|
||
}),
|
||
});
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`Failed to seed data: ${response.statusText}`);
|
||
}
|
||
|
||
console.log('✅ Settings record created');
|
||
return true;
|
||
} catch (error) {
|
||
console.error('❌ Seeding failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
console.log(`\n🚀 Setting up Hotel Pi configuration...\n`);
|
||
console.log(`API URL: ${API_URL}\n`);
|
||
|
||
try {
|
||
const collectionOk = await createCollection();
|
||
|
||
if (collectionOk) {
|
||
await seedData();
|
||
console.log('\n✅ Setup complete! Your settings are ready in Directus.\n');
|
||
console.log('📝 You can now edit settings in Directus admin panel:');
|
||
console.log(` ${API_URL}/admin/collections/settings\n`);
|
||
}
|
||
} catch (error) {
|
||
console.error('\n❌ Setup failed:', error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
main();
|