const request = require("../common/super-agent-frp") const view = require("vvvview") const flyd = require('flyd') const flatMap = require('flyd/module/flatmap') const scanMerge = require('flyd/module/scanmerge') const h = require('virtual-dom/h') const Im = require('immutable') const Map = Im.Map const fromJS = Im.fromJS const OrderedMap = Im.OrderedMap const format = require('../common/format') var state = fromJS({is_visible: false, data: {}, coords: {top: 0, right: 0, left: 0}}) var $showClicks = flyd.stream() var $hideClicks = flyd.stream() const root = state => { if(state.get('is_visible') && state.get('data')) { return h('aside.infoCard', { style: { display: state.get('is_visible') ? 'block' : 'none', top: state.getIn(['coords', 'top']) - state.get('rows') * 23 + 'px', left: state.getIn(['coords', 'left']) + 'px', right: state.getIn(['coords', 'right']) + 'px' } }, [ h('i.fa.fa-times', {onclick: $hideClicks}), supporterTable(state.get('data')), h('a.button--micro', {href: state.getIn(['data', 'link'])}, 'View Full Details') ]) } else return h('span') } const supporterDetail = pair => { var [key, val] = pair if(key === 'link') return '' return val ? h('tr', [h('td', format.snake_to_words(key)), h('td', val)]) : '' } const supporterTable = supporter => h('table', supporter.entrySeq().map(supporterDetail).toJS()) const displayCard = (state, node) => { var clientTop = document.documentElement.clientTop var clientLeft = document.documentElement.clientLeft var box = node.getBoundingClientRect() var top = box.top + window.pageYOffset - clientTop var left = box.left + window.pageXOffset - clientLeft // Place card 15px from right when it's too far over. if(left + 350 >= document.body.offsetWidth) { state = state.setIn(['coords', 'right'], 15) state = state.setIn(['coords', 'left'], 'initial') } else { state = state.setIn(['coords', 'left'], left) state = state.setIn(['coords', 'right'], 'initial') } return state .setIn(['coords', 'top'], top) .set('is_visible', true) .set('data', false) } // Count the number of rows of data the supporter has const calculateRows = state => state.set('rows', state.get('data').entrySeq().filter(pair => { var [key, val] = pair return val && String(val).length }).count() + 1.5) const ajaxSupporter = node => { var id = node.getAttribute('data-id') return request.get(`/nonprofits/${app.nonprofit_id}/supporters/${id}/info_card`).perform() } var $responses = flatMap(ajaxSupporter, $showClicks) const setSupporterData = (state, response) => { var d = response.body if(!d) return state state = state.set('data', OrderedMap({ name: d.name , email: d.email , phone: utils.pretty_phone(d.phone) , address: utils.address_with_commas(d.address, d.city, d.state_code, d.zip_code,d.country) , organization: d.organization , total_raised: '$' + utils.cents_to_dollars(d.raised) , link: `/nonprofits/${app.nonprofit_id}/supporters?sid=${d.id}/` })) // Count the rows of present data to calculate the card height state = calculateRows(state) return state } var $state = flyd.immediate(scanMerge([ [$hideClicks, state => state.set('is_visible', false)], [$showClicks, displayCard], [$responses, setSupporterData], ], state)) var infoCard = view(root, document.body, state) flyd.map(infoCard, $state) // XXX viewscript lol appl.def('show_supporter_info_card', function(node){ $showClicks(appl.prev_elem(node)) })