ishingiro / chatbot /config.js
IZERE HIRWA Roger
o
818ef98
/**
* Frontend Configuration Management
* Centralized configuration for the AIMHSA chatbot frontend
*/
(() => {
'use strict';
// Default configuration
const DEFAULT_CONFIG = {
// API Configuration
api: {
baseUrl: 'https://prodevroger-ishingiro.hf.space',
timeout: 10000,
retryAttempts: 3,
retryDelay: 1000
},
// UI Configuration
ui: {
theme: 'dark',
language: 'en',
autoRefreshInterval: 30000,
animationDuration: 300
},
// Chat Configuration
chat: {
maxMessageLength: 5000,
typingIndicatorDelay: 1000,
autoScroll: true,
saveConversations: true
},
// Professional Dashboard Configuration
professional: {
defaultPageSize: 25,
autoRefreshBookings: true,
notificationSound: true
},
// Admin Dashboard Configuration
admin: {
defaultPageSize: 50,
enableDataExport: true,
showAdvancedStats: true
}
};
// Environment-specific configurations
const ENVIRONMENT_CONFIGS = {
development: {
api: {
baseUrl: 'https://prodevroger-ishingiro.hf.space'
}
},
production: {
api: {
baseUrl: 'https://prodevroger-ishingiro.hf.space'
}
},
staging: {
api: {
baseUrl: 'https://prodevroger-ishingiro.hf.space'
}
}
};
class ConfigManager {
constructor() {
this.config = { ...DEFAULT_CONFIG };
this.environment = this.detectEnvironment();
this.loadConfiguration();
}
/**
* Detect current environment
*/
detectEnvironment() {
const hostname = window.location.hostname;
const port = window.location.port;
if (hostname === 'localhost' || hostname === '127.0.0.1') {
return 'development';
} else if (hostname.includes('staging')) {
return 'staging';
} else {
return 'production';
}
}
/**
* Load configuration from multiple sources
*/
loadConfiguration() {
try {
// 1. Apply environment-specific config
this.applyEnvironmentConfig();
// 2. Load from localStorage (user preferences)
this.loadFromLocalStorage();
// 3. Load from URL parameters
this.loadFromUrlParams();
// 4. Auto-detect API URL based on current location
this.autoDetectApiUrl();
console.log('πŸ”§ Configuration loaded:', this.config);
} catch (error) {
console.error('❌ Error loading configuration:', error);
// Fallback to default config
this.config = { ...DEFAULT_CONFIG };
}
}
/**
* Apply environment-specific configuration
*/
applyEnvironmentConfig() {
const envConfig = ENVIRONMENT_CONFIGS[this.environment];
if (envConfig) {
this.config = this.deepMerge(this.config, envConfig);
console.log(`🌍 Applied ${this.environment} environment config`);
}
}
/**
* Load configuration from localStorage
*/
loadFromLocalStorage() {
try {
const savedConfig = localStorage.getItem('aimhsa_config');
if (savedConfig) {
const parsedConfig = JSON.parse(savedConfig);
this.config = this.deepMerge(this.config, parsedConfig);
console.log('πŸ’Ύ Loaded config from localStorage');
}
} catch (error) {
console.warn('⚠️ Failed to load config from localStorage:', error);
}
}
/**
* Load configuration from URL parameters
*/
loadFromUrlParams() {
const urlParams = new URLSearchParams(window.location.search);
// API Base URL override
const apiUrl = urlParams.get('api_url') || urlParams.get('baseUrl');
if (apiUrl) {
this.config.api.baseUrl = apiUrl;
console.log('πŸ”— API URL overridden from URL params:', apiUrl);
}
// Environment override
const env = urlParams.get('env') || urlParams.get('environment');
if (env && ENVIRONMENT_CONFIGS[env]) {
this.environment = env;
this.applyEnvironmentConfig();
console.log('🌍 Environment overridden from URL params:', env);
}
// Theme override
const theme = urlParams.get('theme');
if (theme) {
this.config.ui.theme = theme;
console.log('🎨 Theme overridden from URL params:', theme);
}
}
/**
* Auto-detect API URL based on current page location
*/
autoDetectApiUrl() {
const currentLocation = window.location;
// Smart API URL detection
if (currentLocation.port === '8000') {
// Development server (likely Python/Django)
this.config.api.baseUrl = `${currentLocation.protocol}//${currentLocation.hostname}:7860`;
} else if (currentLocation.port === '3000') {
// React development server
this.config.api.baseUrl = `${currentLocation.protocol}//${currentLocation.hostname}:7860`;
} else if (currentLocation.port === '7860') {
// Running on API port
this.config.api.baseUrl = currentLocation.origin;
} else if (currentLocation.port === '80' || currentLocation.port === '443' || !currentLocation.port) {
// Production environment
this.config.api.baseUrl = currentLocation.origin;
}
console.log('πŸ” Auto-detected API URL:', this.config.api.baseUrl);
}
/**
* Get configuration value
*/
get(path, defaultValue = null) {
return this.getNestedValue(this.config, path, defaultValue);
}
/**
* Set configuration value
*/
set(path, value) {
this.setNestedValue(this.config, path, value);
this.saveToLocalStorage();
}
/**
* Get API base URL
*/
getApiBaseUrl() {
return this.config.api.baseUrl;
}
/**
* Set API base URL
*/
setApiBaseUrl(url) {
this.config.api.baseUrl = url;
this.saveToLocalStorage();
console.log('πŸ”— API Base URL updated:', url);
}
/**
* Get full API URL for an endpoint
*/
getApiUrl(endpoint = '') {
const baseUrl = this.config.api.baseUrl;
const cleanEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
return `${baseUrl}${cleanEndpoint}`;
}
/**
* Save current configuration to localStorage
*/
saveToLocalStorage() {
try {
localStorage.setItem('aimhsa_config', JSON.stringify(this.config));
console.log('πŸ’Ύ Configuration saved to localStorage');
} catch (error) {
console.warn('⚠️ Failed to save config to localStorage:', error);
}
}
/**
* Reset configuration to defaults
*/
reset() {
this.config = { ...DEFAULT_CONFIG };
localStorage.removeItem('aimhsa_config');
this.loadConfiguration();
console.log('πŸ”„ Configuration reset to defaults');
}
/**
* Deep merge objects
*/
deepMerge(target, source) {
const result = { ...target };
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
result[key] = this.deepMerge(result[key] || {}, source[key]);
} else {
result[key] = source[key];
}
}
}
return result;
}
/**
* Get nested object value by path
*/
getNestedValue(obj, path, defaultValue = null) {
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (current && current.hasOwnProperty(key)) {
current = current[key];
} else {
return defaultValue;
}
}
return current;
}
/**
* Set nested object value by path
*/
setNestedValue(obj, path, value) {
const keys = path.split('.');
let current = obj;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!current[key] || typeof current[key] !== 'object') {
current[key] = {};
}
current = current[key];
}
current[keys[keys.length - 1]] = value;
}
/**
* Validate API connection
*/
async validateApiConnection() {
try {
const response = await fetch(`${this.config.api.baseUrl}/health`, {
method: 'GET',
timeout: this.config.api.timeout
});
if (response.ok) {
console.log('βœ… API connection validated');
return true;
} else {
console.warn('⚠️ API responded but not healthy:', response.status);
return false;
}
} catch (error) {
console.error('❌ API connection failed:', error);
return false;
}
}
/**
* Get environment info
*/
getEnvironmentInfo() {
return {
environment: this.environment,
hostname: window.location.hostname,
port: window.location.port,
protocol: window.location.protocol,
apiBaseUrl: this.config.api.baseUrl,
userAgent: navigator.userAgent,
timestamp: new Date().toISOString()
};
}
}
// Create global configuration manager instance
const configManager = new ConfigManager();
// Export to global scope
window.AIMHSA = window.AIMHSA || {};
window.AIMHSA.Config = configManager;
// Legacy support
window.getApiBaseUrl = () => configManager.getApiBaseUrl();
window.getApiUrl = (endpoint) => configManager.getApiUrl(endpoint);
console.log('βš™οΈ AIMHSA Configuration Manager initialized');
console.log('🌍 Environment:', configManager.environment);
console.log('πŸ”— API Base URL:', configManager.getApiBaseUrl());
})();