/**
* Feedback UI Components for Detection Accuracy
* Provides thumbs-up/down buttons, feedback forms, and missed detection reporting
*/
(function() {
'use strict';
var Feedback = {
// State
pendingFeedback: null,
feedbackPanelVisible: false,
// Event types
EventTypes: {
BLOB_DETECTION: 'blob_detection',
ZONE_TRANSITION: 'zone_transition',
FALL_ALERT: 'fall_alert',
ANOMALY: 'anomaly'
},
// Feedback types
FeedbackTypes: {
TRUE_POSITIVE: 'TRUE_POSITIVE',
FALSE_POSITIVE: 'FALSE_POSITIVE',
FALSE_NEGATIVE: 'FALSE_NEGATIVE',
WRONG_IDENTITY: 'WRONG_IDENTITY',
WRONG_ZONE: 'WRONG_ZONE'
},
/**
* Initialize the feedback module
*/
init: function() {
this.createFeedbackPanel();
this.createMissedDetectionButton();
console.log('[Feedback] Module initialized');
},
/**
* Create the feedback panel (hidden by default)
*/
createFeedbackPanel: function() {
var panel = document.createElement('div');
panel.id = 'feedback-panel';
panel.className = 'feedback-panel';
panel.style.display = 'none';
panel.innerHTML = '\
\
';
document.body.appendChild(panel);
// Add styles
this.addStyles();
},
/**
* Create the "Report missed detection" button
*/
createMissedDetectionButton: function() {
var btn = document.createElement('button');
btn.id = 'missed-detection-btn';
btn.className = 'missed-detection-btn';
btn.innerHTML = '⚠ Report missed detection';
btn.onclick = function() { Feedback.showMissedDetectionForm(); };
document.body.appendChild(btn);
},
/**
* Show feedback panel for a specific event (thumbs-down clicked)
*/
showFeedbackPanel: function(eventID, eventType, eventTime, details) {
this.pendingFeedback = {
eventID: eventID,
eventType: eventType,
eventTime: eventTime,
details: details || {}
};
var panel = document.getElementById('feedback-panel');
if (!panel) return;
// Update event info
panel.querySelector('.feedback-event-type').textContent = this.formatEventType(eventType);
panel.querySelector('.feedback-event-time').textContent = eventTime ? new Date(eventTime).toLocaleString() : 'Now';
// Reset form
var radios = panel.querySelectorAll('input[name="feedback-type"]');
radios.forEach(function(r) { r.checked = false; });
document.getElementById('feedback-notes').value = '';
// Show panel
panel.style.display = 'block';
this.feedbackPanelVisible = true;
},
/**
* Hide the feedback panel
*/
hideFeedbackPanel: function() {
var panel = document.getElementById('feedback-panel');
if (panel) {
panel.style.display = 'none';
}
this.pendingFeedback = null;
this.feedbackPanelVisible = false;
},
/**
* Submit feedback to the server
*/
submitFeedback: function() {
if (!this.pendingFeedback) return;
var panel = document.getElementById('feedback-panel');
var selected = panel.querySelector('input[name="feedback-type"]:checked');
if (!selected) {
alert('Please select what was wrong with this detection.');
return;
}
var feedbackType = selected.value;
var notes = document.getElementById('feedback-notes').value;
var details = Object.assign({}, this.pendingFeedback.details);
if (notes) {
details.notes = notes;
}
this.sendFeedback(
this.pendingFeedback.eventID,
this.pendingFeedback.eventType,
feedbackType,
details
);
this.hideFeedbackPanel();
},
/**
* Submit thumbs-up (true positive) feedback
*/
submitThumbsUp: function(eventID, eventType, details) {
this.sendFeedback(eventID, eventType, this.FeedbackTypes.TRUE_POSITIVE, details || {});
},
/**
* Send feedback to the API
*/
sendFeedback: function(eventID, eventType, feedbackType, details) {
var data = {
event_id: eventID || '',
event_type: eventType,
feedback_type: feedbackType,
details: details
};
fetch('/api/learning/feedback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(function(res) { return res.json(); })
.then(function(result) {
if (result.success) {
console.log('[Feedback] Submitted:', feedbackType, 'for event', eventID);
if (window.SpaxelApp && window.SpaxelApp.showToast) {
window.SpaxelApp.showToast('Thank you for your feedback!', 'success');
}
}
})
.catch(function(err) {
console.error('[Feedback] Failed to submit:', err);
});
},
/**
* Show missed detection form
*/
showMissedDetectionForm: function() {
var modal = document.createElement('div');
modal.id = 'missed-detection-modal';
modal.className = 'missed-detection-modal';
modal.innerHTML = '\