@apteva/integrations 0.3.61 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/dist/aws-sigv4.d.ts +32 -0
  2. package/dist/aws-sigv4.d.ts.map +1 -0
  3. package/dist/aws-sigv4.js +126 -0
  4. package/dist/aws-sigv4.js.map +1 -0
  5. package/dist/explorer/main.js +21617 -0
  6. package/dist/explorer/main.js.map +90 -0
  7. package/dist/explorer/style.css +2 -0
  8. package/dist/http-executor.d.ts.map +1 -1
  9. package/dist/http-executor.js +145 -12
  10. package/dist/http-executor.js.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp-generator.d.ts +7 -2
  15. package/dist/mcp-generator.d.ts.map +1 -1
  16. package/dist/mcp-generator.js +46 -5
  17. package/dist/mcp-generator.js.map +1 -1
  18. package/dist/oauth.js +1 -1
  19. package/dist/oauth.js.map +1 -1
  20. package/dist/types.d.ts +251 -3
  21. package/dist/types.d.ts.map +1 -1
  22. package/dist/ui/github/ActivityFeed.d.ts +24 -0
  23. package/dist/ui/github/ActivityFeed.d.ts.map +1 -0
  24. package/dist/ui/github/ActivityFeed.js +106 -0
  25. package/dist/ui/github/ActivityFeed.js.map +1 -0
  26. package/dist/ui/github/ActivityFeed.mjs +3 -0
  27. package/dist/ui/github/ActivityFeed.mjs.map +29 -0
  28. package/dist/ui/github/CommitCard.d.ts +24 -0
  29. package/dist/ui/github/CommitCard.d.ts.map +1 -0
  30. package/dist/ui/github/CommitCard.js +102 -0
  31. package/dist/ui/github/CommitCard.js.map +1 -0
  32. package/dist/ui/github/CommitCard.mjs +5 -0
  33. package/dist/ui/github/CommitCard.mjs.map +11 -0
  34. package/dist/ui/github/IssueCard.d.ts +33 -0
  35. package/dist/ui/github/IssueCard.d.ts.map +1 -0
  36. package/dist/ui/github/IssueCard.js +131 -0
  37. package/dist/ui/github/IssueCard.js.map +1 -0
  38. package/dist/ui/github/IssueCard.mjs +3 -0
  39. package/dist/ui/github/IssueCard.mjs.map +21 -0
  40. package/dist/ui/github/PullRequestCard.d.ts +36 -0
  41. package/dist/ui/github/PullRequestCard.d.ts.map +1 -0
  42. package/dist/ui/github/PullRequestCard.js +158 -0
  43. package/dist/ui/github/PullRequestCard.js.map +1 -0
  44. package/dist/ui/github/PullRequestCard.mjs +3 -0
  45. package/dist/ui/github/PullRequestCard.mjs.map +22 -0
  46. package/dist/ui/github/WorkflowRunCard.d.ts +30 -0
  47. package/dist/ui/github/WorkflowRunCard.d.ts.map +1 -0
  48. package/dist/ui/github/WorkflowRunCard.js +124 -0
  49. package/dist/ui/github/WorkflowRunCard.js.map +1 -0
  50. package/dist/ui/github/WorkflowRunCard.mjs +3 -0
  51. package/dist/ui/github/WorkflowRunCard.mjs.map +11 -0
  52. package/dist/ui/github/lib/github.d.ts +43 -0
  53. package/dist/ui/github/lib/github.d.ts.map +1 -0
  54. package/dist/ui/github/lib/github.js +151 -0
  55. package/dist/ui/github/lib/github.js.map +1 -0
  56. package/dist/ui/hubspot/ActivityFeed.d.ts +22 -0
  57. package/dist/ui/hubspot/ActivityFeed.d.ts.map +1 -0
  58. package/dist/ui/hubspot/ActivityFeed.js +52 -0
  59. package/dist/ui/hubspot/ActivityFeed.js.map +1 -0
  60. package/dist/ui/hubspot/ActivityFeed.mjs +3 -0
  61. package/dist/ui/hubspot/ActivityFeed.mjs.map +26 -0
  62. package/dist/ui/hubspot/CompanyCard.d.ts +22 -0
  63. package/dist/ui/hubspot/CompanyCard.d.ts.map +1 -0
  64. package/dist/ui/hubspot/CompanyCard.js +63 -0
  65. package/dist/ui/hubspot/CompanyCard.js.map +1 -0
  66. package/dist/ui/hubspot/CompanyCard.mjs +3 -0
  67. package/dist/ui/hubspot/CompanyCard.mjs.map +11 -0
  68. package/dist/ui/hubspot/ContactCard.d.ts +22 -0
  69. package/dist/ui/hubspot/ContactCard.d.ts.map +1 -0
  70. package/dist/ui/hubspot/ContactCard.js +62 -0
  71. package/dist/ui/hubspot/ContactCard.js.map +1 -0
  72. package/dist/ui/hubspot/ContactCard.mjs +3 -0
  73. package/dist/ui/hubspot/ContactCard.mjs.map +11 -0
  74. package/dist/ui/hubspot/ContactList.d.ts +21 -0
  75. package/dist/ui/hubspot/ContactList.d.ts.map +1 -0
  76. package/dist/ui/hubspot/ContactList.js +31 -0
  77. package/dist/ui/hubspot/ContactList.js.map +1 -0
  78. package/dist/ui/hubspot/ContactList.mjs +3 -0
  79. package/dist/ui/hubspot/ContactList.mjs.map +11 -0
  80. package/dist/ui/hubspot/DealCard.d.ts +23 -0
  81. package/dist/ui/hubspot/DealCard.d.ts.map +1 -0
  82. package/dist/ui/hubspot/DealCard.js +63 -0
  83. package/dist/ui/hubspot/DealCard.js.map +1 -0
  84. package/dist/ui/hubspot/DealCard.mjs +3 -0
  85. package/dist/ui/hubspot/DealCard.mjs.map +11 -0
  86. package/dist/ui/hubspot/DealList.d.ts +24 -0
  87. package/dist/ui/hubspot/DealList.d.ts.map +1 -0
  88. package/dist/ui/hubspot/DealList.js +35 -0
  89. package/dist/ui/hubspot/DealList.js.map +1 -0
  90. package/dist/ui/hubspot/DealList.mjs +3 -0
  91. package/dist/ui/hubspot/DealList.mjs.map +11 -0
  92. package/dist/ui/hubspot/EmailCard.d.ts +25 -0
  93. package/dist/ui/hubspot/EmailCard.d.ts.map +1 -0
  94. package/dist/ui/hubspot/EmailCard.js +62 -0
  95. package/dist/ui/hubspot/EmailCard.js.map +1 -0
  96. package/dist/ui/hubspot/EmailCard.mjs +5 -0
  97. package/dist/ui/hubspot/EmailCard.mjs.map +11 -0
  98. package/dist/ui/hubspot/InboxStrip.d.ts +23 -0
  99. package/dist/ui/hubspot/InboxStrip.d.ts.map +1 -0
  100. package/dist/ui/hubspot/InboxStrip.js +36 -0
  101. package/dist/ui/hubspot/InboxStrip.js.map +1 -0
  102. package/dist/ui/hubspot/InboxStrip.mjs +3 -0
  103. package/dist/ui/hubspot/InboxStrip.mjs.map +11 -0
  104. package/dist/ui/hubspot/PipelineStrip.d.ts +22 -0
  105. package/dist/ui/hubspot/PipelineStrip.d.ts.map +1 -0
  106. package/dist/ui/hubspot/PipelineStrip.js +54 -0
  107. package/dist/ui/hubspot/PipelineStrip.js.map +1 -0
  108. package/dist/ui/hubspot/PipelineStrip.mjs +3 -0
  109. package/dist/ui/hubspot/PipelineStrip.mjs.map +11 -0
  110. package/dist/ui/hubspot/TicketCard.d.ts +25 -0
  111. package/dist/ui/hubspot/TicketCard.d.ts.map +1 -0
  112. package/dist/ui/hubspot/TicketCard.js +53 -0
  113. package/dist/ui/hubspot/TicketCard.js.map +1 -0
  114. package/dist/ui/hubspot/TicketCard.mjs +3 -0
  115. package/dist/ui/hubspot/TicketCard.mjs.map +21 -0
  116. package/dist/ui/hubspot/TicketList.d.ts +21 -0
  117. package/dist/ui/hubspot/TicketList.d.ts.map +1 -0
  118. package/dist/ui/hubspot/TicketList.js +33 -0
  119. package/dist/ui/hubspot/TicketList.js.map +1 -0
  120. package/dist/ui/hubspot/TicketList.mjs +3 -0
  121. package/dist/ui/hubspot/TicketList.mjs.map +11 -0
  122. package/dist/ui/hubspot/lib/hubspot.d.ts +24 -0
  123. package/dist/ui/hubspot/lib/hubspot.d.ts.map +1 -0
  124. package/dist/ui/hubspot/lib/hubspot.js +176 -0
  125. package/dist/ui/hubspot/lib/hubspot.js.map +1 -0
  126. package/dist/ui/notion/DatabaseCard.d.ts +24 -0
  127. package/dist/ui/notion/DatabaseCard.d.ts.map +1 -0
  128. package/dist/ui/notion/DatabaseCard.js +86 -0
  129. package/dist/ui/notion/DatabaseCard.js.map +1 -0
  130. package/dist/ui/notion/DatabaseCard.mjs +3 -0
  131. package/dist/ui/notion/DatabaseCard.mjs.map +11 -0
  132. package/dist/ui/notion/DatabaseRowList.d.ts +36 -0
  133. package/dist/ui/notion/DatabaseRowList.d.ts.map +1 -0
  134. package/dist/ui/notion/DatabaseRowList.js +87 -0
  135. package/dist/ui/notion/DatabaseRowList.js.map +1 -0
  136. package/dist/ui/notion/DatabaseRowList.mjs +3 -0
  137. package/dist/ui/notion/DatabaseRowList.mjs.map +11 -0
  138. package/dist/ui/notion/PageCard.d.ts +27 -0
  139. package/dist/ui/notion/PageCard.d.ts.map +1 -0
  140. package/dist/ui/notion/PageCard.js +80 -0
  141. package/dist/ui/notion/PageCard.js.map +1 -0
  142. package/dist/ui/notion/PageCard.mjs +3 -0
  143. package/dist/ui/notion/PageCard.mjs.map +11 -0
  144. package/dist/ui/notion/PageList.d.ts +24 -0
  145. package/dist/ui/notion/PageList.d.ts.map +1 -0
  146. package/dist/ui/notion/PageList.js +51 -0
  147. package/dist/ui/notion/PageList.js.map +1 -0
  148. package/dist/ui/notion/PageList.mjs +3 -0
  149. package/dist/ui/notion/PageList.mjs.map +11 -0
  150. package/dist/ui/notion/lib/notion.d.ts +35 -0
  151. package/dist/ui/notion/lib/notion.d.ts.map +1 -0
  152. package/dist/ui/notion/lib/notion.js +119 -0
  153. package/dist/ui/notion/lib/notion.js.map +1 -0
  154. package/dist/xml-to-json.d.ts +20 -0
  155. package/dist/xml-to-json.d.ts.map +1 -0
  156. package/dist/xml-to-json.js +256 -0
  157. package/dist/xml-to-json.js.map +1 -0
  158. package/package.json +12 -1
  159. package/src/apps/adroll.json +254 -0
  160. package/src/apps/ahrefs.json +156 -0
  161. package/src/apps/airtable.json +4 -13
  162. package/src/apps/algolia.json +115 -0
  163. package/src/apps/alibaba-cloud.json +211 -0
  164. package/src/apps/aliexpress.json +369 -0
  165. package/src/apps/alpaca-market-data.json +699 -0
  166. package/src/apps/alpaca-trading.json +214 -989
  167. package/src/apps/amazon-ads.json +249 -0
  168. package/src/apps/amazon-associates.json +102 -0
  169. package/src/apps/amplitude.json +86 -0
  170. package/src/apps/anchor-browser.json +173 -0
  171. package/src/apps/anthropic-api.json +9 -4
  172. package/src/apps/api-sports.json +180 -0
  173. package/src/apps/apple-search-ads.json +266 -0
  174. package/src/apps/auth0.json +126 -0
  175. package/src/apps/awin.json +111 -0
  176. package/src/apps/aws-codebuild.json +139 -0
  177. package/src/apps/aws-mediaconvert.json +196 -0
  178. package/src/apps/aws-s3.json +108 -192
  179. package/src/apps/aws-ses.json +666 -303
  180. package/src/apps/aws-sns.json +128 -106
  181. package/src/apps/azure-container-apps.json +116 -0
  182. package/src/apps/backblaze-b2.json +175 -0
  183. package/src/apps/bamboohr.json +303 -0
  184. package/src/apps/basiq.json +308 -0
  185. package/src/apps/bigcommerce.json +366 -0
  186. package/src/apps/bigquery.json +121 -0
  187. package/src/apps/binance-trading.json +7 -4
  188. package/src/apps/bing-webmaster-tools.json +158 -0
  189. package/src/apps/bitbucket.json +163 -0
  190. package/src/apps/blacksmith.json +81 -0
  191. package/src/apps/bls.json +104 -0
  192. package/src/apps/bluesky.json +74 -0
  193. package/src/apps/braze.json +103 -0
  194. package/src/apps/brevo.json +4 -1
  195. package/src/apps/brightdata.json +94 -0
  196. package/src/apps/browserbase.json +237 -0
  197. package/src/apps/bscscan.json +150 -0
  198. package/src/apps/buffer.json +121 -0
  199. package/src/apps/buildjet.json +80 -0
  200. package/src/apps/builtwith.json +101 -0
  201. package/src/apps/bunny-cdn.json +104 -0
  202. package/src/apps/bunny-stream.json +205 -3
  203. package/src/apps/byrd.json +585 -0
  204. package/src/apps/calendly.json +10 -7
  205. package/src/apps/campaign-manager-360.json +264 -0
  206. package/src/apps/capturekit.json +51 -0
  207. package/src/apps/circleci.json +212 -0
  208. package/src/apps/cirrus-runners.json +75 -0
  209. package/src/apps/cj-affiliate.json +101 -0
  210. package/src/apps/cjdropshipping.json +278 -0
  211. package/src/apps/clerk.json +153 -0
  212. package/src/apps/cloudflare-containers.json +98 -0
  213. package/src/apps/cloudflare-r2.json +180 -0
  214. package/src/apps/cloudflare.json +474 -157
  215. package/src/apps/cloudinary.json +119 -97
  216. package/src/apps/coconut.json +94 -0
  217. package/src/apps/contentful.json +157 -0
  218. package/src/apps/criteo.json +222 -0
  219. package/src/apps/crunchbase.json +104 -0
  220. package/src/apps/customer-io.json +106 -0
  221. package/src/apps/databricks.json +94 -0
  222. package/src/apps/deepgram.json +3 -0
  223. package/src/apps/deepl.json +113 -0
  224. package/src/apps/deepseek.json +5 -2
  225. package/src/apps/depot.json +102 -0
  226. package/src/apps/digitalocean-spaces.json +121 -0
  227. package/src/apps/digitalocean.json +115 -0
  228. package/src/apps/discord.json +90 -1
  229. package/src/apps/docker-build-cloud.json +68 -0
  230. package/src/apps/duffel.json +193 -77
  231. package/src/apps/dux-soup.json +4 -1
  232. package/src/apps/dv360.json +287 -0
  233. package/src/apps/earthly-cloud.json +84 -0
  234. package/src/apps/eia.json +121 -0
  235. package/src/apps/elasticsearch.json +282 -0
  236. package/src/apps/elevenlabs.json +336 -192
  237. package/src/apps/etherscan.json +162 -0
  238. package/src/apps/etsy.json +484 -0
  239. package/src/apps/eventbrite-events.json +5 -2
  240. package/src/apps/exa.json +101 -0
  241. package/src/apps/facebook-ads.json +3 -3
  242. package/src/apps/facebook-api.json +1484 -37
  243. package/src/apps/finnhub.json +232 -0
  244. package/src/apps/flightapi.json +248 -0
  245. package/src/apps/fly-io.json +134 -0
  246. package/src/apps/fred.json +156 -0
  247. package/src/apps/gdelt.json +96 -0
  248. package/src/apps/gelato.json +123 -0
  249. package/src/apps/gemini.json +143 -49
  250. package/src/apps/getscreenshot.json +52 -0
  251. package/src/apps/github.json +355 -39
  252. package/src/apps/gmail.json +151 -2
  253. package/src/apps/gnews.json +71 -0
  254. package/src/apps/google-analytics.json +311 -0
  255. package/src/apps/google-cloud-storage.json +484 -0
  256. package/src/apps/google-docs.json +2 -2
  257. package/src/apps/google-drive.json +2 -2
  258. package/src/apps/google-places.json +127 -0
  259. package/src/apps/google-search-console.json +126 -0
  260. package/src/apps/google-sheets.json +2 -2
  261. package/src/apps/grafana-cloud.json +98 -0
  262. package/src/apps/groq.json +119 -0
  263. package/src/apps/hetzner-object-storage.json +177 -0
  264. package/src/apps/hetzner.json +255 -367
  265. package/src/apps/heygen.json +828 -141
  266. package/src/apps/hive-fulfillment.json +559 -0
  267. package/src/apps/hotjar.json +91 -0
  268. package/src/apps/huawei-cloud.json +189 -0
  269. package/src/apps/huboo.json +286 -0
  270. package/src/apps/hubspot.json +253 -637
  271. package/src/apps/huggingface.json +5 -2
  272. package/src/apps/hunter.json +5 -2
  273. package/src/apps/hyperbrowser.json +205 -0
  274. package/src/apps/idrive-e2.json +128 -0
  275. package/src/apps/impact.json +106 -0
  276. package/src/apps/instagram-api.json +185 -11
  277. package/src/apps/instantly.json +169 -0
  278. package/src/apps/ionos.json +250 -0
  279. package/src/apps/{learning-platform.json → kalio.json} +162 -3
  280. package/src/apps/kalshi.json +144 -0
  281. package/src/apps/keywords-everywhere.json +86 -0
  282. package/src/apps/kickbox.json +71 -0
  283. package/src/apps/launchdarkly.json +111 -0
  284. package/src/apps/leadbyte.json +600 -0
  285. package/src/apps/leadfeeder.json +89 -0
  286. package/src/apps/lemlist.json +109 -0
  287. package/src/apps/linkedin-ads.json +279 -0
  288. package/src/apps/linkedin.json +96 -2
  289. package/src/apps/linode-object-storage.json +183 -0
  290. package/src/apps/linode.json +160 -0
  291. package/src/apps/lnk-bio.json +5 -2
  292. package/src/apps/loom.json +5 -2
  293. package/src/apps/lusha.json +104 -0
  294. package/src/apps/magalu-cloud.json +187 -0
  295. package/src/apps/majestic.json +117 -0
  296. package/src/apps/manifold-markets.json +144 -0
  297. package/src/apps/mapbox.json +118 -0
  298. package/src/apps/microsoft-ads.json +246 -0
  299. package/src/apps/microsoft-onedrive.json +380 -0
  300. package/src/apps/microsoft-teams.json +315 -96
  301. package/src/apps/millionverifier.json +85 -0
  302. package/src/apps/mindee.json +246 -0
  303. package/src/apps/miro.json +138 -0
  304. package/src/apps/mistral.json +129 -0
  305. package/src/apps/mixpanel.json +95 -0
  306. package/src/apps/moz.json +127 -0
  307. package/src/apps/mux.json +201 -0
  308. package/src/apps/namecheap.json +321 -123
  309. package/src/apps/namespace-cloud.json +84 -0
  310. package/src/apps/naver-cloud.json +184 -0
  311. package/src/apps/neon.json +122 -0
  312. package/src/apps/netlify.json +124 -0
  313. package/src/apps/neverbounce.json +92 -0
  314. package/src/apps/newrelic.json +80 -0
  315. package/src/apps/newsapi.json +86 -0
  316. package/src/apps/ngrok.json +29 -0
  317. package/src/apps/nixbuild.json +116 -0
  318. package/src/apps/northflank.json +161 -0
  319. package/src/apps/notion.json +3 -0
  320. package/src/apps/okta.json +131 -0
  321. package/src/apps/omnikit-analytics.json +73 -1
  322. package/src/apps/omnikit-api-gateway.json +74 -2
  323. package/src/apps/omnikit-billing.json +73 -1
  324. package/src/apps/omnikit-cms.json +73 -1
  325. package/src/apps/omnikit-code-ops.json +76 -4
  326. package/src/apps/omnikit-functions.json +74 -2
  327. package/src/apps/omnikit-intelligence.json +176 -33
  328. package/src/apps/omnikit-management.json +73 -1
  329. package/src/apps/omnikit-media.json +73 -1
  330. package/src/apps/omnikit-messaging.json +72 -0
  331. package/src/apps/omnikit-redirects.json +73 -1
  332. package/src/apps/omnikit-sites.json +325 -66
  333. package/src/apps/omnikit-storage.json +105 -8
  334. package/src/apps/omnikit-webhooks.json +73 -1
  335. package/src/apps/omnikit-workflows.json +73 -1
  336. package/src/apps/onesignal.json +108 -0
  337. package/src/apps/openai-api.json +176 -30
  338. package/src/apps/openai-codex.json +187 -0
  339. package/src/apps/opencode-go.json +113 -0
  340. package/src/apps/optinmonster.json +7 -4
  341. package/src/apps/outlook-calendar.json +350 -0
  342. package/src/apps/outlook-mail.json +337 -0
  343. package/src/apps/outscraper.json +118 -0
  344. package/src/apps/ovhcloud.json +209 -0
  345. package/src/apps/paddle.json +170 -0
  346. package/src/apps/pagerduty.json +151 -0
  347. package/src/apps/partnerstack.json +118 -0
  348. package/src/apps/perplexity.json +37 -0
  349. package/src/apps/phantombuster.json +85 -0
  350. package/src/apps/pinecone.json +129 -0
  351. package/src/apps/pinterest-ads.json +261 -0
  352. package/src/apps/pinterest.json +217 -0
  353. package/src/apps/planetscale.json +139 -0
  354. package/src/apps/polygonscan.json +157 -0
  355. package/src/apps/polymarket-clob.json +184 -0
  356. package/src/apps/polymarket-data.json +153 -0
  357. package/src/apps/porkbun.json +609 -145
  358. package/src/apps/posthog.json +107 -0
  359. package/src/apps/pushover.json +28 -0
  360. package/src/apps/quora-ads.json +251 -0
  361. package/src/apps/railway.json +57 -0
  362. package/src/apps/reddit-ads.json +238 -0
  363. package/src/apps/reddit.json +274 -0
  364. package/src/apps/render.json +124 -0
  365. package/src/apps/replicate.json +5 -2
  366. package/src/apps/reply-io.json +111 -0
  367. package/src/apps/resend.json +110 -0
  368. package/src/apps/ringover.json +1144 -0
  369. package/src/apps/rocketreach.json +158 -0
  370. package/src/apps/rollbar.json +88 -0
  371. package/src/apps/runs-on.json +70 -0
  372. package/src/apps/sanity.json +89 -0
  373. package/src/apps/scaleway-object-storage.json +175 -0
  374. package/src/apps/scrapingbee.json +75 -0
  375. package/src/apps/screenshotlayer.json +49 -0
  376. package/src/apps/screenshotmachine.json +49 -0
  377. package/src/apps/se-ranking.json +239 -0
  378. package/src/apps/seamless-ai.json +91 -0
  379. package/src/apps/sec-edgar.json +107 -0
  380. package/src/apps/segment.json +104 -0
  381. package/src/apps/semrush.json +153 -0
  382. package/src/apps/sentry.json +109 -0
  383. package/src/apps/serpapi.json +95 -0
  384. package/src/apps/serper.json +139 -0
  385. package/src/apps/shareasale.json +130 -0
  386. package/src/apps/skimlinks.json +48 -0
  387. package/src/apps/slack.json +101 -0
  388. package/src/apps/smartlead.json +146 -0
  389. package/src/apps/snapchat-ads.json +238 -0
  390. package/src/apps/snaprender.json +64 -0
  391. package/src/apps/snowflake.json +70 -0
  392. package/src/apps/snyk.json +108 -0
  393. package/src/apps/socialcast.json +74 -8
  394. package/src/apps/sovrn.json +125 -0
  395. package/src/apps/spotify-ads.json +231 -0
  396. package/src/apps/steel.json +239 -0
  397. package/src/apps/stocktwits.json +120 -0
  398. package/src/apps/stripe.json +153 -0
  399. package/src/apps/target-circle.json +348 -0
  400. package/src/apps/tavily.json +104 -0
  401. package/src/apps/tavus.json +403 -0
  402. package/src/apps/telegram.json +5 -2
  403. package/src/apps/teller.json +187 -0
  404. package/src/apps/tencent-cloud.json +214 -0
  405. package/src/apps/tennis-abstract.json +108 -0
  406. package/src/apps/the-odds-api.json +132 -0
  407. package/src/apps/the-sports-db.json +163 -0
  408. package/src/apps/tiktok-ads.json +295 -0
  409. package/src/apps/tiktok-api.json +181 -7
  410. package/src/apps/together.json +5 -2
  411. package/src/apps/trade-desk.json +237 -0
  412. package/src/apps/trading212.json +26 -29
  413. package/src/apps/transloadit.json +138 -0
  414. package/src/apps/truelayer.json +318 -0
  415. package/src/apps/twilio.json +313 -42
  416. package/src/apps/twitter-api.json +216 -33
  417. package/src/apps/ubicloud.json +82 -0
  418. package/src/apps/uplead.json +105 -0
  419. package/src/apps/upstash.json +90 -0
  420. package/src/apps/valueserp.json +63 -0
  421. package/src/apps/venice-ai.json +685 -0
  422. package/src/apps/vercel.json +137 -0
  423. package/src/apps/wappalyzer.json +65 -0
  424. package/src/apps/wasabi.json +175 -0
  425. package/src/apps/whale-alert.json +74 -0
  426. package/src/apps/whatsapp-business.json +131 -0
  427. package/src/apps/wikipedia.json +112 -0
  428. package/src/apps/workos.json +123 -0
  429. package/src/apps/yahoo-dsp.json +265 -0
  430. package/src/apps/yahoo-finance.json +60 -0
  431. package/src/apps/youtube-api.json +520 -142
  432. package/src/apps/zenrows.json +47 -0
  433. package/src/apps/zenserp.json +99 -0
  434. package/src/apps/zerobounce.json +80 -0
