import { completedIcon, pendingIcon, processingIcon } from './constants.js'; import { apiBaseUrl, clientId, estTimeStep1, estTimeStep2 } from './main.js'; import { t, onLanguageChange } from './i18n.js'; const statusFaceCheckElement = document.getElementById('status-face-check'); const baseServices = [ { id: 1, name: 'Geolocation', displayKey: 'serviceGeolocation', }, { id: 2, name: 'Timestamp', displayKey: 'serviceTimestamp', }, { id: 3, name: 'AIGVDetection', displayKey: 'serviceAIGVDetection', }, { id: 4, name: 'Report', displayKey: 'serviceReport', }, ]; const createInitData = () => baseServices.map((service) => ({ ...service, status: 'pending', percent: 0, })); export let statusStep1 = 'pending'; export let statusStep2 = 'pending'; let _estTimeStep1 = 0; let _estTimeStep2 = 0; function formatText(key, params = {}) { let value = t(key) || ''; Object.entries(params).forEach(([k, v]) => { value = value.replace(`{${k}}`, v); }); return value; } function getDisplayName(item) { if (item.displayKey) { const translated = t(item.displayKey); if (translated) return translated; } return item.displayName || item.name || ''; } function renderStatus(newValue, countItem, countItemCompleted) { const percent = Math.round((countItemCompleted / countItem) * 100); const step1Message = statusStep1 === 'pending' ? `${t('waitingLabel')} - ${ _estTimeStep1 === 0 ? t('calculatingLabel') : formatText('minutesRemaining', { minutes: _estTimeStep1 }) }` : statusStep1 === 'processing' ? formatText('processingEstimate', { minutes: _estTimeStep1 }) : t('completedLabel'); const step2Message = statusStep2 === 'pending' ? `${t('waitingLabel')} - ${ _estTimeStep2 === 0 ? t('calculatingLabel') : formatText('beginsAfterStep1', { minutes: _estTimeStep2 }) }` : statusStep2 === 'processing' ? formatText('processingEstimate', { minutes: _estTimeStep2 }) : t('completedLabel'); return `

${formatText('statusHeaderCompleted', { completed: countItemCompleted, total: countItem, })}

${formatText('statusPercent', { percent })}

${newValue .map((item, index) => { return ` ${ index === 0 ? `
${formatText('stepTitle', { step: 1, })} ${step1Message}
` : '' } ${ index === 3 ? `
${formatText('stepTitle', { step: 2, })} ${step2Message}
` : '' }
${ item.status === 'completed' ? completedIcon : item.status === 'processing' ? processingIcon : pendingIcon }

${formatText('serviceLabel', { index: index + 1, total: countItem, name: getDisplayName(item), })}

${ item.status === 'processing' ? t('statusProcessing') : item.status === 'completed' ? t('statusCompleted') : t('statusPending') }

`; }) .join('')}
`; } let data = {}; Object.defineProperty(data, 'value', { set(newValue) { const countItem = newValue.length; const countItemCompleted = newValue.filter( (item) => item.status === 'completed' ).length; statusStep1 = 'pending'; statusStep2 = newValue.find((i) => i.name === 'Report').status; if ( ['Geolocation', 'Timestamp', 'AIGVDetection'].every((item) => { return newValue.find((i) => i.name === item).status === 'completed'; }) ) { statusStep1 = 'completed'; } else if ( ['Geolocation', 'Timestamp', 'AIGVDetection'].some((item) => { return newValue.find((i) => i.name === item).status === 'processing'; }) ) { statusStep1 = 'processing'; } const content = renderStatus(newValue, countItem, countItemCompleted); statusFaceCheckElement.innerHTML = content; this._value = newValue; }, get() { return this._value; }, }); data.value = createInitData(); onLanguageChange(() => { if (data.value) { data.value = data.value; } }); export function initValueData() { console.log('test...'); } let isLoading = {}; Object.defineProperty(isLoading, 'value', { set(newValue) { if (newValue) { // statusFaceCheckElement.classList.remove('display-none'); data.value = createInitData(); } else { statusFaceCheckElement.classList.add('display-none'); data.value = createInitData(); } this._value = newValue; }, get() { return this._value; }, }); const source = new EventSource(apiBaseUrl + `v1/sse?client_id=${clientId}`); source.onopen = () => console.log('✅ SSE connected'); let _interval; source.onmessage = (event) => { try { const _data = JSON.parse(event.data); console.log(_data); if (_data?.status) { if (_data.status === 'start') { isLoading.value = true; _estTimeStep1 = estTimeStep1; _estTimeStep2 = estTimeStep2; _interval = setInterval(() => { if (statusStep1 === 'processing' && _estTimeStep1 > 1) { _estTimeStep1 -= 1; } if (statusStep2 === 'processing' && _estTimeStep2 > 1) { _estTimeStep2 -= 1; } data.value = data.value; }, 60000); } else { setTimeout(() => { isLoading.value = false; _estTimeStep1 = 0; _estTimeStep2 = 0; data.value = createInitData(); clearInterval(_interval); }, 2500); } } if (_data?.status_service) { const updatedData = data.value?.map((item) => { if (_data.service === item.name) { if (_data.status_service === 'completed') { return { ...item, status: _data.status_service, percent: 100 }; } return { ...item, status: _data.status_service }; } return item; }); data.value = updatedData; } } catch (err) { console.log('err', err); } }; source.onerror = (err) => { console.error('❌ SSE error:', err); };