/**
*
* @param {HTMLElement} parentDiv
*/
window.LGWIDGET.thumbs_up_thumbs_down = function (parentDiv) {
const renderResults = (results = []) => {
// {
// "ok": 1,
// "data": [
// {
// "_id": "no",
// "count": 2
// },
// {
// "_id": "yes",
// "count": 3
// }
// ]
// }
const items = {
Yes: 0,
No: 0,
}
const total = results.reduce((acc, result) => acc + result.count, 0)
results.forEach(result => {
const percentage = result.count / total * 100
items[result._id] = percentage.toFixed(1)
})
const orderedResults = [
{ label: 'Yes', percentage: items['Yes'] },
{ label: 'No', percentage: items['No'] },
]
let renderedResults = `
`
for (const row of orderedResults) {
renderedResults += `
${row.label}
${row.percentage}%
`
}
renderedResults += '
'
return renderedResults
}
// Generate a unique class to scope everything to.
// https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
const unique_id = `c${(Math.random() + 1).toString(36).substring(7)}`
const base_class = `thumbs-up-down${unique_id}`
const {
site = '',
slug = '',
question = '',
thumbs_up_text = 'Yes',
thumbs_down_text = 'No',
settings = '{}',
results = 'false',
thanks = 'Thank you for your feedback',
} = parentDiv.dataset
let {
url = 'https://api.leafmedia.io/widget',
} = parentDiv.dataset
if (results === 'true') {
url = `${url}?results=true`
}
// local storage check
const storageKey = `LGWIDGET.thumbs-up-down:${question}`
const voted = localStorage.getItem(storageKey) ?? 'false'
if (voted === 'true') {
return
}
const objToStyle = obj => Object.entries(obj)
.reduce((acc, [key, value]) => (`${acc }${key}: ${value};`), '')
let parsed = {}
try {
parsed = JSON.parse(settings)
// eslint-disable-next-line no-empty
} catch (e) {}
const {
base = {},
base_question = {},
base_container = {},
base_item = {},
base_item__hover = {},
base_thumbs_up = {},
base_thumbs_down = {},
base_thumbs_up__hover = {},
base_thumbs_down__hover = {},
base_thanks = {},
results_row = {},
results_row__labels = {},
results_bar_color = '#008eff',
} = parsed
const base_style = {
display: 'flex',
'flex-direction': 'column',
'justify-content': 'space-between',
gap: '15px',
padding: '20px',
'background-color': '#fff',
...base,
}
const base_question_style = {
'text-align': 'center',
'font-size': '30px',
...base_question,
}
const base_container_style = {
display: 'flex',
'justify-content': 'space-between',
gap: '15px',
...base_container,
}
const base_item_style = {
height: '50px',
display: 'flex',
flex: '1',
'justify-content': 'center',
'align-items': 'center',
'font-size': '20px',
'background-color': '#eee',
...base_item,
}
const base_item__hover_style = {
cursor: 'pointer',
...base_item__hover,
}
const base_thumbs_up_style = {
...base_thumbs_up,
}
const base_thumbs_down_style = {
...base_thumbs_down,
}
const base_thumbs_up__hover_style = {
...base_thumbs_up__hover,
}
const base_thumbs_down__hover_style = {
...base_thumbs_down__hover,
}
const base_thanks_style = {
height: '50px',
display: 'flex',
flex: '1',
'justify-content': 'center',
'align-items': 'center',
'font-size': '20px',
...base_thanks,
}
const results_row_style = {
display: 'flex',
'justify-content': 'space-between',
gap: '10px',
'margin-bottom': '5px',
height: '30px',
...results_row,
}
const results_row__labels_style = {
width: '45px',
display: 'flex',
'justify-content': 'center',
'align-items': 'center',
...results_row__labels,
}
const results_row__percentage_style = {
...results_row__labels_style,
'justify-content': 'right',
}
const thanksHtml = `${thanks}
`
parentDiv.innerHTML = `
${question}
${thumbs_up_text}
${thumbs_down_text}
`
const $thumbs = document.querySelectorAll(`.${base_class}-item`)
$thumbs.forEach($thumb => {
$thumb.addEventListener('click', e => {
if (voted === 'true') {
return
}
// localStorage.setItem(storageKey, 'true')
// voted = 'true'
// todo uncomment local storage
const $classList = e.target.classList
const key = $classList.contains('thumbs-up') ? thumbs_up_text : thumbs_down_text
const answer = {}
answer[key] = 1
const payload = {
site,
slug,
type: 'thumbs-up-down',
prompt: question,
answer,
}
let response = []
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})
.then(r => r.json())
.then(r => response = r)
.catch(e => console.error(e))
.finally(() => {
const $element = document.querySelector(`.${base_class}-container`)
// if epmd response fails, just show thanks
if (!Array.isArray(response)) {
return $element.innerHTML = thanksHtml
}
if (results === 'true') {
return $element.innerHTML = renderResults(response)
}
return $element.innerHTML = thanksHtml
})
})
})
}