payments_dashboard_pipedream/slack-app-home-p_3nC3laY/build_home_view/entry.js
2026-03-31 23:46:11 +00:00

182 lines
No EOL
4.7 KiB
JavaScript

export default defineComponent({
async run({ steps }) {
const dashboard = steps.get_current_dashboard.$return_value;
const slackEvent = steps.handle_slack_event.$return_value || {};
const userId =
slackEvent.user_id ||
slackEvent.raw_body?.event?.user ||
slackEvent.raw_body?.user ||
slackEvent.raw_body?.authorizations?.[0]?.user_id;
if (!dashboard || Object.keys(dashboard).length === 0) {
throw new Error("No dashboard data found in Data Store.");
}
if (!userId) {
throw new Error("No Slack user ID found in the event payload.");
}
const payments = Array.isArray(dashboard.payments) ? dashboard.payments : [];
const formatCurrency = (value) =>
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(Number(value || 0));
const parseMDYLocal = (value) => {
if (!value) return null;
const parts = String(value).split("/");
if (parts.length !== 3) return null;
const [mm, dd, yyyy] = parts.map((p) => parseInt(p, 10));
if (!mm || !dd || !yyyy) return null;
return new Date(yyyy, mm - 1, dd);
};
const formatDateKey = (date) => {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
};
const formatDisplayDate = (dateKey) => {
const [y, m, d] = dateKey.split("-").map(Number);
const dt = new Date(y, m - 1, d);
return dt.toLocaleDateString("en-US", {
weekday: "short",
month: "short",
day: "numeric",
});
};
const today = new Date();
today.setHours(0, 0, 0, 0);
const futurePayments = payments.filter((p) => {
const dt = parseMDYLocal(p.send_payment_on);
return dt && dt >= today && (p.method === "ACH" || p.method === "Check");
});
const groupByMethodAndDay = (methodName) => {
const grouped = {};
for (const payment of futurePayments) {
if (payment.method !== methodName) continue;
const dt = parseMDYLocal(payment.send_payment_on);
if (!dt) continue;
const key = formatDateKey(dt);
if (!grouped[key]) {
grouped[key] = {
count: 0,
total: 0,
};
}
grouped[key].count += 1;
grouped[key].total += payment.amount_usd;
}
return Object.keys(grouped)
.sort()
.map((dateKey) => ({
date_key: dateKey,
display_date: formatDisplayDate(dateKey),
count: grouped[dateKey].count,
total: Number(grouped[dateKey].total.toFixed(2)),
}));
};
const achDays = groupByMethodAndDay("ACH");
const checkDays = groupByMethodAndDay("Check");
const buildDayBlocks = (title, days) => {
const total = days.reduce((sum, d) => sum + d.total, 0);
const count = days.reduce((sum, d) => sum + d.count, 0);
const blocks = [
{
type: "section",
text: {
type: "mrkdwn",
text: `*${title}*\n${count} payments • ${formatCurrency(total)}`,
},
},
{
type: "divider",
},
];
if (!days.length) {
blocks.push({
type: "section",
text: {
type: "mrkdwn",
text: "_No upcoming payments found._",
},
});
blocks.push({ type: "divider" });
return blocks;
}
for (const day of days) {
blocks.push({
type: "section",
fields: [
{
type: "mrkdwn",
text: `*${day.display_date}*`,
},
{
type: "mrkdwn",
text: `${day.count} payments • ${formatCurrency(day.total)}`,
},
],
});
}
blocks.push({ type: "divider" });
return blocks;
};
return {
user_id: userId,
view: {
type: "home",
blocks: [
{
type: "header",
text: {
type: "plain_text",
text: "Payments Dashboard",
},
},
{
type: "context",
elements: [
{
type: "mrkdwn",
text: `*Last updated:* ${dashboard.last_updated || "N/A"}`,
},
{
type: "mrkdwn",
text: `*Source:* ${dashboard.file_name || "N/A"}`,
},
],
},
{
type: "divider",
},
...buildDayBlocks("ACH", achDays),
...buildDayBlocks("Check", checkDays),
],
},
};
},
});