53 lines
2.1 KiB
TypeScript
53 lines
2.1 KiB
TypeScript
/**
|
|
* rFlows applet definition — Flow Summary card.
|
|
*/
|
|
|
|
import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types";
|
|
|
|
const flowSummary: AppletDefinition = {
|
|
id: "flow-summary",
|
|
label: "Flow Summary",
|
|
icon: "💧",
|
|
accentColor: "#0891b2",
|
|
ports: [
|
|
{ name: "transfer-in", type: "json", direction: "input" },
|
|
{ name: "balance-out", type: "number", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const inflowRate = (snapshot.inflowRate as number) || 0;
|
|
const balance = (snapshot.balance as number) || 0;
|
|
const capacity = (snapshot.capacity as number) || 1;
|
|
const fillPct = Math.min(100, Math.round((balance / capacity) * 100));
|
|
const sufficiency = fillPct >= 80 ? "Sufficient" : fillPct >= 40 ? "Moderate" : "Low";
|
|
const suffColor = fillPct >= 80 ? "#22c55e" : fillPct >= 40 ? "#f59e0b" : "#ef4444";
|
|
|
|
return `
|
|
<div>
|
|
<div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px">
|
|
<span style="font-size:13px;font-weight:600">Inflow Rate</span>
|
|
<span style="font-size:15px;font-weight:700;color:#0891b2">${inflowRate.toLocaleString()}/mo</span>
|
|
</div>
|
|
<div style="margin-bottom:6px">
|
|
<div style="font-size:10px;color:#94a3b8;margin-bottom:3px">Fill: ${fillPct}%</div>
|
|
<div style="background:#334155;border-radius:3px;height:8px;overflow:hidden">
|
|
<div style="background:linear-gradient(90deg,#0891b2,#06b6d4);width:${fillPct}%;height:100%;border-radius:3px;transition:width 0.3s"></div>
|
|
</div>
|
|
</div>
|
|
<div style="text-align:center;margin-top:8px">
|
|
<span style="font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:0.5px;color:${suffColor}">${sufficiency}</span>
|
|
</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "transfer-in" && value && typeof value === "object") {
|
|
const transfer = value as Record<string, unknown>;
|
|
const amount = Number(transfer.amount) || 0;
|
|
ctx.emitOutput("balance-out", amount);
|
|
}
|
|
},
|
|
};
|
|
|
|
export const flowsApplets: AppletDefinition[] = [flowSummary];
|