import { customElement, property, state } from "lit/decorators.js"; import { FeedobellElement } from "../FeedobellElement"; import { voteAPI, type IPoll, type IPollOptions } from "@feedobell/client"; import Store from "../GlobalStore"; import { html } from "lit"; import { styleMap } from "lit/directives/style-map.js"; import { FeedobellEvent } from "../events/FeedobellEvent"; import { EventName } from "../events/types"; @customElement("feedobell-poll-option") export class PollOption extends FeedobellElement { @property({ attribute: "poll", type: Object }) poll: IPoll | undefined; @property({ attribute: "poll-option", type: Object }) pollOption: IPollOptions | undefined; @property({ attribute: "total-votes", type: Number }) totalVotes: number = 0; @property({attribute: "can-vote", type: Boolean}) canVote: boolean = true; @state() private _hasVoted: boolean = false; @state() private _votePercentage: number = 0; private _onVoteEvent = new FeedobellEvent({name: EventName.OPTION_VOTED, data: {} }, {bubbles: true, composed: true} ) updated(changedProps: Map) { if (changedProps.has("pollOption") || changedProps.has("totalVotes")) { this._votePercentage = this.totalVotes > 0 ? parseFloat( (((this.pollOption?.votes || 0) / this.totalVotes) * 100).toFixed(2) ) : 0; } } private _updateVotePercentage() { this._votePercentage = this.totalVotes > 0 ? Math.round(((this.pollOption?.votes || 0) / this.totalVotes) * 100) : 0; } protected firstUpdated(): void { this._updateVotePercentage(); this._hasVoted = this.pollOption?.hasVoted || false; } private _handleOnclick = () => { if (!this.poll || !this.pollOption || !this.canVote) return null; this._hasVoted = true; this.pollOption.votes = (this.pollOption?.votes || 0) + 1; this.dispatchEvent(this._onVoteEvent); voteAPI({ projectId: Store.getProjectId(), userId: Store.getUserId(), pollId: this.poll?._id, pollOptionId: this.pollOption._id, }); }; private _barStyles = (percent: number) => { return { width: `${percent}%`, backgroundColor: "deepskyblue", }; }; private _renderPollOption() { if (!this.poll || !this.pollOption) return null; return html`
${this._hasVoted ? html`

You have voted for this option

` : ""}
${this.pollOption.label} ${this._votePercentage}%
`; } protected render() { return html` ${this._renderPollOption()} `; } } declare global { interface HTMLElementTagNameMap { "feedobell-poll-option": PollOption; } }