diff options
Diffstat (limited to 'desk/web/components/poll.hoon')
-rw-r--r-- | desk/web/components/poll.hoon | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/desk/web/components/poll.hoon b/desk/web/components/poll.hoon new file mode 100644 index 0000000..3184ec0 --- /dev/null +++ b/desk/web/components/poll.hoon @@ -0,0 +1,208 @@ +/- *polls +/+ sr=sortug, kaji, lib=boke +|% +++ css ^~ %- trip +''' +.new-poll{ + border: 1px solid black; + width: 80%; + margin: auto; + margin-bottom: 1rem; + padding: 1rem; + #poll-title{ + font-size: 1.5rem; + padding: 0.3rem; + margin-bottom: 0.5rem; + text-align: center; + } + & input[type=text]{ + display: block; + line-height: 1.5rem; + width: 80%; + margin: 0.3rem auto; + } + #final-row{ + border-top: 1px solid black; + } + #bet-input{ + width: 30%; + display: inline-block; + margin-left: 1ch; + } +} +@media (max-width: 800px){ + #final-row{ + display: block; + } +} + +''' +++ script ^~ %- trip +''' +function newOpts(){ + const button = document.getElementById("add-opt-button"); + const container = document.getElementById("options"); + + button.addEventListener("click", (e) => { + console.log(e, "clck") + e.preventDefault(); + e.stopPropagation(); + + const currentOpts = container.querySelectorAll(".opt"); + const index = currentOpts.length; + + const input = document.createElement("input"); + input.classList.add("opt"); + input.type = "text"; + input.name = `poll-opt-${index}`; + input.placeholder = "New Option"; + input.autocomplete = "off"; + container.appendChild(input); + }) +} +setTimeout(newOpts, 500); +''' +++ form +|= =bowl:gall ^- manx +;form +;div.new-poll + ;style:"{css}" + ;input#poll-title(type "text", name "poll-title", placeholder "Poll Question"); + ;div#options + ;input.opt(type "text", name "poll-opt-0", placeholder "First Option", autocomplete "off"); + ;input.opt(type "text", name "poll-opt-1", placeholder "Second Option", autocomplete "off"); + == + ;div.f1 + ;div + ;label: Multiple Choice + ;input(type "checkbox", name "poll-multiple"); + == + ;button#add-opt-button(type "button"):"Add" + == + ;div#final-row.f1 + ;div + ;label: Require betting + ;input#bet-input(type "text", name "poll-min-bet"); + == + ;div + ;label: Expires + ;input(type "datetime-local", name "poll-expiry"); + == + == + ;script:"{script}" +== +== ++$ opt + $: text=@t + votes=(set @p) + == +++ show +|= [=poll =bowl:gall] ^- manx + =/ poll-type=tape ?: ?=(%exc -.votes.poll) "Single choice poll" "Multiple choice poll" + =/ pid-string (enc:kaji [author.poll time.poll]) + =/ total=@ud + ?: ?=(%exc -.votes.poll) + ~(wyt by p.votes.poll) + %- ~(rep by p.votes.poll) |= [it=[@ud m=(map @p (set @ud))] acc=@ud] + (add acc ~(wyt by m.it)) + + |^ + ?: (gth now.bowl expiry.poll) expired-poll fresh-poll + ++ fresh-poll ^- manx + =/ expiry-string (post-date-ago:lib now.bowl expiry.poll %yau) + ;div.poll + ;div.top-row + ;h6:"Open Poll" + ;h3.hs:"{(trip text.poll)}" + == + ;div.options + ;* %+ mapi:sr options.poll fresh-opt + == + ;div.bottom-row.f1 + ;div.poll-type:"{poll-type}" + ;div.expiry:"Expires in {expiry-string}" + == + == + ++ fresh-opt + |= [i=@ud text=@t] + =/ payload (enc:kaji [author.poll time.poll i]) + =/ stats (opt-stats i) + =/ pct (scow %ud pct.stats) + =/ style "width: {pct}%;" + =/ classes + ?: ?=(%exc -.votes.poll) + =/ have-voted (~(get by p.votes.poll) src.bowl) + ?~ have-voted + "poll-option open" + ?: .=(u.have-voted i) + "poll-option voted" + "poll-option not-voted" + :: inc + =/ opt-votes (~(get by p.votes.poll) i) + ?~ opt-votes "poll-option open" + =/ my-votes (~(get by u.opt-votes) src.bowl) + ?~ my-votes "poll-option open" + ?: (~(has in u.my-votes) i) + "poll-option voted" + "poll-option open" + + + ;div + =class classes + =kaji "poke" + =action "vote-poll" + =name "option" + =payload payload + + ;div.poll-option-color(style style); + ;div.f1.inner + =name "option-{(scow %ud i)}" + =payload "vote" + ;div.poll-option-name.hs:"{(trip text)}" + ;div:"{pct}%" + == + == + ++ expired-poll ^- manx + =/ expiry-string (post-date-ago:lib expiry.poll now.bowl %yau) + ;div.poll + ;div.top-row + ;h6:"Closed Poll" + ;h3.hs:"{(trip text.poll)}" + == + ;div.options + ;* %+ mapi:sr options.poll dead-opt + == + ;div.bottom-row + ;div.poll-type:"{poll-type}" + ;div.expiry:"Expired {expiry-string} ago" + == + == + ++ dead-opt + |= [i=@ud text=@t] ^- manx + =/ stats (opt-stats i) + =/ pct (scow %ud pct.stats) + =/ style "width: {pct}%;" + ;div.poll-option + ;div.poll-option-color(style style); + ;div.inner.f1 + ;div.poll-option-name.hs:"{(trip text)}" + ;div:"{pct}%" + == + == + ++ opt-stats + |= i=@ud ^- [count=@ud pct=@ud voters=(set @p)] + =/ voters + ?: ?=(%exc -.votes.poll) + =/ all-votes ~(tap by p.votes.poll) + %+ roll all-votes |= [[sip=@p vote=@ud] acc=(set @p)] + ?. .=(vote i) acc %- ~(put in acc) sip + :: + =/ all-votes (~(get by p.votes.poll) i) + ?~ all-votes ~ + ~(key by u.all-votes) + =/ voter-count ~(wyt in voters) + =/ pct ?: .=(total 0) 0 (div (mul voter-count 100) total) + [voter-count pct voters] + + -- +-- |