Spaces:
Running
Running
| import { confirmIcon } from './constants.js'; | |
| import { apiBaseUrl, output } from './main.js'; | |
| import { t, onLanguageChange } from './i18n.js'; | |
| const feedbackButton = document.getElementById('btn-feedback-face-check'); | |
| const closeFeedback = document.getElementById('close-feedback-1765253515534'); | |
| const liveChat = document.getElementById('live-chat-1765253515534'); | |
| const feedbackContainer = document.getElementById('feedback-1765253515534'); | |
| const blockNotification = document.getElementById( | |
| 'block-notification-1765336324468' | |
| ); | |
| const blockQuestion = document.getElementById('block-question-1765336324468'); | |
| const footerFeedback = document.getElementById('footer-feedback-1765336324468'); | |
| const REQUIRED_QUESTION_IDS = ['q1', 'q2']; | |
| const isSuccess = {}; | |
| const isLoading = {}; | |
| const isFailed = {}; | |
| let isLoadingInternal = false; | |
| function updateFeedbackButtonLabel() { | |
| if (!feedbackButton) return; | |
| feedbackButton.innerText = isLoadingInternal | |
| ? t('sendingLabel') | |
| : t('sendButton'); | |
| } | |
| onLanguageChange(() => { | |
| updateFeedbackButtonLabel(); | |
| }); | |
| function areRequiredQuestionsAnswered() { | |
| return REQUIRED_QUESTION_IDS.every((id) => | |
| document.querySelector(`#${id} input[type="radio"]:checked`) | |
| ); | |
| } | |
| function syncFeedbackButtonState() { | |
| const missingRequired = !areRequiredQuestionsAnswered(); | |
| const shouldDisable = isLoadingInternal || missingRequired; | |
| if (feedbackButton) { | |
| feedbackButton.disabled = shouldDisable; | |
| feedbackButton.classList.toggle('btn-disabled', shouldDisable); | |
| feedbackButton.classList.toggle('disable', shouldDisable); | |
| } | |
| } | |
| Object.defineProperty(isSuccess, 'value', { | |
| set(newValue) { | |
| if (newValue) { | |
| if (blockNotification) { | |
| const contentSentSuccessfully = `<div class="notification-content-feedback"> | |
| ${confirmIcon} | |
| <p class="notification-message">${t('feedbackSuccess')}</p> | |
| </div>`; | |
| blockNotification.innerHTML = contentSentSuccessfully; | |
| blockNotification.classList.remove('display-none'); | |
| feedbackButton.disabled = true; | |
| feedbackButton.classList.add('btn-disabled', 'disable'); | |
| footerFeedback.classList.add('display-none'); | |
| } | |
| if (blockQuestion) { | |
| blockQuestion.classList.add('display-none'); | |
| } | |
| } else { | |
| blockNotification.classList.add('display-none'); | |
| blockQuestion.classList.remove('display-none'); | |
| blockNotification.innerHTML = ''; | |
| syncFeedbackButtonState(); | |
| footerFeedback.classList.remove('display-none'); | |
| } | |
| this._value = newValue; | |
| }, | |
| get() { | |
| return this._value; | |
| }, | |
| }); | |
| Object.defineProperty(isLoading, 'value', { | |
| set(newValue) { | |
| isLoadingInternal = newValue; | |
| updateFeedbackButtonLabel(); | |
| this._value = newValue; | |
| syncFeedbackButtonState(); | |
| }, | |
| get() { | |
| return this._value; | |
| }, | |
| }); | |
| function resetFeedbackForm() { | |
| const radios = document.querySelectorAll('.question input[type="radio"]'); | |
| const textareas = document.querySelectorAll('.feedback textarea'); | |
| const stars = document.querySelectorAll('.options-stars .star'); | |
| radios.forEach((radio) => { | |
| radio.checked = false; | |
| }); | |
| textareas.forEach((textarea) => { | |
| textarea.value = ''; | |
| }); | |
| stars.forEach((star) => { | |
| star.classList.remove('active'); | |
| }); | |
| syncFeedbackButtonState(); | |
| } | |
| function assignRadioValues() { | |
| const enValues = { | |
| q0: [ | |
| 'Journalist / Fact Checker', | |
| 'Researcher / Student', | |
| 'Law Enforcement / OSINT', | |
| 'General User', | |
| ], | |
| q1: [ | |
| 'Spot on', | |
| 'Mostly correct', | |
| 'Mixed results', | |
| 'Missed key context', | |
| 'Completely wrong', | |
| ], | |
| q2: [ | |
| 'Yes', | |
| 'No - It was actually Real', | |
| 'No - It was actually AI-Generated', | |
| ], | |
| q3: [ | |
| 'All links worked and were relevant', | |
| 'Some links were broken/dead', | |
| 'Links were unrelated to the topic', | |
| ], | |
| q4: [ | |
| 'No issues', | |
| 'Invented dates/times', | |
| 'Invented people/names', | |
| "Citations that don't exist", | |
| ], | |
| q5: [ | |
| 'Very Clear', | |
| 'Clear', | |
| 'Moderately Clear', | |
| 'Slightly Clear', | |
| 'Not Clear', | |
| ], | |
| q6: ['Yes', 'Partially', 'No'], | |
| q7: [ | |
| 'Very Clear', | |
| 'Clear', | |
| 'Moderately Clear', | |
| 'Slightly Clear', | |
| 'Not Clear', | |
| ], | |
| q8: ['Yes', 'Not Applicable', 'No'], | |
| q9: [ | |
| 'Clearly Explained', | |
| 'Well Explained', | |
| 'Moderately Explained', | |
| 'Poorly Explained', | |
| 'Not Explained', | |
| ], | |
| }; | |
| const questions = document.querySelectorAll('.question'); | |
| questions.forEach((question) => { | |
| const questionId = question.id; | |
| const options = question.querySelectorAll('.option'); | |
| options.forEach((option, index) => { | |
| const radio = option.querySelector('input[type="radio"]'); | |
| if (!radio) return; | |
| const enList = enValues[questionId]; | |
| if (enList && enList[index]) { | |
| radio.value = enList[index]; | |
| return; | |
| } | |
| // Fallbacks if question not mapped | |
| if (questionId === '') { | |
| radio.value = String(index + 1); | |
| } else { | |
| const optionText = option | |
| .querySelector('.option-text') | |
| ?.textContent?.trim(); | |
| radio.value = optionText || radio.value || String(index + 1); | |
| } | |
| }); | |
| }); | |
| } | |
| function initializeStarRatings() { | |
| const starGroups = document.querySelectorAll('.options-stars'); | |
| starGroups.forEach((group) => { | |
| const options = Array.from(group.querySelectorAll('.option')); | |
| const radios = options | |
| .map((option) => option.querySelector('input[type="radio"]')) | |
| .filter(Boolean); | |
| const stars = options | |
| .map((option) => option.querySelector('.star')) | |
| .filter(Boolean); | |
| const updateStars = (activeIndex) => { | |
| stars.forEach((star, index) => { | |
| star.classList.toggle('active', index <= activeIndex); | |
| }); | |
| }; | |
| if (radios.length === 0 || stars.length === 0) { | |
| return; | |
| } | |
| radios.forEach((radio, index) => { | |
| radio.value = radio.value || String(index + 1); | |
| radio.addEventListener('change', () => { | |
| updateStars(index); | |
| }); | |
| if (radio.checked) { | |
| updateStars(index); | |
| } | |
| }); | |
| if (!radios.some((radio) => radio.checked)) { | |
| updateStars(-1); | |
| } | |
| }); | |
| } | |
| function collectFeedbackData() { | |
| const responses = {}; | |
| const questions = document.querySelectorAll('.question'); | |
| questions.forEach((question) => { | |
| if (!question.id) return; | |
| const radios = question.querySelectorAll('input[type="radio"]'); | |
| const selected = question.querySelector('input[type="radio"]:checked'); | |
| const textarea = question.querySelector('textarea'); | |
| if (radios.length > 0) { | |
| if (!selected) { | |
| responses[question.id] = '-'; | |
| } else { | |
| let value = selected.value; | |
| if (!value) { | |
| const optionText = selected | |
| .closest('.opt') | |
| ?.querySelector('.option-text') | |
| ?.textContent?.trim(); | |
| value = optionText || '-'; | |
| } | |
| responses[question.id] = value; | |
| } | |
| if (textarea) { | |
| const textValue = textarea.value.trim(); | |
| responses[`${question.id}_comments`] = textValue || '-'; | |
| } | |
| } else if (textarea) { | |
| const textValue = textarea.value.trim(); | |
| responses[question.id] = textValue || '-'; | |
| } else { | |
| responses[question.id] = '-'; | |
| } | |
| }); | |
| return responses; | |
| } | |
| async function handleFeedbackSubmit(event) { | |
| event.preventDefault(); | |
| if (!areRequiredQuestionsAnswered()) { | |
| syncFeedbackButtonState(); | |
| return; | |
| } | |
| isLoading.value = true; | |
| // Simulate async feedback submission | |
| const feedbackData = collectFeedbackData(); | |
| const _output = `${output?.readme_content?.case_summary?.title || ''}${ | |
| output?.readme_content?.case_summary?.content || '' | |
| }${output?.readme_content?.content_classification?.title || ''}${ | |
| output?.readme_content?.content_classification?.content || '' | |
| }${output?.readme_content?.verified_evidence?.title || ''} | |
| ${output?.readme_content?.verified_evidence?.source_details?.title || ''}${ | |
| output?.readme_content?.verified_evidence?.source_details?.content || '' | |
| }${output?.readme_content?.verified_evidence?.where?.title || ''}${ | |
| output?.readme_content?.verified_evidence?.where?.content || '' | |
| }${output?.readme_content?.verified_evidence?.when?.title || ''}${ | |
| output?.readme_content?.verified_evidence?.when?.content || '' | |
| }${output?.readme_content?.verified_evidence?.who?.title || ''}${ | |
| output?.readme_content?.verified_evidence?.who?.content || '' | |
| }${output?.readme_content?.verified_evidence?.why?.title || ''}${ | |
| output?.readme_content?.verified_evidence?.why?.content || '' | |
| }${output?.readme_content?.forensic_analysis?.title || ''}${ | |
| output?.readme_content?.forensic_analysis?.content || '' | |
| }${output?.readme_content?.other_evidence?.title || ''}${ | |
| output?.readme_content?.other_evidence?.content || '' | |
| } | |
| `; | |
| feedbackData['q11'] = _output.trim().length > 0 ? _output.trim() : '-'; | |
| axios | |
| .post(apiBaseUrl + 'v1/survey', feedbackData, { | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }) | |
| .then((response) => { | |
| console.log('Feedback submitted successfully:', response.data); | |
| isLoading.value = false; | |
| resetFeedbackForm(); | |
| isSuccess.value = true; | |
| }) | |
| .catch((error) => { | |
| console.error('Error submitting feedback:', error); | |
| isLoading.value = false; | |
| isFailed.value = true; | |
| }); | |
| } | |
| assignRadioValues(); | |
| initializeStarRatings(); | |
| syncFeedbackButtonState(); | |
| const requiredRadios = document.querySelectorAll( | |
| '#q1 input[type="radio"], #q2 input[type="radio"]' | |
| ); | |
| requiredRadios.forEach((radio) => { | |
| radio.addEventListener('change', () => { | |
| syncFeedbackButtonState(); | |
| }); | |
| }); | |
| if (feedbackButton) { | |
| feedbackButton.addEventListener('click', handleFeedbackSubmit); | |
| } | |
| updateFeedbackButtonLabel(); | |
| window.collectFeedbackData = collectFeedbackData; | |
| closeFeedback.addEventListener('click', () => { | |
| if (feedbackContainer) { | |
| feedbackContainer.classList.add('display-none'); | |
| liveChat.classList.remove('display-none'); | |
| isLoading.value = false; | |
| isFailed.value = false; | |
| isSuccess.value = false; | |
| } | |
| }); | |
| liveChat.addEventListener('click', () => { | |
| if (feedbackContainer) { | |
| feedbackContainer.classList.remove('display-none'); | |
| liveChat.classList.add('display-none'); | |
| } | |
| }); | |