@@ -0,0 +1,25 @@
1
+ interface Props {
2
+ /** Engagement id. */
3
+ email_id: string;
4
+ direction?: "INCOMING_EMAIL" | "EMAIL" | "FORWARDED_EMAIL";
5
+ from_name?: string;
6
+ from_email?: string;
7
+ to_email?: string;
8
+ subject?: string;
9
+ /** Plain-text body — first 240 chars rendered as snippet. */
10
+ body?: string;
11
+ /** ISO timestamp the email was received / sent. */
12
+ sent_at?: string;
13
+ /** Length of the thread this message belongs to (1 if standalone). */
14
+ thread_length?: number;
15
+ /** Associated company / contact name for the chip strip. */
16
+ company_name?: string;
17
+ company_domain?: string;
18
+ contact_name?: string;
19
+ portal_id?: string;
20
+ preview?: boolean;
21
+ projectId?: string;
22
+ }
23
+ export default function EmailCard(props: Props): import("react").JSX.Element;
24
+ export {};
25
+ //# sourceMappingURL=EmailCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailCard.d.ts","sourceRoot":"","sources":["../../../src/ui/hubspot/EmailCard.tsx"],"names":[],"mappings":"AAQA,UAAU,KAAK;IACd,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAC,gBAAgB,GAAE,OAAO,GAAE,iBAAiB,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA4BD,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,KAAK,EAAE,KAAK,+BAsD7C"}
@@ -0,0 +1,62 @@
1
+ // EmailCard — single inbound/outbound email engagement. The card the
2
+ // email-monitor demo's chat surface attaches whenever the agent
3
+ // processes an inbound message. Sender identity, subject, snippet,
4
+ // thread length, associated record chips.
5
+ import { Card, CardHeader, Avatar, StatusPill } from "@apteva/ui-kit";
6
+ import { recordUrl, faviconFor, timeAgo, minusHoursISO, hubspotVendor } from "./lib/hubspot";
7
+ const previewSample = {
8
+ email_id: "30100",
9
+ direction: "INCOMING_EMAIL",
10
+ from_name: "Sarah Chen",
11
+ from_email: "sarah.chen@acme-logistics.com",
12
+ to_email: "marc-olivier@apteva.local",
13
+ subject: "This is the third time I'm asking — board review tomorrow",
14
+ body: "Marco,\n\nWe're 36 hours away from our board review. The API performance issue is now in the deck. I have not heard a thing back since you said the team was on it five days ago. If we don't have a concrete fix or a written plan by EOD, I'm pulling the renewal off the agenda…",
15
+ sent_at: minusHoursISO(2),
16
+ thread_length: 3,
17
+ company_name: "Acme Logistics",
18
+ company_domain: "acme-logistics.com",
19
+ contact_name: "Sarah Chen",
20
+ portal_id: "0",
21
+ };
22
+ function snippet(body, n = 240) {
23
+ if (!body)
24
+ return "";
25
+ const flat = body.replace(/\s+/g, "").trim();
26
+ return flat.length > n ? flat.slice(0, n) + "…" : flat;
27
+ }
28
+ export default function EmailCard(props) {
29
+ const p = props.preview ? { ...previewSample, ...props } : props;
30
+ const url = recordUrl("engagement", p.email_id, p.portal_id);
31
+ const incoming = p.direction === "INCOMING_EMAIL" || p.direction === "FORWARDED_EMAIL";
32
+ const dirLabel = incoming ? "Incoming" : "Sent";
33
+ return (<Card>
34
+ <CardHeader vendor={hubspotVendor} title={p.subject || "(no subject)"} subtitle={p.from_email && p.to_email ? `${p.from_email} → ${p.to_email}` : (p.from_email || p.to_email)} status={{ label: dirLabel, variant: incoming ? "active" : "muted" }} action={{ label: "View in HubSpot", href: url }}/>
35
+ <div className="px-3 py-3 flex flex-col gap-3">
36
+ <div className="flex items-center gap-2">
37
+ <Avatar src="" name={p.from_name || p.from_email || "? "} size={28}/>
38
+ <div className="min-w-0 flex-1">
39
+ <div className="text-text text-xs font-medium truncate">{p.from_name || p.from_email}</div>
40
+ {p.from_name && p.from_email && (<div className="text-text-dim text-[11px] truncate">{p.from_email}</div>)}
41
+ </div>
42
+ <span className="text-[11px] text-text-dim tabular-nums">{timeAgo(p.sent_at)}</span>
43
+ </div>
44
+
45
+ {p.body && (<p className="text-xs text-text-muted line-clamp-4 border-l-2 border-border pl-2 whitespace-pre-line">
46
+ {snippet(p.body)}
47
+ </p>)}
48
+
49
+ <div className="flex items-center gap-2 flex-wrap">
50
+ {p.thread_length && p.thread_length > 1 && (<StatusPill variant="info">Thread of {p.thread_length}</StatusPill>)}
51
+ {p.company_name && (<span className="inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded">
52
+ {p.company_domain && (<img src={faviconFor(p.company_domain, 16)} alt="" width={10} height={10} className="rounded-sm"/>)}
53
+ {p.company_name}
54
+ </span>)}
55
+ {p.contact_name && (<span className="inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded">
56
+ {p.contact_name}
57
+ </span>)}
58
+ </div>
59
+ </div>
60
+ </Card>);
61
+ }
62
+ //# sourceMappingURL=EmailCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailCard.js","sourceRoot":"","sources":["../../../src/ui/hubspot/EmailCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import{Card as f,CardHeader as P,Avatar as g,StatusPill as R}from"@apteva/ui-kit";import{jsx as $,jsxs as K}from"react/jsx-runtime";function z(J){if(!J)return"—";let q=new Date(J);if(Number.isNaN(q.getTime()))return J;let M=Math.round((Date.now()-q.getTime())/1000);if(M<60)return"just now";let W=Math.round(M/60);if(W<60)return`${W}m ago`;let Z=Math.round(W/60);if(Z<24)return`${Z}h ago`;let N=Math.round(Z/24);if(N<7)return`${N}d ago`;let V=Math.round(N/7);if(V<5)return`${V}w ago`;return q.toLocaleDateString("en-US",{month:"short",day:"numeric"})}function D(J){let q=new Date;return q.setHours(q.getHours()-J),q.toISOString()}var B="0";function G(J,q,M){return`https://app.hubspot.com/contacts/${M||B}/${J}/${q}`}function U(J,q=32){if(!J)return;return`https://www.google.com/s2/favicons?domain=${encodeURIComponent(J)}&sz=${q}`}var F=K("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:[$("circle",{cx:"18",cy:"6",r:"2.2"}),$("circle",{cx:"18",cy:"18",r:"2.2"}),$("circle",{cx:"6",cy:"12",r:"2.2"}),$("circle",{cx:"14",cy:"12",r:"3",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),$("path",{d:"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8",stroke:"currentColor",strokeWidth:"1.2",fill:"none"})]}),H="#FF7A59",Y={name:"HubSpot",logo:F,color:H};import{jsx as Q,jsxs as X}from"react/jsx-runtime";var E={email_id:"30100",direction:"INCOMING_EMAIL",from_name:"Sarah Chen",from_email:"sarah.chen@acme-logistics.com",to_email:"marc-olivier@apteva.local",subject:"This is the third time I'm asking — board review tomorrow",body:`Marco,
2
+
3
+ We're 36 hours away from our board review. The API performance issue is now in the deck. I have not heard a thing back since you said the team was on it five days ago. If we don't have a concrete fix or a written plan by EOD, I'm pulling the renewal off the agenda…`,sent_at:D(2),thread_length:3,company_name:"Acme Logistics",company_domain:"acme-logistics.com",contact_name:"Sarah Chen",portal_id:"0"};function O(J,q=240){if(!J)return"";let M=J.replace(/\s+/g,"").trim();return M.length>q?M.slice(0,q)+"…":M}function _(J){let q=J.preview?{...E,...J}:J,M=G("engagement",q.email_id,q.portal_id),W=q.direction==="INCOMING_EMAIL"||q.direction==="FORWARDED_EMAIL",Z=W?"Incoming":"Sent";return X(f,{children:[Q(P,{vendor:Y,title:q.subject||"(no subject)",subtitle:q.from_email&&q.to_email?`${q.from_email} → ${q.to_email}`:q.from_email||q.to_email,status:{label:Z,variant:W?"active":"muted"},action:{label:"View in HubSpot",href:M}}),X("div",{className:"px-3 py-3 flex flex-col gap-3",children:[X("div",{className:"flex items-center gap-2",children:[Q(g,{src:"",name:q.from_name||q.from_email||"? ",size:28}),X("div",{className:"min-w-0 flex-1",children:[Q("div",{className:"text-text text-xs font-medium truncate",children:q.from_name||q.from_email}),q.from_name&&q.from_email&&Q("div",{className:"text-text-dim text-[11px] truncate",children:q.from_email})]}),Q("span",{className:"text-[11px] text-text-dim tabular-nums",children:z(q.sent_at)})]}),q.body&&Q("p",{className:"text-xs text-text-muted line-clamp-4 border-l-2 border-border pl-2 whitespace-pre-line",children:O(q.body)}),X("div",{className:"flex items-center gap-2 flex-wrap",children:[q.thread_length&&q.thread_length>1&&X(R,{variant:"info",children:["Thread of ",q.thread_length]}),q.company_name&&X("span",{className:"inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded",children:[q.company_domain&&Q("img",{src:U(q.company_domain,16),alt:"",width:10,height:10,className:"rounded-sm"}),q.company_name]}),q.contact_name&&Q("span",{className:"inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded",children:q.contact_name})]})]})]})}export{_ as default};
4
+
5
+ //# debugId=2E79F064C0DA74E564756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/hubspot/EmailCard.tsx", "../../../src/ui/hubspot/lib/hubspot.tsx"],
4
+ "sourcesContent": [
5
+ "// EmailCard — single inbound/outbound email engagement. The card the\n// email-monitor demo's chat surface attaches whenever the agent\n// processes an inbound message. Sender identity, subject, snippet,\n// thread length, associated record chips.\n\nimport { Card, CardHeader, Avatar, StatusPill } from \"@apteva/ui-kit\";\nimport { recordUrl, faviconFor, timeAgo, minusHoursISO, hubspotVendor } from \"./lib/hubspot\";\n\ninterface Props {\n /** Engagement id. */\n email_id: string;\n direction?:\"INCOMING_EMAIL\" |\"EMAIL\" |\"FORWARDED_EMAIL\";\n from_name?: string;\n from_email?: string;\n to_email?: string;\n subject?: string;\n /** Plain-text body — first 240 chars rendered as snippet. */\n body?: string;\n /** ISO timestamp the email was received / sent. */\n sent_at?: string;\n /** Length of the thread this message belongs to (1 if standalone). */\n thread_length?: number;\n /** Associated company / contact name for the chip strip. */\n company_name?: string;\n company_domain?: string;\n contact_name?: string;\n portal_id?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewSample: Required<Pick<Props,\n |\"email_id\" |\"direction\" |\"from_name\" |\"from_email\" |\"to_email\"\n |\"subject\" |\"body\" |\"sent_at\" |\"thread_length\"\n |\"company_name\" |\"company_domain\" |\"contact_name\" |\"portal_id\"\n>> = {\n email_id: \"30100\",\n direction: \"INCOMING_EMAIL\",\n from_name: \"Sarah Chen\",\n from_email: \"sarah.chen@acme-logistics.com\",\n to_email: \"marc-olivier@apteva.local\",\n subject: \"This is the third time I'm asking — board review tomorrow\",\n body: \"Marco,\\n\\nWe're 36 hours away from our board review. The API performance issue is now in the deck. I have not heard a thing back since you said the team was on it five days ago. If we don't have a concrete fix or a written plan by EOD, I'm pulling the renewal off the agenda…\",\n sent_at: minusHoursISO(2),\n thread_length: 3,\n company_name: \"Acme Logistics\",\n company_domain: \"acme-logistics.com\",\n contact_name: \"Sarah Chen\",\n portal_id: \"0\",\n};\n\nfunction snippet(body: string | undefined, n = 240): string {\n if (!body) return \"\";\n const flat = body.replace(/\\s+/g,\"\").trim();\n return flat.length > n ? flat.slice(0, n) +\"…\" : flat;\n}\n\nexport default function EmailCard(props: Props) {\n const p: Props = props.preview ? { ...previewSample, ...props } : props;\n const url = recordUrl(\"engagement\", p.email_id, p.portal_id);\n const incoming = p.direction === \"INCOMING_EMAIL\" || p.direction === \"FORWARDED_EMAIL\";\n const dirLabel = incoming ? \"Incoming\" :\"Sent\";\n\n return (\n <Card>\n <CardHeader\n vendor={hubspotVendor}\n title={p.subject || \"(no subject)\"}\n subtitle={p.from_email && p.to_email ? `${p.from_email} → ${p.to_email}` : (p.from_email || p.to_email)}\n status={{ label: dirLabel, variant: incoming ? \"active\" :\"muted\" }}\n action={{ label: \"View in HubSpot\", href: url }}\n />\n <div className=\"px-3 py-3 flex flex-col gap-3\">\n <div className=\"flex items-center gap-2\">\n <Avatar src=\"\" name={p.from_name || p.from_email || \"? \"} size={28} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-text text-xs font-medium truncate\">{p.from_name || p.from_email}</div>\n {p.from_name && p.from_email && (\n <div className=\"text-text-dim text-[11px] truncate\">{p.from_email}</div>\n )}\n </div>\n <span className=\"text-[11px] text-text-dim tabular-nums\">{timeAgo(p.sent_at)}</span>\n </div>\n\n {p.body && (\n <p className=\"text-xs text-text-muted line-clamp-4 border-l-2 border-border pl-2 whitespace-pre-line\">\n {snippet(p.body)}\n </p>\n )}\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n {p.thread_length && p.thread_length > 1 && (\n <StatusPill variant=\"info\">Thread of {p.thread_length}</StatusPill>\n )}\n {p.company_name && (\n <span className=\"inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded\">\n {p.company_domain && (\n <img src={faviconFor(p.company_domain, 16)} alt=\"\" width={10} height={10} className=\"rounded-sm\" />\n )}\n {p.company_name}\n </span>\n )}\n {p.contact_name && (\n <span className=\"inline-flex items-center gap-1 text-[11px] text-text-muted bg-bg-hover px-1.5 py-0.5 rounded\">\n {p.contact_name}\n </span>\n )}\n </div>\n </div>\n </Card>\n );\n}\n",
6
+ "// Shared helpers for every HubSpot UI component.\n//\n// * pill metadata for deal stages, ticket priorities, lifecycle\n// stages — one source of truth for label + color across cards\n// * formatters: USD, relative date, relative time-since\n// * URL builders for HubSpot canonical record links\n// * favicon helper (Google s2)\n// * pillToDot — bridges StatusPill variant → StatusDot variant for\n// CardHeader's status slot\n// * HubSpot brand mark SVG used in every card header\n\nimport type { StatusDotVariant, StatusPillVariant } from \"@apteva/ui-kit\";\n\n// ─── pill metadata ────────────────────────────────────────────────\n\nexport type PillMeta = { label: string; variant: StatusPillVariant };\n\nconst DEAL_STAGE: Record<string, PillMeta> = {\n appointmentscheduled: { label: \"Appointment scheduled\", variant: \"info\" },\n qualifiedtobuy: { label: \"Qualified to buy\", variant: \"info\" },\n presentationscheduled: { label: \"Presentation scheduled\", variant: \"info\" },\n decisionmakerboughtin: { label: \"Decision-maker bought in \", variant: \"info\" },\n contractsent: { label: \"Contract sent\", variant: \"warn\" },\n closedwon: { label: \"Closed (won)\", variant: \"success\" },\n closedlost: { label: \"Closed (lost)\", variant: \"error\" },\n};\n\nexport function dealStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = DEAL_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst TICKET_PRIORITY: Record<string, PillMeta> = {\n LOW: { label: \"Low\", variant: \"neutral\" },\n MEDIUM: { label: \"Medium\", variant: \"info\" },\n HIGH: { label: \"High\", variant: \"warn\" },\n URGENT: { label: \"Urgent\", variant: \"error\" },\n};\n\nexport function ticketPriorityMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return TICKET_PRIORITY[id] ?? { label: id, variant: \"neutral\" };\n}\n\nconst TICKET_STAGE: Record<string, PillMeta> = {\n \"1\": { label: \"New\", variant: \"info\" },\n \"2\": { label: \"Waiting on us\", variant: \"warn\" },\n \"3\": { label: \"Waiting on them\", variant: \"neutral\" },\n \"4\": { label: \"Closed\", variant: \"success\" },\n};\n\nexport function ticketStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = TICKET_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst LIFECYCLE: Record<string, PillMeta> = {\n subscriber: { label: \"Subscriber\", variant: \"neutral\" },\n lead: { label: \"Lead\", variant: \"neutral\" },\n marketingqualifiedlead: { label: \"MQL\", variant: \"info\" },\n salesqualifiedlead: { label: \"SQL\", variant: \"info\" },\n opportunity: { label: \"Opportunity\", variant: \"info\" },\n customer: { label: \"Customer\", variant: \"success\" },\n evangelist: { label: \"Evangelist\", variant: \"success\" },\n other: { label: \"Other\", variant: \"neutral\" },\n};\n\nexport function lifecycleMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return LIFECYCLE[id] ?? { label: id, variant: \"neutral\" };\n}\n\n// ─── formatters ───────────────────────────────────────────────────\n\nexport function formatUSD(raw: string | number | undefined | null): string {\n if (raw === undefined || raw === null || raw === \"\") return \"—\";\n const n = typeof raw === \"number\" ? raw : Number(raw);\n if (!Number.isFinite(n)) return String(raw);\n return n.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: n >= 1000 ? 0 : 2,\n });\n}\n\nexport function formatRelativeDate(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const now = new Date();\n const days = Math.round((d.getTime() - now.getTime()) / 86_400_000);\n const dateStr = d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n if (days === 0) return `${dateStr} · today`;\n if (days > 0) return `${dateStr} · in ${days} day${days === 1 ? \"\" : \"s\"}`;\n const overdue = -days;\n return `${dateStr} · ${overdue} day${overdue === 1 ? \"\" : \"s\"} overdue`;\n}\n\nexport function timeAgo(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const sec = Math.round((Date.now() - d.getTime()) / 1000);\n if (sec < 60) return \"just now\";\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n if (day < 7) return `${day}d ago`;\n const wk = Math.round(day / 7);\n if (wk < 5) return `${wk}w ago`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nexport function addDaysISO(n: number): string {\n const d = new Date();\n d.setDate(d.getDate() + n);\n return d.toISOString().slice(0, 10);\n}\n\nexport function minusHoursISO(n: number): string {\n const d = new Date();\n d.setHours(d.getHours() - n);\n return d.toISOString();\n}\n\n// ─── URL builders ─────────────────────────────────────────────────\n\nconst PORTAL_FALLBACK = \"0\";\n\nexport function recordUrl(\n type: \"deal\" | \"company\" | \"contact\" | \"ticket\" | \"engagement\",\n id: string,\n portalId?: string,\n): string {\n const portal = portalId || PORTAL_FALLBACK;\n return `https://app.hubspot.com/contacts/${portal}/${type}/${id}`;\n}\n\nexport function pipelineUrl(portalId?: string, pipeline?: string): string {\n const portal = portalId || PORTAL_FALLBACK;\n const path = pipeline ? `?pipeline=${encodeURIComponent(pipeline)}` : \"\";\n return `https://app.hubspot.com/pipelines/${portal}/deals${path}`;\n}\n\n// ─── favicon helper ───────────────────────────────────────────────\n\nexport function faviconFor(domain: string | undefined, size = 32): string | undefined {\n if (!domain) return undefined;\n return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size}`;\n}\n\n// ─── pill → dot bridge ────────────────────────────────────────────\n//\n// CardHeader's status slot wants a StatusDot variant. StatusPill's\n// variant set is wider; this is the canonical mapping.\n\nexport function pillToDot(v: StatusPillVariant): StatusDotVariant {\n switch (v) {\n case \"success\": return \"live\";\n case \"info\": return \"active\";\n case \"warn\": return \"warn\";\n case \"error\": return \"error\";\n default: return \"muted\";\n }\n}\n\n// ─── HubSpot brand mark ───────────────────────────────────────────\n//\n// Simplified mark — three satellites linked to a central node. Reads\n// at 14×14 without shipping the full brand artwork. Uses currentColor\n// so the consumer can recolor it (CardHeader's vendor strip pipes the\n// HubSpot brand orange in via inline `style.color`).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\nexport const hubspotLogo: ReactNode = (\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <circle cx=\"18\" cy=\"6\" r=\"2.2\" />\n <circle cx=\"18\" cy=\"18\" r=\"2.2\" />\n <circle cx=\"6\" cy=\"12\" r=\"2.2\" />\n <circle cx=\"14\" cy=\"12\" r=\"3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8\" stroke=\"currentColor\" strokeWidth=\"1.2\" fill=\"none\" />\n </svg>\n);\n\n// HubSpot's official brand orange. Passed through CardHeader's\n// `vendor.color` so the brand strip on every HubSpot-emitted card\n// reads as obviously HubSpot at a glance, in both light and dark.\nexport const HUBSPOT_BRAND_COLOR = \"#FF7A59\";\n\nexport const hubspotVendor: CardVendor = {\n name: \"HubSpot\",\n logo: hubspotLogo,\n color: HUBSPOT_BRAND_COLOR,\n};\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "2E79F064C0DA74E564756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,23 @@
1
+ interface InboxItem {
2
+ email_id: string;
3
+ from_name?: string;
4
+ from_email?: string;
5
+ subject?: string;
6
+ /** First line of the body — caller pre-trims. */
7
+ snippet?: string;
8
+ sent_at?: string;
9
+ unread?: boolean;
10
+ thread_length?: number;
11
+ }
12
+ interface Props {
13
+ items?: InboxItem[];
14
+ title?: string;
15
+ subtitle?: string;
16
+ max_rows?: number;
17
+ portal_id?: string;
18
+ preview?: boolean;
19
+ projectId?: string;
20
+ }
21
+ export default function InboxStrip(props: Props): import("react").JSX.Element;
22
+ export {};
23
+ //# sourceMappingURL=InboxStrip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InboxStrip.d.ts","sourceRoot":"","sources":["../../../src/ui/hubspot/InboxStrip.tsx"],"names":[],"mappings":"AAOA,UAAU,SAAS;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,KAAK;IACd,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,KAAK,EAAE,KAAK,+BAsD9C"}
@@ -0,0 +1,36 @@
1
+ // InboxStrip — compact unread-feed of recent emails. Same shape as
2
+ // EmailCard items[] but flattened into one-line rows with a snippet.
3
+ // Used in the dashboard tile and the demo runner's kiosk header.
4
+ import { Card, CardHeader, Avatar, Row, StatusPill } from "@apteva/ui-kit";
5
+ import { recordUrl, timeAgo, minusHoursISO, hubspotVendor } from "./lib/hubspot";
6
+ const previewItems = [
7
+ { email_id: "1", from_name: "Sarah Chen", from_email: "sarah.chen@acme-logistics.com", subject: "Third time I'm asking — board review tomorrow", snippet: "We're 36 hours away from our board review.", sent_at: minusHoursISO(2), unread: true, thread_length: 3 },
8
+ { email_id: "2", from_name: "David Park", from_email: "david.park@globex-innovations.com", subject: "Globex pilot — push to next quarter", snippet: "We've had to deprioritize new initiatives…", sent_at: minusHoursISO(28), unread: true },
9
+ { email_id: "3", from_name: "Lisa Rodriguez", from_email: "lisa.rodriguez@initech-corp.com", subject: "Re: Pricing — final ask before committee", snippet: "Three different per-seat numbers from your team.", sent_at: minusHoursISO(6), unread: true, thread_length: 5 },
10
+ { email_id: "4", from_name: "HubSpot", from_email: "no-reply@hubspot.com", subject: "Weekly digest: 3 new opportunities", snippet: "Your pipeline summary for this week.", sent_at: minusHoursISO(80) },
11
+ ];
12
+ export default function InboxStrip(props) {
13
+ const items = props.preview ? (props.items ?? previewItems) : (props.items ?? []);
14
+ const max = props.max_rows ?? 6;
15
+ const visible = items.slice(0, max);
16
+ const overflow = items.length - visible.length;
17
+ const unreadCount = items.filter((i) => i.unread).length;
18
+ return (<Card fullWidth>
19
+ <CardHeader vendor={hubspotVendor} title={props.title || "Inbox"} subtitle={props.subtitle || (unreadCount > 0 ? `${unreadCount} unread` : `${items.length} message${items.length === 1 ? "" : "s"}`)}/>
20
+ {visible.length === 0 && (<div className="px-3 py-3 text-xs text-text-dim">Inbox is quiet.</div>)}
21
+ {visible.map((it, i) => (<Row key={it.email_id} flush={i === 0} href={recordUrl("engagement", it.email_id, props.portal_id)} leading={<span className="relative">
22
+ <Avatar src="" name={it.from_name || it.from_email || "? "} size={20}/>
23
+ {it.unread && (<span className="absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full bg-accent ring-1 ring-white dark:ring-zinc-900" aria-label="unread"/>)}
24
+ </span>} title={<span className={it.unread ? "font-semibold" : undefined}>
25
+ {it.from_name || it.from_email}
26
+ {it.subject && <span className="text-text-dim font-normal"> · {it.subject}</span>}
27
+ </span>} subtitle={it.snippet} trailing={<span className="inline-flex items-center gap-1.5">
28
+ {it.thread_length && it.thread_length > 1 && (<StatusPill variant="info">{it.thread_length}</StatusPill>)}
29
+ <span className="text-text-dim tabular-nums">{timeAgo(it.sent_at)}</span>
30
+ </span>}/>))}
31
+ {overflow > 0 && (<div className="px-3 py-1.5 text-[11px] text-text-dim border-t border-border">
32
+ +{overflow} more
33
+ </div>)}
34
+ </Card>);
35
+ }
36
+ //# sourceMappingURL=InboxStrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InboxStrip.js","sourceRoot":"","sources":["../../../src/ui/hubspot/InboxStrip.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{Card as K,CardHeader as P,Avatar as c,Row as E,StatusPill as H}from"@apteva/ui-kit";import{jsx as V,jsxs as F}from"react/jsx-runtime";function D(J){if(!J)return"—";let M=new Date(J);if(Number.isNaN(M.getTime()))return J;let X=Math.round((Date.now()-M.getTime())/1000);if(X<60)return"just now";let Q=Math.round(X/60);if(Q<60)return`${Q}m ago`;let Z=Math.round(Q/60);if(Z<24)return`${Z}h ago`;let $=Math.round(Z/24);if($<7)return`${$}d ago`;let q=Math.round($/7);if(q<5)return`${q}w ago`;return M.toLocaleDateString("en-US",{month:"short",day:"numeric"})}function z(J){let M=new Date;return M.setHours(M.getHours()-J),M.toISOString()}var f="0";function G(J,M,X){return`https://app.hubspot.com/contacts/${X||f}/${J}/${M}`}var g=F("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:[V("circle",{cx:"18",cy:"6",r:"2.2"}),V("circle",{cx:"18",cy:"18",r:"2.2"}),V("circle",{cx:"6",cy:"12",r:"2.2"}),V("circle",{cx:"14",cy:"12",r:"3",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),V("path",{d:"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8",stroke:"currentColor",strokeWidth:"1.2",fill:"none"})]}),B="#FF7A59",U={name:"HubSpot",logo:g,color:B};import{jsx as W,jsxs as N}from"react/jsx-runtime";var R=[{email_id:"1",from_name:"Sarah Chen",from_email:"sarah.chen@acme-logistics.com",subject:"Third time I'm asking — board review tomorrow",snippet:"We're 36 hours away from our board review.",sent_at:z(2),unread:!0,thread_length:3},{email_id:"2",from_name:"David Park",from_email:"david.park@globex-innovations.com",subject:"Globex pilot — push to next quarter",snippet:"We've had to deprioritize new initiatives…",sent_at:z(28),unread:!0},{email_id:"3",from_name:"Lisa Rodriguez",from_email:"lisa.rodriguez@initech-corp.com",subject:"Re: Pricing — final ask before committee",snippet:"Three different per-seat numbers from your team.",sent_at:z(6),unread:!0,thread_length:5},{email_id:"4",from_name:"HubSpot",from_email:"no-reply@hubspot.com",subject:"Weekly digest: 3 new opportunities",snippet:"Your pipeline summary for this week.",sent_at:z(80)}];function _(J){let M=J.preview?J.items??R:J.items??[],X=J.max_rows??6,Q=M.slice(0,X),Z=M.length-Q.length,$=M.filter((q)=>q.unread).length;return N(K,{fullWidth:!0,children:[W(P,{vendor:U,title:J.title||"Inbox",subtitle:J.subtitle||($>0?`${$} unread`:`${M.length} message${M.length===1?"":"s"}`)}),Q.length===0&&W("div",{className:"px-3 py-3 text-xs text-text-dim",children:"Inbox is quiet."}),Q.map((q,Y)=>W(E,{flush:Y===0,href:G("engagement",q.email_id,J.portal_id),leading:N("span",{className:"relative",children:[W(c,{src:"",name:q.from_name||q.from_email||"? ",size:20}),q.unread&&W("span",{className:"absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full bg-accent ring-1 ring-white dark:ring-zinc-900","aria-label":"unread"})]}),title:N("span",{className:q.unread?"font-semibold":void 0,children:[q.from_name||q.from_email,q.subject&&N("span",{className:"text-text-dim font-normal",children:[" · ",q.subject]})]}),subtitle:q.snippet,trailing:N("span",{className:"inline-flex items-center gap-1.5",children:[q.thread_length&&q.thread_length>1&&W(H,{variant:"info",children:q.thread_length}),W("span",{className:"text-text-dim tabular-nums",children:D(q.sent_at)})]})},q.email_id)),Z>0&&N("div",{className:"px-3 py-1.5 text-[11px] text-text-dim border-t border-border",children:["+",Z," more"]})]})}export{_ as default};
2
+
3
+ //# debugId=32D2320F7002334564756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/hubspot/InboxStrip.tsx", "../../../src/ui/hubspot/lib/hubspot.tsx"],
4
+ "sourcesContent": [
5
+ "// InboxStrip — compact unread-feed of recent emails. Same shape as\n// EmailCard items[] but flattened into one-line rows with a snippet.\n// Used in the dashboard tile and the demo runner's kiosk header.\n\nimport { Card, CardHeader, Avatar, Row, StatusPill } from \"@apteva/ui-kit\";\nimport { recordUrl, timeAgo, minusHoursISO, hubspotVendor } from \"./lib/hubspot\";\n\ninterface InboxItem {\n email_id: string;\n from_name?: string;\n from_email?: string;\n subject?: string;\n /** First line of the body — caller pre-trims. */\n snippet?: string;\n sent_at?: string;\n unread?: boolean;\n thread_length?: number;\n}\n\ninterface Props {\n items?: InboxItem[];\n title?: string;\n subtitle?: string;\n max_rows?: number;\n portal_id?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewItems: InboxItem[] = [\n { email_id: \"1\", from_name: \"Sarah Chen\", from_email: \"sarah.chen@acme-logistics.com\", subject: \"Third time I'm asking — board review tomorrow\", snippet: \"We're 36 hours away from our board review.\", sent_at: minusHoursISO(2), unread: true, thread_length: 3 },\n { email_id: \"2\", from_name: \"David Park\", from_email: \"david.park@globex-innovations.com\", subject: \"Globex pilot — push to next quarter\", snippet: \"We've had to deprioritize new initiatives…\", sent_at: minusHoursISO(28), unread: true },\n { email_id: \"3\", from_name: \"Lisa Rodriguez\", from_email: \"lisa.rodriguez@initech-corp.com\", subject: \"Re: Pricing — final ask before committee\", snippet: \"Three different per-seat numbers from your team.\", sent_at: minusHoursISO(6), unread: true, thread_length: 5 },\n { email_id: \"4\", from_name: \"HubSpot\", from_email: \"no-reply@hubspot.com\", subject: \"Weekly digest: 3 new opportunities\", snippet: \"Your pipeline summary for this week.\", sent_at: minusHoursISO(80) },\n];\n\nexport default function InboxStrip(props: Props) {\n const items = props.preview ? (props.items ?? previewItems) : (props.items ?? []);\n const max = props.max_rows ?? 6;\n const visible = items.slice(0, max);\n const overflow = items.length - visible.length;\n const unreadCount = items.filter((i) => i.unread).length;\n\n return (\n <Card fullWidth>\n <CardHeader\n vendor={hubspotVendor}\n title={props.title || \"Inbox\"}\n subtitle={props.subtitle || (unreadCount > 0 ? `${unreadCount} unread` : `${items.length} message${items.length === 1 ? \"\" :\"s\"}`)}\n />\n {visible.length === 0 && (\n <div className=\"px-3 py-3 text-xs text-text-dim\">Inbox is quiet.</div>\n )}\n {visible.map((it, i) => (\n <Row\n key={it.email_id}\n flush={i === 0}\n href={recordUrl(\"engagement\", it.email_id, props.portal_id)}\n leading={\n <span className=\"relative\">\n <Avatar src=\"\" name={it.from_name || it.from_email || \"? \"} size={20} />\n {it.unread && (\n <span className=\"absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full bg-accent ring-1 ring-white dark:ring-zinc-900\" aria-label=\"unread\" />\n )}\n </span>\n }\n title={\n <span className={it.unread ? \"font-semibold\" : undefined}>\n {it.from_name || it.from_email}\n {it.subject && <span className=\"text-text-dim font-normal\"> · {it.subject}</span>}\n </span>\n }\n subtitle={it.snippet}\n trailing={\n <span className=\"inline-flex items-center gap-1.5\">\n {it.thread_length && it.thread_length > 1 && (\n <StatusPill variant=\"info\">{it.thread_length}</StatusPill>\n )}\n <span className=\"text-text-dim tabular-nums\">{timeAgo(it.sent_at)}</span>\n </span>\n }\n />\n ))}\n {overflow > 0 && (\n <div className=\"px-3 py-1.5 text-[11px] text-text-dim border-t border-border\">\n +{overflow} more\n </div>\n )}\n </Card>\n );\n}\n",
6
+ "// Shared helpers for every HubSpot UI component.\n//\n// * pill metadata for deal stages, ticket priorities, lifecycle\n// stages — one source of truth for label + color across cards\n// * formatters: USD, relative date, relative time-since\n// * URL builders for HubSpot canonical record links\n// * favicon helper (Google s2)\n// * pillToDot — bridges StatusPill variant → StatusDot variant for\n// CardHeader's status slot\n// * HubSpot brand mark SVG used in every card header\n\nimport type { StatusDotVariant, StatusPillVariant } from \"@apteva/ui-kit\";\n\n// ─── pill metadata ────────────────────────────────────────────────\n\nexport type PillMeta = { label: string; variant: StatusPillVariant };\n\nconst DEAL_STAGE: Record<string, PillMeta> = {\n appointmentscheduled: { label: \"Appointment scheduled\", variant: \"info\" },\n qualifiedtobuy: { label: \"Qualified to buy\", variant: \"info\" },\n presentationscheduled: { label: \"Presentation scheduled\", variant: \"info\" },\n decisionmakerboughtin: { label: \"Decision-maker bought in \", variant: \"info\" },\n contractsent: { label: \"Contract sent\", variant: \"warn\" },\n closedwon: { label: \"Closed (won)\", variant: \"success\" },\n closedlost: { label: \"Closed (lost)\", variant: \"error\" },\n};\n\nexport function dealStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = DEAL_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst TICKET_PRIORITY: Record<string, PillMeta> = {\n LOW: { label: \"Low\", variant: \"neutral\" },\n MEDIUM: { label: \"Medium\", variant: \"info\" },\n HIGH: { label: \"High\", variant: \"warn\" },\n URGENT: { label: \"Urgent\", variant: \"error\" },\n};\n\nexport function ticketPriorityMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return TICKET_PRIORITY[id] ?? { label: id, variant: \"neutral\" };\n}\n\nconst TICKET_STAGE: Record<string, PillMeta> = {\n \"1\": { label: \"New\", variant: \"info\" },\n \"2\": { label: \"Waiting on us\", variant: \"warn\" },\n \"3\": { label: \"Waiting on them\", variant: \"neutral\" },\n \"4\": { label: \"Closed\", variant: \"success\" },\n};\n\nexport function ticketStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = TICKET_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst LIFECYCLE: Record<string, PillMeta> = {\n subscriber: { label: \"Subscriber\", variant: \"neutral\" },\n lead: { label: \"Lead\", variant: \"neutral\" },\n marketingqualifiedlead: { label: \"MQL\", variant: \"info\" },\n salesqualifiedlead: { label: \"SQL\", variant: \"info\" },\n opportunity: { label: \"Opportunity\", variant: \"info\" },\n customer: { label: \"Customer\", variant: \"success\" },\n evangelist: { label: \"Evangelist\", variant: \"success\" },\n other: { label: \"Other\", variant: \"neutral\" },\n};\n\nexport function lifecycleMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return LIFECYCLE[id] ?? { label: id, variant: \"neutral\" };\n}\n\n// ─── formatters ───────────────────────────────────────────────────\n\nexport function formatUSD(raw: string | number | undefined | null): string {\n if (raw === undefined || raw === null || raw === \"\") return \"—\";\n const n = typeof raw === \"number\" ? raw : Number(raw);\n if (!Number.isFinite(n)) return String(raw);\n return n.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: n >= 1000 ? 0 : 2,\n });\n}\n\nexport function formatRelativeDate(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const now = new Date();\n const days = Math.round((d.getTime() - now.getTime()) / 86_400_000);\n const dateStr = d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n if (days === 0) return `${dateStr} · today`;\n if (days > 0) return `${dateStr} · in ${days} day${days === 1 ? \"\" : \"s\"}`;\n const overdue = -days;\n return `${dateStr} · ${overdue} day${overdue === 1 ? \"\" : \"s\"} overdue`;\n}\n\nexport function timeAgo(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const sec = Math.round((Date.now() - d.getTime()) / 1000);\n if (sec < 60) return \"just now\";\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n if (day < 7) return `${day}d ago`;\n const wk = Math.round(day / 7);\n if (wk < 5) return `${wk}w ago`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nexport function addDaysISO(n: number): string {\n const d = new Date();\n d.setDate(d.getDate() + n);\n return d.toISOString().slice(0, 10);\n}\n\nexport function minusHoursISO(n: number): string {\n const d = new Date();\n d.setHours(d.getHours() - n);\n return d.toISOString();\n}\n\n// ─── URL builders ─────────────────────────────────────────────────\n\nconst PORTAL_FALLBACK = \"0\";\n\nexport function recordUrl(\n type: \"deal\" | \"company\" | \"contact\" | \"ticket\" | \"engagement\",\n id: string,\n portalId?: string,\n): string {\n const portal = portalId || PORTAL_FALLBACK;\n return `https://app.hubspot.com/contacts/${portal}/${type}/${id}`;\n}\n\nexport function pipelineUrl(portalId?: string, pipeline?: string): string {\n const portal = portalId || PORTAL_FALLBACK;\n const path = pipeline ? `?pipeline=${encodeURIComponent(pipeline)}` : \"\";\n return `https://app.hubspot.com/pipelines/${portal}/deals${path}`;\n}\n\n// ─── favicon helper ───────────────────────────────────────────────\n\nexport function faviconFor(domain: string | undefined, size = 32): string | undefined {\n if (!domain) return undefined;\n return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size}`;\n}\n\n// ─── pill → dot bridge ────────────────────────────────────────────\n//\n// CardHeader's status slot wants a StatusDot variant. StatusPill's\n// variant set is wider; this is the canonical mapping.\n\nexport function pillToDot(v: StatusPillVariant): StatusDotVariant {\n switch (v) {\n case \"success\": return \"live\";\n case \"info\": return \"active\";\n case \"warn\": return \"warn\";\n case \"error\": return \"error\";\n default: return \"muted\";\n }\n}\n\n// ─── HubSpot brand mark ───────────────────────────────────────────\n//\n// Simplified mark — three satellites linked to a central node. Reads\n// at 14×14 without shipping the full brand artwork. Uses currentColor\n// so the consumer can recolor it (CardHeader's vendor strip pipes the\n// HubSpot brand orange in via inline `style.color`).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\nexport const hubspotLogo: ReactNode = (\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <circle cx=\"18\" cy=\"6\" r=\"2.2\" />\n <circle cx=\"18\" cy=\"18\" r=\"2.2\" />\n <circle cx=\"6\" cy=\"12\" r=\"2.2\" />\n <circle cx=\"14\" cy=\"12\" r=\"3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8\" stroke=\"currentColor\" strokeWidth=\"1.2\" fill=\"none\" />\n </svg>\n);\n\n// HubSpot's official brand orange. Passed through CardHeader's\n// `vendor.color` so the brand strip on every HubSpot-emitted card\n// reads as obviously HubSpot at a glance, in both light and dark.\nexport const HUBSPOT_BRAND_COLOR = \"#FF7A59\";\n\nexport const hubspotVendor: CardVendor = {\n name: \"HubSpot\",\n logo: hubspotLogo,\n color: HUBSPOT_BRAND_COLOR,\n};\n"
7
+ ],
8
+ "mappings": "AAIA,eAAS,gBAAM,YAAY,SAAQ,gBAAK,yECkGjC,SAAS,CAAO,CAAC,EAAiC,CACvD,GAAI,CAAC,EAAK,MAAO,IACjB,IAAM,EAAI,IAAI,KAAK,CAAG,EACtB,GAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAG,OAAO,EACtC,IAAM,EAAM,KAAK,OAAO,KAAK,IAAI,EAAI,EAAE,QAAQ,GAAK,IAAI,EACxD,GAAI,EAAM,GAAI,MAAO,WACrB,IAAM,EAAM,KAAK,MAAM,EAAM,EAAE,EAC/B,GAAI,EAAM,GAAI,MAAO,GAAG,SACxB,IAAM,EAAK,KAAK,MAAM,EAAM,EAAE,EAC9B,GAAI,EAAK,GAAI,MAAO,GAAG,SACvB,IAAM,EAAM,KAAK,MAAM,EAAK,EAAE,EAC9B,GAAI,EAAM,EAAG,MAAO,GAAG,SACvB,IAAM,EAAK,KAAK,MAAM,EAAM,CAAC,EAC7B,GAAI,EAAK,EAAG,MAAO,GAAG,SACtB,OAAO,EAAE,mBAAmB,QAAS,CAAE,MAAO,QAAS,IAAK,SAAU,CAAC,EASlE,SAAS,CAAa,CAAC,EAAmB,CAC/C,IAAM,EAAI,IAAI,KAEd,OADA,EAAE,SAAS,EAAE,SAAS,EAAI,CAAC,EACpB,EAAE,YAAY,EAKvB,IAAM,EAAkB,IAEjB,SAAS,CAAS,CACvB,EACA,EACA,EACQ,CAER,MAAO,oCADQ,GAAY,KAC0B,KAAQ,IAyCxD,IAAM,EACX,EAME,MANF,CAAK,QAAQ,YAAY,MAAM,KAAK,OAAO,KAAK,KAAK,eAAe,cAAW,GAA/E,SAME,CALA,EAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,IAAI,EAAE,MAAM,EAC/B,EAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,EAChC,EAAC,SAAD,CAAQ,GAAG,IAAI,GAAG,KAAK,EAAE,MAAM,EAC/B,EAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,OAAO,OAAO,eAAe,YAAY,MAAM,EAClF,EAAC,OAAD,CAAM,EAAE,oDAAoD,OAAO,eAAe,YAAY,MAAM,KAAK,OAAO,GAChH,EAMS,EAAsB,UAEtB,EAA4B,CACvC,KAAM,UACN,KAAM,EACN,MAAO,CACT,oDD5KA,IAAM,EAA4B,CACjC,CAAE,SAAU,IAAK,UAAW,aAAc,WAAY,gCAAiC,QAAS,gDAAgD,QAAS,6CAA8C,QAAS,EAAc,CAAC,EAAG,OAAQ,GAAM,cAAe,CAAE,EACjQ,CAAE,SAAU,IAAK,UAAW,aAAc,WAAY,oCAAqC,QAAS,sCAAsC,QAAS,6CAA8C,QAAS,EAAc,EAAE,EAAG,OAAQ,EAAK,EAC1O,CAAE,SAAU,IAAK,UAAW,iBAAkB,WAAY,kCAAmC,QAAS,2CAA2C,QAAS,mDAAoD,QAAS,EAAc,CAAC,EAAG,OAAQ,GAAM,cAAe,CAAE,EACxQ,CAAE,SAAU,IAAK,UAAW,UAAW,WAAY,uBAAwB,QAAS,qCAAsC,QAAS,uCAAwC,QAAS,EAAc,EAAE,CAAE,CACvM,EAEA,SAAwB,CAAU,CAAC,EAAc,CAChD,IAAM,EAAQ,EAAM,QAAW,EAAM,OAAS,EAAiB,EAAM,OAAS,CAAC,EACzE,EAAM,EAAM,UAAY,EACxB,EAAU,EAAM,MAAM,EAAG,CAAG,EAC5B,EAAW,EAAM,OAAS,EAAQ,OAClC,EAAc,EAAM,OAAO,CAAC,IAAM,EAAE,MAAM,EAAE,OAElD,OACA,EA4CE,EA5CF,CAAM,UAAS,GAAf,SA4CE,CA3CF,EAAC,EAAD,CACA,OAAQ,EACR,MAAO,EAAM,OAAS,QACtB,SAAU,EAAM,WAAa,EAAc,EAAI,GAAG,WAAuB,GAAG,EAAM,iBAAiB,EAAM,SAAW,EAAI,GAAI,OAC5H,EACC,EAAQ,SAAW,GACpB,EAAkE,MAAlE,CAAK,UAAU,kCAAf,2BAAkE,EAEjE,EAAQ,IAAI,CAAC,EAAI,IAClB,EAAC,EAAD,CAEA,MAAO,IAAM,EACb,KAAM,EAAU,aAAc,EAAG,SAAU,EAAM,SAAS,EAC1D,QACA,EAKE,OALF,CAAM,UAAU,WAAhB,SAKE,CAJF,EAAC,EAAD,CAAQ,IAAI,GAAG,KAAM,EAAG,WAAa,EAAG,YAAc,KAAM,KAAM,GAAI,EACrE,EAAG,QACJ,EAAC,OAAD,CAAM,UAAU,mGAAmG,aAAW,SAAS,GAErI,EAEF,MACA,EAGE,OAHF,CAAM,UAAW,EAAG,OAAS,gBAAkB,OAA/C,SAGE,CAFD,EAAG,WAAa,EAAG,WACnB,EAAG,SAAW,EAA4D,OAA5D,CAAM,UAAU,4BAAhB,SAA4D,CAA5D,MAA+C,EAAG,SAAU,GACzE,EAEF,SAAU,EAAG,QACb,SACA,EAKE,OALF,CAAM,UAAU,mCAAhB,SAKE,CAJD,EAAG,eAAiB,EAAG,cAAgB,GACxC,EAA+C,EAA/C,CAAY,QAAQ,OAApB,SAA4B,EAAG,cAAgB,EAE/C,EAAoE,OAApE,CAAM,UAAU,6BAAhB,SAA8C,EAAQ,EAAG,OAAO,EAAI,GAClE,GAxBG,EAAG,QA0BR,CACC,EACA,EAAW,GACZ,EAEE,MAFF,CAAK,UAAU,+DAAf,SAEE,CAFF,IACE,EADF,SAEE,GAEA",
9
+ "debugId": "32D2320F7002334564756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,22 @@
1
+ interface Stage {
2
+ /** HubSpot internal stage id (e.g."contractsent"). */
3
+ id: string;
4
+ /** Optional human label override for custom pipelines. */
5
+ label?: string;
6
+ count: number;
7
+ /** Sum of deal amounts in the stage. HubSpot wire string or number. */
8
+ total?: string | number;
9
+ }
10
+ interface Props {
11
+ /** Pipeline display name (e.g."Sales pipeline"). */
12
+ pipeline_label?: string;
13
+ /** Pipeline id — used for the canonical link. */
14
+ pipeline?: string;
15
+ stages?: Stage[];
16
+ portal_id?: string;
17
+ preview?: boolean;
18
+ projectId?: string;
19
+ }
20
+ export default function PipelineStrip(props: Props): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=PipelineStrip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelineStrip.d.ts","sourceRoot":"","sources":["../../../src/ui/hubspot/PipelineStrip.tsx"],"names":[],"mappings":"AAkBA,UAAU,KAAK;IACd,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,UAAU,KAAK;IACd,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAUD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,KAAK,+BAmDjD"}
@@ -0,0 +1,54 @@
1
+ // PipelineStrip — at-a-glance funnel state. Compact horizontal strip
2
+ // of deal-pipeline stages, each tile rendering count + total $ via
3
+ // the shared KPI primitive. Designed for the dashboard tile slot and
4
+ // the demo runner's kiosk-mode header.
5
+ //
6
+ // Caller pre-aggregates the data — we don't fetch here. A typical
7
+ // agent computation:
8
+ //
9
+ // stages = [
10
+ // { id: "qualifiedtobuy", count: 4, total: "210000" },
11
+ // { id: "presentationscheduled", count: 3, total: "165000" },
12
+ // { id: "decisionmakerboughtin", count: 2, total: "180000" },
13
+ // { id: "contractsent", count: 2, total: "98000" },
14
+ // ]
15
+ import { Card, CardHeader, KPI } from "@apteva/ui-kit";
16
+ import { dealStageMeta, formatUSD, pipelineUrl, hubspotVendor } from "./lib/hubspot";
17
+ const previewStages = [
18
+ { id: "qualifiedtobuy", count: 4, total: "210000" },
19
+ { id: "presentationscheduled", count: 3, total: "165000" },
20
+ { id: "decisionmakerboughtin", count: 2, total: "180000" },
21
+ { id: "contractsent", count: 2, total: "98000" },
22
+ { id: "closedwon", count: 5, total: "412000" },
23
+ ];
24
+ export default function PipelineStrip(props) {
25
+ const p = props.preview ? { pipeline_label: "Sales pipeline", pipeline: "default", stages: previewStages, portal_id: "0", ...props } : props;
26
+ const stages = p.stages ?? [];
27
+ const url = pipelineUrl(p.portal_id, p.pipeline);
28
+ // Aggregate total across non-closed stages — the headline number.
29
+ const openTotal = stages
30
+ .filter((s) => s.id !== "closedwon" && s.id !== "closedlost")
31
+ .reduce((acc, s) => acc + (Number(s.total ?? 0) || 0), 0);
32
+ const openCount = stages
33
+ .filter((s) => s.id !== "closedwon" && s.id !== "closedlost")
34
+ .reduce((acc, s) => acc + (s.count || 0), 0);
35
+ return (<Card fullWidth>
36
+ <CardHeader vendor={hubspotVendor} title={p.pipeline_label || "Pipeline"} subtitle={openCount > 0 ? `${openCount} open · ${formatUSD(openTotal)} weighted` : "No open deals"} action={{ label: "Open pipeline", href: url }}/>
37
+ <div className="px-3 py-3 overflow-x-auto">
38
+ <div className="flex items-stretch gap-4 min-w-max">
39
+ {stages.map((s, i) => {
40
+ const meta = dealStageMeta(s.id, s.label);
41
+ return (<div key={s.id} className="flex items-stretch gap-4">
42
+ <KPI label={meta.label} value={<span>{s.count}</span>} caption={s.total !== undefined ? formatUSD(s.total) : undefined} tone={meta.variant === "success" ? "positive"
43
+ : meta.variant === "error" ? "negative"
44
+ : meta.variant === "warn" ? "accent"
45
+ : "neutral"}/>
46
+ {i < stages.length - 1 && (<span className="self-center text-text-dim">›</span>)}
47
+ </div>);
48
+ })}
49
+ {stages.length === 0 && (<span className="text-xs text-text-dim">No stages provided.</span>)}
50
+ </div>
51
+ </div>
52
+ </Card>);
53
+ }
54
+ //# sourceMappingURL=PipelineStrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelineStrip.js","sourceRoot":"","sources":["../../../src/ui/hubspot/PipelineStrip.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,mEAAmE;AACnE,qEAAqE;AACrE,uCAAuC;AACvC,EAAE;AACF,kEAAkE;AAClE,qBAAqB;AACrB,EAAE;AACF,aAAa;AACb,uDAAuD;AACvD,8DAA8D;AAC9D,8DAA8D;AAC9D,oDAAoD;AACpD,IAAI;AAEJ,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuBrF,MAAM,aAAa,GAAY;IAC9B,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACnD,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1D,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1D,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE;IAChD,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;CAC9C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAY;IACjD,MAAM,CAAC,GAAU,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACpJ,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEjD,kEAAkE;IAClE,MAAM,SAAS,GAAG,MAAM;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC;SAC5D,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,MAAM;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC;SAC5D,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7C,OAAO,CACP,CAAC,IAAI,CAAC,SAAS,CACf;CAAA,CAAC,UAAU,CACX,MAAM,CAAC,CAAC,aAAa,CAAC,CACtB,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,UAAU,CAAC,CACtC,QAAQ,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,WAAW,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAA,eAAe,CAAC,CAClG,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAE9C;CAAA,CAAC,GAAG,CAAC,SAAS,CAAC,2BAA2B,CAC1C;CAAA,CAAC,GAAG,CAAC,SAAS,CAAC,oCAAoC,CACnD;CAAA,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1C,OAAO,CACP,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,0BAA0B,CACpD;CAAA,CAAC,GAAG,CACJ,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAClB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAC9B,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAChE,IAAI,CAAC,CACL,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU;oBACvC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU;wBACvC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ;4BACpC,CAAC,CAAC,SACF,CAAC,EAED;CAAA,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAC1B,CAAC,IAAI,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,EAAE,IAAI,CAAC,CACnD,CACD;CAAA,EAAE,GAAG,CAAC,CACL,CAAC;QACF,CAAC,CAAC,CACF;CAAA,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CACxB,CAAC,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,mBAAmB,EAAE,IAAI,CAAC,CACjE,CACD;CAAA,EAAE,GAAG,CACL;CAAA,EAAE,GAAG,CACL;CAAA,EAAE,IAAI,CAAC,CACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import{Card as O,CardHeader as R,KPI as E}from"@apteva/ui-kit";import{jsx as $,jsxs as P}from"react/jsx-runtime";var B={appointmentscheduled:{label:"Appointment scheduled",variant:"info"},qualifiedtobuy:{label:"Qualified to buy",variant:"info"},presentationscheduled:{label:"Presentation scheduled",variant:"info"},decisionmakerboughtin:{label:"Decision-maker bought in ",variant:"info"},contractsent:{label:"Contract sent",variant:"warn"},closedwon:{label:"Closed (won)",variant:"success"},closedlost:{label:"Closed (lost)",variant:"error"}};function G(q,Q){if(!q)return{label:Q??"—",variant:"neutral"};let W=B[q];if(W)return{label:Q??W.label,variant:W.variant};return{label:Q??q,variant:"neutral"}}function V(q){if(q===void 0||q===null||q==="")return"—";let Q=typeof q==="number"?q:Number(q);if(!Number.isFinite(Q))return String(q);return Q.toLocaleString("en-US",{style:"currency",currency:"USD",maximumFractionDigits:Q>=1000?0:2})}var D="0";function Y(q,Q){let W=q||D,N=Q?`?pipeline=${encodeURIComponent(Q)}`:"";return`https://app.hubspot.com/pipelines/${W}/deals${N}`}var U=P("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:[$("circle",{cx:"18",cy:"6",r:"2.2"}),$("circle",{cx:"18",cy:"18",r:"2.2"}),$("circle",{cx:"6",cy:"12",r:"2.2"}),$("circle",{cx:"14",cy:"12",r:"3",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),$("path",{d:"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8",stroke:"currentColor",strokeWidth:"1.2",fill:"none"})]}),K="#FF7A59",F={name:"HubSpot",logo:U,color:K};import{jsx as X,jsxs as f}from"react/jsx-runtime";var _=[{id:"qualifiedtobuy",count:4,total:"210000"},{id:"presentationscheduled",count:3,total:"165000"},{id:"decisionmakerboughtin",count:2,total:"180000"},{id:"contractsent",count:2,total:"98000"},{id:"closedwon",count:5,total:"412000"}];function b(q){let Q=q.preview?{pipeline_label:"Sales pipeline",pipeline:"default",stages:_,portal_id:"0",...q}:q,W=Q.stages??[],N=Y(Q.portal_id,Q.pipeline),H=W.filter((J)=>J.id!=="closedwon"&&J.id!=="closedlost").reduce((J,Z)=>J+(Number(Z.total??0)||0),0),z=W.filter((J)=>J.id!=="closedwon"&&J.id!=="closedlost").reduce((J,Z)=>J+(Z.count||0),0);return f(O,{fullWidth:!0,children:[X(R,{vendor:F,title:Q.pipeline_label||"Pipeline",subtitle:z>0?`${z} open · ${V(H)} weighted`:"No open deals",action:{label:"Open pipeline",href:N}}),X("div",{className:"px-3 py-3 overflow-x-auto",children:f("div",{className:"flex items-stretch gap-4 min-w-max",children:[W.map((J,Z)=>{let M=G(J.id,J.label);return f("div",{className:"flex items-stretch gap-4",children:[X(E,{label:M.label,value:X("span",{children:J.count}),caption:J.total!==void 0?V(J.total):void 0,tone:M.variant==="success"?"positive":M.variant==="error"?"negative":M.variant==="warn"?"accent":"neutral"}),Z<W.length-1&&X("span",{className:"self-center text-text-dim",children:"›"})]},J.id)}),W.length===0&&X("span",{className:"text-xs text-text-dim",children:"No stages provided."})]})})]})}export{b as default};
2
+
3
+ //# debugId=97309CEF443473D864756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/hubspot/PipelineStrip.tsx", "../../../src/ui/hubspot/lib/hubspot.tsx"],
4
+ "sourcesContent": [
5
+ "// PipelineStrip — at-a-glance funnel state. Compact horizontal strip\n// of deal-pipeline stages, each tile rendering count + total $ via\n// the shared KPI primitive. Designed for the dashboard tile slot and\n// the demo runner's kiosk-mode header.\n//\n// Caller pre-aggregates the data — we don't fetch here. A typical\n// agent computation:\n//\n// stages = [\n// { id: \"qualifiedtobuy\", count: 4, total: \"210000\" },\n// { id: \"presentationscheduled\", count: 3, total: \"165000\" },\n// { id: \"decisionmakerboughtin\", count: 2, total: \"180000\" },\n// { id: \"contractsent\", count: 2, total: \"98000\" },\n// ]\n\nimport { Card, CardHeader, KPI } from \"@apteva/ui-kit\";\nimport { dealStageMeta, formatUSD, pipelineUrl, hubspotVendor } from \"./lib/hubspot\";\n\ninterface Stage {\n /** HubSpot internal stage id (e.g.\"contractsent\"). */\n id: string;\n /** Optional human label override for custom pipelines. */\n label?: string;\n count: number;\n /** Sum of deal amounts in the stage. HubSpot wire string or number. */\n total?: string | number;\n}\n\ninterface Props {\n /** Pipeline display name (e.g.\"Sales pipeline\"). */\n pipeline_label?: string;\n /** Pipeline id — used for the canonical link. */\n pipeline?: string;\n stages?: Stage[];\n portal_id?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewStages: Stage[] = [\n { id: \"qualifiedtobuy\", count: 4, total: \"210000\" },\n { id: \"presentationscheduled\", count: 3, total: \"165000\" },\n { id: \"decisionmakerboughtin\", count: 2, total: \"180000\" },\n { id: \"contractsent\", count: 2, total: \"98000\" },\n { id: \"closedwon\", count: 5, total: \"412000\" },\n];\n\nexport default function PipelineStrip(props: Props) {\n const p: Props = props.preview ? { pipeline_label: \"Sales pipeline\", pipeline: \"default\", stages: previewStages, portal_id: \"0\", ...props } : props;\n const stages = p.stages ?? [];\n const url = pipelineUrl(p.portal_id, p.pipeline);\n\n // Aggregate total across non-closed stages — the headline number.\n const openTotal = stages\n .filter((s) => s.id !== \"closedwon\" && s.id !== \"closedlost\")\n .reduce((acc, s) => acc + (Number(s.total ?? 0) || 0), 0);\n const openCount = stages\n .filter((s) => s.id !== \"closedwon\" && s.id !== \"closedlost\")\n .reduce((acc, s) => acc + (s.count || 0), 0);\n\n return (\n <Card fullWidth>\n <CardHeader\n vendor={hubspotVendor}\n title={p.pipeline_label || \"Pipeline\"}\n subtitle={openCount > 0 ? `${openCount} open · ${formatUSD(openTotal)} weighted` :\"No open deals\"}\n action={{ label: \"Open pipeline\", href: url }}\n />\n <div className=\"px-3 py-3 overflow-x-auto\">\n <div className=\"flex items-stretch gap-4 min-w-max\">\n {stages.map((s, i) => {\n const meta = dealStageMeta(s.id, s.label);\n return (\n <div key={s.id} className=\"flex items-stretch gap-4\">\n <KPI\n label={meta.label}\n value={<span>{s.count}</span>}\n caption={s.total !== undefined ? formatUSD(s.total) : undefined}\n tone={\n meta.variant === \"success\" ? \"positive\"\n : meta.variant === \"error\" ? \"negative\"\n : meta.variant === \"warn\" ? \"accent\"\n : \"neutral\"\n }\n />\n {i < stages.length - 1 && (\n <span className=\"self-center text-text-dim\">›</span>\n )}\n </div>\n );\n })}\n {stages.length === 0 && (\n <span className=\"text-xs text-text-dim\">No stages provided.</span>\n )}\n </div>\n </div>\n </Card>\n );\n}\n",
6
+ "// Shared helpers for every HubSpot UI component.\n//\n// * pill metadata for deal stages, ticket priorities, lifecycle\n// stages — one source of truth for label + color across cards\n// * formatters: USD, relative date, relative time-since\n// * URL builders for HubSpot canonical record links\n// * favicon helper (Google s2)\n// * pillToDot — bridges StatusPill variant → StatusDot variant for\n// CardHeader's status slot\n// * HubSpot brand mark SVG used in every card header\n\nimport type { StatusDotVariant, StatusPillVariant } from \"@apteva/ui-kit\";\n\n// ─── pill metadata ────────────────────────────────────────────────\n\nexport type PillMeta = { label: string; variant: StatusPillVariant };\n\nconst DEAL_STAGE: Record<string, PillMeta> = {\n appointmentscheduled: { label: \"Appointment scheduled\", variant: \"info\" },\n qualifiedtobuy: { label: \"Qualified to buy\", variant: \"info\" },\n presentationscheduled: { label: \"Presentation scheduled\", variant: \"info\" },\n decisionmakerboughtin: { label: \"Decision-maker bought in \", variant: \"info\" },\n contractsent: { label: \"Contract sent\", variant: \"warn\" },\n closedwon: { label: \"Closed (won)\", variant: \"success\" },\n closedlost: { label: \"Closed (lost)\", variant: \"error\" },\n};\n\nexport function dealStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = DEAL_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst TICKET_PRIORITY: Record<string, PillMeta> = {\n LOW: { label: \"Low\", variant: \"neutral\" },\n MEDIUM: { label: \"Medium\", variant: \"info\" },\n HIGH: { label: \"High\", variant: \"warn\" },\n URGENT: { label: \"Urgent\", variant: \"error\" },\n};\n\nexport function ticketPriorityMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return TICKET_PRIORITY[id] ?? { label: id, variant: \"neutral\" };\n}\n\nconst TICKET_STAGE: Record<string, PillMeta> = {\n \"1\": { label: \"New\", variant: \"info\" },\n \"2\": { label: \"Waiting on us\", variant: \"warn\" },\n \"3\": { label: \"Waiting on them\", variant: \"neutral\" },\n \"4\": { label: \"Closed\", variant: \"success\" },\n};\n\nexport function ticketStageMeta(id: string | undefined, override?: string): PillMeta {\n if (!id) return { label: override ?? \"—\", variant: \"neutral\" };\n const known = TICKET_STAGE[id];\n if (known) return { label: override ?? known.label, variant: known.variant };\n return { label: override ?? id, variant: \"neutral\" };\n}\n\nconst LIFECYCLE: Record<string, PillMeta> = {\n subscriber: { label: \"Subscriber\", variant: \"neutral\" },\n lead: { label: \"Lead\", variant: \"neutral\" },\n marketingqualifiedlead: { label: \"MQL\", variant: \"info\" },\n salesqualifiedlead: { label: \"SQL\", variant: \"info\" },\n opportunity: { label: \"Opportunity\", variant: \"info\" },\n customer: { label: \"Customer\", variant: \"success\" },\n evangelist: { label: \"Evangelist\", variant: \"success\" },\n other: { label: \"Other\", variant: \"neutral\" },\n};\n\nexport function lifecycleMeta(id: string | undefined): PillMeta {\n if (!id) return { label: \"—\", variant: \"neutral\" };\n return LIFECYCLE[id] ?? { label: id, variant: \"neutral\" };\n}\n\n// ─── formatters ───────────────────────────────────────────────────\n\nexport function formatUSD(raw: string | number | undefined | null): string {\n if (raw === undefined || raw === null || raw === \"\") return \"—\";\n const n = typeof raw === \"number\" ? raw : Number(raw);\n if (!Number.isFinite(n)) return String(raw);\n return n.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: n >= 1000 ? 0 : 2,\n });\n}\n\nexport function formatRelativeDate(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const now = new Date();\n const days = Math.round((d.getTime() - now.getTime()) / 86_400_000);\n const dateStr = d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n if (days === 0) return `${dateStr} · today`;\n if (days > 0) return `${dateStr} · in ${days} day${days === 1 ? \"\" : \"s\"}`;\n const overdue = -days;\n return `${dateStr} · ${overdue} day${overdue === 1 ? \"\" : \"s\"} overdue`;\n}\n\nexport function timeAgo(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const sec = Math.round((Date.now() - d.getTime()) / 1000);\n if (sec < 60) return \"just now\";\n const min = Math.round(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n if (day < 7) return `${day}d ago`;\n const wk = Math.round(day / 7);\n if (wk < 5) return `${wk}w ago`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nexport function addDaysISO(n: number): string {\n const d = new Date();\n d.setDate(d.getDate() + n);\n return d.toISOString().slice(0, 10);\n}\n\nexport function minusHoursISO(n: number): string {\n const d = new Date();\n d.setHours(d.getHours() - n);\n return d.toISOString();\n}\n\n// ─── URL builders ─────────────────────────────────────────────────\n\nconst PORTAL_FALLBACK = \"0\";\n\nexport function recordUrl(\n type: \"deal\" | \"company\" | \"contact\" | \"ticket\" | \"engagement\",\n id: string,\n portalId?: string,\n): string {\n const portal = portalId || PORTAL_FALLBACK;\n return `https://app.hubspot.com/contacts/${portal}/${type}/${id}`;\n}\n\nexport function pipelineUrl(portalId?: string, pipeline?: string): string {\n const portal = portalId || PORTAL_FALLBACK;\n const path = pipeline ? `?pipeline=${encodeURIComponent(pipeline)}` : \"\";\n return `https://app.hubspot.com/pipelines/${portal}/deals${path}`;\n}\n\n// ─── favicon helper ───────────────────────────────────────────────\n\nexport function faviconFor(domain: string | undefined, size = 32): string | undefined {\n if (!domain) return undefined;\n return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size}`;\n}\n\n// ─── pill → dot bridge ────────────────────────────────────────────\n//\n// CardHeader's status slot wants a StatusDot variant. StatusPill's\n// variant set is wider; this is the canonical mapping.\n\nexport function pillToDot(v: StatusPillVariant): StatusDotVariant {\n switch (v) {\n case \"success\": return \"live\";\n case \"info\": return \"active\";\n case \"warn\": return \"warn\";\n case \"error\": return \"error\";\n default: return \"muted\";\n }\n}\n\n// ─── HubSpot brand mark ───────────────────────────────────────────\n//\n// Simplified mark — three satellites linked to a central node. Reads\n// at 14×14 without shipping the full brand artwork. Uses currentColor\n// so the consumer can recolor it (CardHeader's vendor strip pipes the\n// HubSpot brand orange in via inline `style.color`).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\nexport const hubspotLogo: ReactNode = (\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <circle cx=\"18\" cy=\"6\" r=\"2.2\" />\n <circle cx=\"18\" cy=\"18\" r=\"2.2\" />\n <circle cx=\"6\" cy=\"12\" r=\"2.2\" />\n <circle cx=\"14\" cy=\"12\" r=\"3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8\" stroke=\"currentColor\" strokeWidth=\"1.2\" fill=\"none\" />\n </svg>\n);\n\n// HubSpot's official brand orange. Passed through CardHeader's\n// `vendor.color` so the brand strip on every HubSpot-emitted card\n// reads as obviously HubSpot at a glance, in both light and dark.\nexport const HUBSPOT_BRAND_COLOR = \"#FF7A59\";\n\nexport const hubspotVendor: CardVendor = {\n name: \"HubSpot\",\n logo: hubspotLogo,\n color: HUBSPOT_BRAND_COLOR,\n};\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "97309CEF443473D864756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,25 @@
1
+ interface Props {
2
+ ticket_id: string;
3
+ subject?: string;
4
+ content?: string;
5
+ /** HubSpot internal priority id: LOW | MEDIUM | HIGH | URGENT. */
6
+ hs_ticket_priority?: string;
7
+ /** Pipeline-stage id (per-pipeline;"1" is"New" in the default). */
8
+ hs_pipeline_stage?: string;
9
+ /** Optional human-friendly stage label override. */
10
+ stage_label?: string;
11
+ /** ISO timestamp when the ticket was created. */
12
+ createdate?: string;
13
+ /** ISO timestamp of the last update. */
14
+ hs_lastmodifieddate?: string;
15
+ company_name?: string;
16
+ company_domain?: string;
17
+ /** Number of comments / replies on the ticket. */
18
+ comment_count?: number;
19
+ portal_id?: string;
20
+ preview?: boolean;
21
+ projectId?: string;
22
+ }
23
+ export default function TicketCard(props: Props): import("react").JSX.Element;
24
+ export {};
25
+ //# sourceMappingURL=TicketCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TicketCard.d.ts","sourceRoot":"","sources":["../../../src/ui/hubspot/TicketCard.tsx"],"names":[],"mappings":"AAYA,UAAU,KAAK;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAoBD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,KAAK,EAAE,KAAK,+BAkD9C"}
@@ -0,0 +1,53 @@
1
+ // TicketCard — single HubSpot ticket. Subject + content body up top,
2
+ // priority pill (LOW/MED/HIGH/URGENT — color-coded), pipeline-stage
3
+ // pill, age, associated company. The card the demo uses for Acme's
4
+ // HIGH-priority API-latency ticket.
5
+ import { MessageCircle } from "lucide-react";
6
+ import { Card, CardHeader, StatusPill, DataList } from "@apteva/ui-kit";
7
+ import { ticketPriorityMeta, ticketStageMeta, recordUrl, faviconFor, pillToDot, timeAgo, minusHoursISO, hubspotVendor, } from "./lib/hubspot";
8
+ const previewSample = {
9
+ ticket_id: "20100",
10
+ subject: "Slow API response times — affecting overnight runs",
11
+ content: "Acme reports API p95 latency above 4s for 10 days. Two follow-ups, no resolution.",
12
+ hs_ticket_priority: "HIGH",
13
+ hs_pipeline_stage: "2",
14
+ createdate: minusHoursISO(240), // ~10 days
15
+ hs_lastmodifieddate: minusHoursISO(36),
16
+ company_name: "Acme Logistics",
17
+ company_domain: "acme-logistics.com",
18
+ comment_count: 4,
19
+ portal_id: "0",
20
+ };
21
+ export default function TicketCard(props) {
22
+ const p = props.preview ? { ...previewSample, ...props } : props;
23
+ const priority = ticketPriorityMeta(p.hs_ticket_priority);
24
+ const stage = ticketStageMeta(p.hs_pipeline_stage, p.stage_label);
25
+ const url = recordUrl("ticket", p.ticket_id, p.portal_id);
26
+ return (<Card>
27
+ <CardHeader vendor={hubspotVendor} title={p.subject || `Ticket ${p.ticket_id}`} subtitle={p.company_name} status={{ label: priority.label, variant: pillToDot(priority.variant) }} action={{ label: "View in HubSpot", href: url }}/>
28
+ <div className="px-3 py-3 flex flex-col gap-3">
29
+ <div className="flex items-center gap-2 flex-wrap">
30
+ <StatusPill variant={priority.variant}>{priority.label} priority</StatusPill>
31
+ <StatusPill variant={stage.variant}>{stage.label}</StatusPill>
32
+ {p.comment_count !== undefined && p.comment_count > 0 && (<span className="text-[11px] text-text-dim inline-flex items-center gap-1"><MessageCircle className="w-3 h-3"/>{p.comment_count}</span>)}
33
+ </div>
34
+
35
+ {p.content && (<div className="text-xs text-text-muted line-clamp-3 border-l-2 border-border pl-2">
36
+ {p.content}
37
+ </div>)}
38
+
39
+ <DataList items={[
40
+ ...(p.company_name ? [{
41
+ label: "Company",
42
+ value: (<span className="inline-flex items-center gap-1.5">
43
+ {p.company_domain && (<img src={faviconFor(p.company_domain)} alt="" width={12} height={12} className="rounded-sm"/>)}
44
+ <span className="text-text">{p.company_name}</span>
45
+ </span>),
46
+ }] : []),
47
+ ...(p.createdate ? [{ label: "Opened", value: timeAgo(p.createdate) }] : []),
48
+ ...(p.hs_lastmodifieddate ? [{ label: "Updated", value: timeAgo(p.hs_lastmodifieddate) }] : []),
49
+ ]}/>
50
+ </div>
51
+ </Card>);
52
+ }
53
+ //# sourceMappingURL=TicketCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TicketCard.js","sourceRoot":"","sources":["../../../src/ui/hubspot/TicketCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{forwardRef as m,createElement as a}from"react";var F=(...Q)=>Q.filter((J,X,Z)=>{return Boolean(J)&&J.trim()!==""&&Z.indexOf(J)===X}).join(" ").trim();var M=(Q)=>Q.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var P=(Q)=>Q.replace(/^([A-Z])|[\s-_]+(\w)/g,(J,X,Z)=>Z?Z.toUpperCase():X.toLowerCase());var O=(Q)=>{let J=P(Q);return J.charAt(0).toUpperCase()+J.slice(1)};import{forwardRef as j,createElement as I}from"react";var H={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var R=(Q)=>{for(let J in Q)if(J.startsWith("aria-")||J==="role"||J==="title")return!0;return!1};import{createContext as p,useContext as l,useMemo as HJ,createElement as KJ}from"react";var d=p({});var W=()=>l(d);var A=j(({color:Q,size:J,strokeWidth:X,absoluteStrokeWidth:Z,className:V="",children:$,iconNode:D,...T},v)=>{let{size:K=24,strokeWidth:_=2,absoluteStrokeWidth:f=!1,color:g="currentColor",className:k=""}=W()??{},h=Z??f?Number(X??_)*24/Number(J??K):X??_;return I("svg",{ref:v,...H,width:J??K??H.width,height:J??K??H.height,stroke:Q??g,strokeWidth:h,className:F("lucide",k,V),...!$&&!R(T)&&{"aria-hidden":"true"},...T},[...D.map(([w,u])=>I(w,u)),...Array.isArray($)?$:[$]])});var S=(Q,J)=>{let X=m(({className:Z,...V},$)=>a(A,{ref:$,iconNode:J,className:F(`lucide-${M(O(Q))}`,`lucide-${Q}`,Z),...V}));return X.displayName=O(Q),X};var r=[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]],Y=S("message-circle",r);import{Card as s,CardHeader as JJ,StatusPill as x,DataList as QJ}from"@apteva/ui-kit";import{jsx as B,jsxs as o}from"react/jsx-runtime";var t={LOW:{label:"Low",variant:"neutral"},MEDIUM:{label:"Medium",variant:"info"},HIGH:{label:"High",variant:"warn"},URGENT:{label:"Urgent",variant:"error"}};function N(Q){if(!Q)return{label:"—",variant:"neutral"};return t[Q]??{label:Q,variant:"neutral"}}var c={"1":{label:"New",variant:"info"},"2":{label:"Waiting on us",variant:"warn"},"3":{label:"Waiting on them",variant:"neutral"},"4":{label:"Closed",variant:"success"}};function L(Q,J){if(!Q)return{label:J??"—",variant:"neutral"};let X=c[Q];if(X)return{label:J??X.label,variant:X.variant};return{label:J??Q,variant:"neutral"}}function U(Q){if(!Q)return"—";let J=new Date(Q);if(Number.isNaN(J.getTime()))return Q;let X=Math.round((Date.now()-J.getTime())/1000);if(X<60)return"just now";let Z=Math.round(X/60);if(Z<60)return`${Z}m ago`;let V=Math.round(Z/60);if(V<24)return`${V}h ago`;let $=Math.round(V/24);if($<7)return`${$}d ago`;let D=Math.round($/7);if(D<5)return`${D}w ago`;return J.toLocaleDateString("en-US",{month:"short",day:"numeric"})}function E(Q){let J=new Date;return J.setHours(J.getHours()-Q),J.toISOString()}var n="0";function y(Q,J,X){return`https://app.hubspot.com/contacts/${X||n}/${Q}/${J}`}function z(Q,J=32){if(!Q)return;return`https://www.google.com/s2/favicons?domain=${encodeURIComponent(Q)}&sz=${J}`}function b(Q){switch(Q){case"success":return"live";case"info":return"active";case"warn":return"warn";case"error":return"error";default:return"muted"}}var e=o("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:[B("circle",{cx:"18",cy:"6",r:"2.2"}),B("circle",{cx:"18",cy:"18",r:"2.2"}),B("circle",{cx:"6",cy:"12",r:"2.2"}),B("circle",{cx:"14",cy:"12",r:"3",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),B("path",{d:"M8.2 12 L11 12 M16 7.5 L15 10.2 M16 16.5 L15 13.8",stroke:"currentColor",strokeWidth:"1.2",fill:"none"})]}),i="#FF7A59",C={name:"HubSpot",logo:e,color:i};import{jsx as q,jsxs as G}from"react/jsx-runtime";var XJ={ticket_id:"20100",subject:"Slow API response times — affecting overnight runs",content:"Acme reports API p95 latency above 4s for 10 days. Two follow-ups, no resolution.",hs_ticket_priority:"HIGH",hs_pipeline_stage:"2",createdate:E(240),hs_lastmodifieddate:E(36),company_name:"Acme Logistics",company_domain:"acme-logistics.com",comment_count:4,portal_id:"0"};function ZJ(Q){let J=Q.preview?{...XJ,...Q}:Q,X=N(J.hs_ticket_priority),Z=L(J.hs_pipeline_stage,J.stage_label),V=y("ticket",J.ticket_id,J.portal_id);return G(s,{children:[q(JJ,{vendor:C,title:J.subject||`Ticket ${J.ticket_id}`,subtitle:J.company_name,status:{label:X.label,variant:b(X.variant)},action:{label:"View in HubSpot",href:V}}),G("div",{className:"px-3 py-3 flex flex-col gap-3",children:[G("div",{className:"flex items-center gap-2 flex-wrap",children:[G(x,{variant:X.variant,children:[X.label," priority"]}),q(x,{variant:Z.variant,children:Z.label}),J.comment_count!==void 0&&J.comment_count>0&&G("span",{className:"text-[11px] text-text-dim inline-flex items-center gap-1",children:[q(Y,{className:"w-3 h-3"}),J.comment_count]})]}),J.content&&q("div",{className:"text-xs text-text-muted line-clamp-3 border-l-2 border-border pl-2",children:J.content}),q(QJ,{items:[...J.company_name?[{label:"Company",value:G("span",{className:"inline-flex items-center gap-1.5",children:[J.company_domain&&q("img",{src:z(J.company_domain),alt:"",width:12,height:12,className:"rounded-sm"}),q("span",{className:"text-text",children:J.company_name})]})}]:[],...J.createdate?[{label:"Opened",value:U(J.createdate)}]:[],...J.hs_lastmodifieddate?[{label:"Updated",value:U(J.hs_lastmodifieddate)}]:[]]})]})]})}export{ZJ as default};
2
+
3
+ //# debugId=5F43CC55406576EC64756E2164756E21