import { customElement, property, state } from "lit/decorators.js"; import { FeedobellElement } from "../FeedobellElement"; import type { IPoll, IPollOptions } from "@feedobell/client"; import { html, type PropertyValueMap } from "lit"; import calender from "../assets/calender.svg"; import vote from "../assets/vote.svg"; import { getRelativeDate } from "../utils"; import "./pollOption"; import { EventName, type IEvent } from "../events/types"; @customElement("feedobell-poll") export class Poll extends FeedobellElement { @property({ attribute: "poll" }) poll: IPoll | undefined; @state() private _totalVotes: number = 0; @state() private _canVote: boolean = true; private _handleOptionVoted(e: CustomEvent>) { const {name} = e.detail; if(name !== EventName.OPTION_VOTED){ return; } this._totalVotes += 1; this._canVote = false; } protected firstUpdated(_changedProperties: PropertyValueMap | Map): void { if(!this.poll) return; this._totalVotes = this.poll.pollOptions.reduce((acc, cur) => acc + (cur.votes || 0), 0); this._canVote = !(this.poll.pollOptions.some((opt) => opt?.hasVoted )); } private _renderPollHeader = ({ poll }: { poll: IPoll }) => { return html` Notifications ${getRelativeDate(poll?.createdAt)} `; }; private _renderPollOption() { if (!this.poll) return null; return this.poll.pollOptions.map( (opt) => html`` ); } private _renderPollBody({ poll }: { poll: IPoll }) { const options: IPollOptions[] = (poll?.pollOptions || []).filter( (o: IPollOptions) => !o.isDeleted ); return html`

${this.poll?.title}

${options.length === 0 ? html`
No options available.
` : this._renderPollOption()}
Notifications ${this._totalVotes} votes
`; } protected render() { if (!this.poll) return null; return html`
${this._renderPollHeader({ poll: this.poll })} ${this._renderPollBody({ poll: this.poll })}
`; } } declare global { interface HTMLElementTagNameMap { "feedobell-poll": Poll; } }