40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
/**
|
|
* rChoices applet definitions — Vote Tally.
|
|
*/
|
|
|
|
import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types";
|
|
|
|
const voteTally: AppletDefinition = {
|
|
id: "vote-tally",
|
|
label: "Vote Tally",
|
|
icon: "🗳️",
|
|
accentColor: "#7c3aed",
|
|
ports: [
|
|
{ name: "session-in", type: "json", direction: "input" },
|
|
{ name: "winner-out", type: "string", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const question = (snapshot.question as string) || "Vote";
|
|
const totalVotes = (snapshot.totalVotes as number) || 0;
|
|
const winner = (snapshot.winner as string) || "—";
|
|
const winPct = (snapshot.winnerPct as number) || 0;
|
|
|
|
return `
|
|
<div style="text-align:center">
|
|
<div style="font-size:12px;font-weight:600;margin-bottom:6px">${question}</div>
|
|
<div style="font-size:20px;font-weight:700;color:#e2e8f0;margin-bottom:2px">${winner}</div>
|
|
<div style="font-size:10px;color:#94a3b8">${winPct}% of ${totalVotes} votes</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "session-in" && value && typeof value === "object") {
|
|
const session = value as Record<string, unknown>;
|
|
ctx.emitOutput("winner-out", (session.winner as string) || "");
|
|
}
|
|
},
|
|
};
|
|
|
|
export const choicesApplets: AppletDefinition[] = [voteTally];
|