besper-frontend-site-dev-main
Version:
Professional B-esper Frontend Site - Site-wide integration toolkit for full website bot deployment
377 lines (333 loc) • 11.8 kB
JavaScript
/**
* Customer Outreach Management Page Script - Bulletproof loading pattern
* Manage customer outreach and communications
*/
class AdminCustomerOutreachManagementPage {
constructor(options = {}) {
this.options = {
containerId: 'besper-site-content',
environment: 'prod',
...options,
};
this.initialized = false;
// BULLETPROOF: Defer all complex operations to avoid blocking class export
this.authService = null;
this.operatorsService = null;
this.isAuthenticated = false;
// Initialize auth safely in next tick to ensure class export completes first
if (typeof window !== 'undefined') {
setTimeout(() => {
this.initializeAuth();
}, 1);
}
}
/**
* Initialize authentication safely without blocking class export
*/
initializeAuth() {
try {
this.authService = this.getAuthService();
this.operatorsService = this.getOperatorsService();
} catch (error) {
console.warn('Auth initialization failed, using fallback:', error);
this.authService = this.createFallbackAuthService();
this.operatorsService = this.createFallbackOperatorsService();
}
}
/**
* Get authentication service from global scope or create simple fallback
*/
getAuthService() {
// Try to access global token auth service if available
if (typeof window !== 'undefined' && window.tokenAuthService) {
return window.tokenAuthService;
}
return this.createFallbackAuthService();
}
/**
* Get operators service from global scope or create simple fallback
*/
getOperatorsService() {
// Try to access global page operators service if available
if (typeof window !== 'undefined' && window.pageOperatorsService) {
return window.pageOperatorsService;
}
return this.createFallbackOperatorsService();
}
/**
* Create safe fallback auth service
*/
createFallbackAuthService() {
return {
isUserAuthenticated: () => {
try {
return (
typeof window !== 'undefined' &&
window.auth &&
typeof window.auth.getToken === 'function' &&
!!window.auth.getToken()
);
} catch (error) {
return false;
}
},
getToken: () => {
try {
if (
typeof window !== 'undefined' &&
window.auth &&
typeof window.auth.getToken === 'function'
) {
return window.auth.getToken();
}
} catch (error) {
console.warn('Token access failed:', error);
}
return null;
},
getUserPermission: key => {
try {
if (typeof window === 'undefined') return null;
const mappings = {
contactId: window.contact_id || window.user_contactid,
userName: window.user_name,
name: window.user_name,
userEmail: window.user_email,
email: window.user_email,
workspaceId: window.workspace_id,
accountId: window.account_id,
subscriptionId: window.subscription_id,
};
return mappings[key] || null;
} catch (error) {
console.warn('User permission access failed:', error);
return null;
}
},
};
}
/**
* Create safe fallback operators service
*/
createFallbackOperatorsService() {
return {
callOperator: async () => {
console.warn(
'Operators service not available, returning empty response'
);
return { success: false, message: 'Service not available' };
},
};
}
/**
* Initialize the page - IMMEDIATE RENDERING
* Shows UI instantly without waiting for authentication
*/
async initialize(_data = {}) {
if (this.initialized) return;
try {
// IMMEDIATE: Show the UI without any loading delays
this.renderImmediateUI();
// IMMEDIATE: Setup basic interactions
this.setupInteractions();
this.initialized = true;
// DEFERRED: Initialize authentication features in background
this.initializeAuthenticationFeaturesInBackground();
} catch (error) {
console.error(
'Error initializing customer outreach management page:',
error
);
this.showError(error);
}
}
/**
* Render immediate UI structure - shows content instantly
*/
renderImmediateUI() {
const container = document.getElementById(this.options.containerId);
if (!container) return;
// Clear any existing loading indicators
container.innerHTML = '';
// Show immediate customer outreach management interface
container.innerHTML = `
<div style="background: #f8f9fa; color: #022d54; font-family: Arial, sans-serif;">
<div style="max-width: 1200px; margin: 0 auto; padding: 2rem 1rem;">
<!-- Header -->
<div style="margin-bottom: 2rem;">
<h1 style="color: #022d54; font-weight: 300; font-size: 28px; margin-bottom: 0.5rem;">Customer Outreach Management</h1>
<p style="color: #6c757d; font-size: 14px; margin: 0;">Manage customer outreach and communications</p>
</div>
<!-- Main Content Area with Skeleton Loading -->
<div style="background: white; border-radius: 8px; border: 1px solid #e0e0e0; overflow: hidden;">
<div style="padding: 1rem; border-bottom: 1px solid #e0e0e0;">
<h3 style="margin: 0; color: #022d54; font-size: 16px; font-weight: 500;">Loading Content...</h3>
</div>
<div id="page-content-area" style="padding: 2rem;">
<!-- Skeleton Loading Animation -->
<div style="height: 20px; background: #e0e0e0; border-radius: 4px; margin-bottom: 1rem; animation: pulse 1.5s ease-in-out infinite;"></div>
<div style="height: 20px; background: #e0e0e0; border-radius: 4px; margin-bottom: 1rem; width: 80%; animation: pulse 1.5s ease-in-out infinite;"></div>
<div style="height: 20px; background: #e0e0e0; border-radius: 4px; margin-bottom: 1rem; width: 60%; animation: pulse 1.5s ease-in-out infinite;"></div>
<div style="height: 100px; background: #e0e0e0; border-radius: 4px; animation: pulse 1.5s ease-in-out infinite;"></div>
</div>
</div>
</div>
</div>
<!-- Skeleton Loading Animation -->
<style>
pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
</style>
`;
}
/**
* Setup interactions - immediate setup without waiting
*/
setupInteractions() {
// TODO: Add page-specific interactions here
console.log('Customer Outreach Management interactions ready');
}
/**
* Initialize authentication features completely in background - NO UI BLOCKING
*/
async initializeAuthenticationFeaturesInBackground() {
// Use requestIdleCallback for true background processing
const initializeAuth = () => {
try {
// Ensure services are ready
if (!this.authService) {
this.initializeAuth();
}
// Check authentication status without blocking
if (this.authService) {
this.isAuthenticated = this.authService.isUserAuthenticated();
if (this.isAuthenticated) {
// Load data in background
this.loadDataInBackground();
} else {
this.showUnauthenticatedView();
}
}
} catch (error) {
console.warn(
'Background authentication features initialization failed:',
error
);
// Continue silently - authentication is not critical for UI display
}
};
// Use requestIdleCallback for non-blocking background execution
if (typeof requestIdleCallback !== 'undefined') {
requestIdleCallback(initializeAuth, { timeout: 5000 });
} else {
// Fallback for browsers without requestIdleCallback
setTimeout(initializeAuth, 50);
}
}
/**
* Load data in background
*/
async loadDataInBackground() {
try {
console.log('Loading customer outreach management data in background...');
// TODO: Replace with actual data loading
// Example:
// const data = await this.fetchData();
// this.updateUIWithData(data);
// For now, just remove skeleton loading after delay
setTimeout(() => {
this.updateUIWithActualContent();
}, 1000);
} catch (error) {
console.error('Background data loading failed:', error);
}
}
/**
* Update UI with actual content (replace skeleton loading)
*/
updateUIWithActualContent() {
const contentArea = document.getElementById('page-content-area');
if (contentArea) {
contentArea.innerHTML = `
<div style="padding: 1rem;">
<p>Customer Outreach Management content has loaded successfully!</p>
<!-- TODO: Add actual customer outreach management content here -->
</div>
`;
}
}
/**
* Show unauthenticated view
*/
showUnauthenticatedView() {
const contentArea = document.getElementById('page-content-area');
if (contentArea) {
contentArea.innerHTML = `
<div style="text-align: center; padding: 2rem;">
<h2 style="color: #022d54;">Authentication Required</h2>
<p style="color: #6c757d;">Please log in to access customer outreach management.</p>
</div>
`;
}
}
/**
* Show error message
*/
showError(error) {
const container = document.getElementById(this.options.containerId);
if (container) {
container.innerHTML = `
<div style="background: #f8f9fa; display: flex; align-items: center; justify-content: center; padding: 4rem 1rem;">
<div style="text-align: center; padding: 2rem; background: white; border-radius: 8px; border: 1px solid #e0e0e0; max-width: 500px;">
<h3 style="color: #d32f2f; margin-bottom: 1rem;">Error Loading Customer Outreach Management</h3>
<p style="color: #6c757d; margin-bottom: 1.5rem;">${error.message || error}</p>
<button onclick="location.reload()" style="padding: 10px 20px; background: #022d54; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 14px;">
Try Again
</button>
</div>
</div>
`;
}
}
}
// BULLETPROOF EXPORT MECHANISM - Ensures class is always available
(function () {
'use strict';
// Multiple export strategies to ensure maximum compatibility
// Strategy 1: Direct window assignment (most reliable)
if (typeof window !== 'undefined') {
window.AdminCustomerOutreachManagementPage =
AdminCustomerOutreachManagementPage;
}
// Strategy 2: Module exports for Node.js environments
if (typeof module !== 'undefined' && module.exports) {
module.exports = AdminCustomerOutreachManagementPage;
}
// Strategy 3: Global fallback
if (typeof global !== 'undefined') {
global.AdminCustomerOutreachManagementPage =
AdminCustomerOutreachManagementPage;
}
// Strategy 4: AMD/RequireJS support
if (typeof define === 'function' && define.amd) {
define([], function () {
return AdminCustomerOutreachManagementPage;
});
}
// Strategy 5: Self-executing verification
setTimeout(function () {
if (
typeof window !== 'undefined' &&
!window.AdminCustomerOutreachManagementPage
) {
console.warn(
'AdminCustomerOutreachManagementPage export failed, retrying...'
);
window.AdminCustomerOutreachManagementPage =
AdminCustomerOutreachManagementPage;
}
}, 10);
})();