- Adaptation of DPA and T&Cs - Refer to privacy statement as DPA, not a privacy statement - Startup of enforcing signed DPA and T&Cs - Adaptation of eveai_chat_client to ensure we retrieve correct DPA & T&Cs
191 lines
6.3 KiB
JavaScript
191 lines
6.3 KiB
JavaScript
// eveai_chat_client/static/assets/js/composables/useContentModal.js
|
|
|
|
import { ref, reactive, provide, inject } from 'vue';
|
|
|
|
// Injection key for the composable
|
|
export const CONTENT_MODAL_KEY = Symbol('contentModal');
|
|
|
|
// Create the composable
|
|
export function useContentModal() {
|
|
// Reactive state for modal
|
|
const modalState = reactive({
|
|
show: false,
|
|
title: '',
|
|
content: '',
|
|
version: '',
|
|
loading: false,
|
|
error: false,
|
|
errorMessage: '',
|
|
lastContentUrl: '' // Add this for retry functionality
|
|
});
|
|
|
|
// Content cache to avoid repeated API calls
|
|
const contentCache = ref({});
|
|
|
|
// Show modal with content
|
|
const showModal = async (options = {}) => {
|
|
const {
|
|
title = 'Content',
|
|
contentUrl = null,
|
|
content = null,
|
|
version = ''
|
|
} = options;
|
|
|
|
// Set initial state
|
|
modalState.show = true;
|
|
modalState.title = title;
|
|
modalState.content = content || '';
|
|
modalState.version = version;
|
|
modalState.loading = !!contentUrl; // Only show loading if we need to fetch content
|
|
modalState.error = false;
|
|
modalState.errorMessage = '';
|
|
modalState.lastContentUrl = contentUrl || ''; // Store for retry functionality
|
|
|
|
// If content is provided directly, no need to fetch
|
|
if (content) {
|
|
modalState.loading = false;
|
|
return;
|
|
}
|
|
|
|
// If contentUrl is provided, fetch the content
|
|
if (contentUrl) {
|
|
await loadContent(contentUrl);
|
|
}
|
|
};
|
|
|
|
// Hide modal
|
|
const hideModal = () => {
|
|
console.log('Hiding content modal');
|
|
modalState.show = false;
|
|
modalState.title = '';
|
|
modalState.content = '';
|
|
modalState.version = '';
|
|
modalState.loading = false;
|
|
modalState.error = false;
|
|
modalState.errorMessage = '';
|
|
modalState.lastContentUrl = ''; // Clear for next use
|
|
};
|
|
|
|
// Load content from API
|
|
const loadContent = async (contentUrl) => {
|
|
try {
|
|
console.log('Loading content from:', contentUrl);
|
|
modalState.loading = true;
|
|
modalState.error = false;
|
|
modalState.errorMessage = '';
|
|
|
|
// Check cache first
|
|
if (contentCache.value[contentUrl]) {
|
|
console.log('Content found in cache for:', contentUrl);
|
|
const cached = contentCache.value[contentUrl];
|
|
modalState.content = cached.content;
|
|
modalState.version = cached.version;
|
|
modalState.loading = false;
|
|
return;
|
|
}
|
|
|
|
// Fetch from API
|
|
console.log('Fetching content from API:', contentUrl);
|
|
const response = await fetch(contentUrl);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('API response received:', {
|
|
hasSuccess: data.success !== undefined,
|
|
hasContent: data.content !== undefined,
|
|
hasError: data.error !== undefined,
|
|
contentLength: data.content ? data.content.length : 0
|
|
});
|
|
|
|
// Support both response formats
|
|
if (data.success !== undefined) {
|
|
// New format with success property
|
|
if (data.success) {
|
|
modalState.content = data.content || '';
|
|
modalState.version = data.version || '';
|
|
} else {
|
|
throw new Error(data.error || 'Onbekende fout bij het laden van content');
|
|
}
|
|
} else if (data.content !== undefined) {
|
|
// Legacy format without success property (current dpa/terms endpoints)
|
|
modalState.content = data.content || '';
|
|
modalState.version = data.version || '';
|
|
} else if (data.error) {
|
|
// Error response format
|
|
throw new Error(data.message || data.error || 'Er is een fout opgetreden');
|
|
} else {
|
|
throw new Error('Invalid response format: no content or success property found');
|
|
}
|
|
|
|
// Cache the result
|
|
contentCache.value[contentUrl] = {
|
|
content: modalState.content,
|
|
version: modalState.version,
|
|
timestamp: Date.now()
|
|
};
|
|
} catch (error) {
|
|
console.error('Error loading content:', error);
|
|
modalState.error = true;
|
|
modalState.errorMessage = error.message || 'Er is een fout opgetreden bij het laden van de content.';
|
|
} finally {
|
|
modalState.loading = false;
|
|
}
|
|
};
|
|
|
|
// Retry loading content
|
|
const retryLoad = async () => {
|
|
if (modalState.lastContentUrl) {
|
|
console.log('Retrying content load for:', modalState.lastContentUrl);
|
|
await loadContent(modalState.lastContentUrl);
|
|
} else {
|
|
console.warn('No content URL available for retry');
|
|
modalState.error = true;
|
|
modalState.errorMessage = 'Geen content URL beschikbaar voor opnieuw proberen.';
|
|
}
|
|
};
|
|
|
|
// Clear cache (useful for development or when content updates)
|
|
const clearCache = () => {
|
|
contentCache.value = {};
|
|
};
|
|
|
|
// Get cache size for debugging
|
|
const getCacheInfo = () => {
|
|
return {
|
|
size: Object.keys(contentCache.value).length,
|
|
entries: Object.keys(contentCache.value)
|
|
};
|
|
};
|
|
|
|
return {
|
|
// State
|
|
modalState,
|
|
|
|
// Methods
|
|
showModal,
|
|
hideModal,
|
|
loadContent,
|
|
retryLoad,
|
|
clearCache,
|
|
getCacheInfo
|
|
};
|
|
}
|
|
|
|
// Provider function to be used in the root component
|
|
export function provideContentModal() {
|
|
const contentModal = useContentModal();
|
|
provide(CONTENT_MODAL_KEY, contentModal);
|
|
return contentModal;
|
|
}
|
|
|
|
// Injector function to be used in child components
|
|
export function injectContentModal() {
|
|
const contentModal = inject(CONTENT_MODAL_KEY);
|
|
if (!contentModal) {
|
|
throw new Error('useContentModal must be provided before it can be injected');
|
|
}
|
|
return contentModal;
|
|
} |