From a7513d1eaef8e0dcfc9adef6eee86fe24c5e6a63 Mon Sep 17 00:00:00 2001 From: Isaac Roberts <119639439+madebyisaacr@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:31:57 -0500 Subject: [PATCH 1/5] Add CMS page to Hubspot plugin --- plugins/hubspot/package.json | 2 +- plugins/hubspot/src/App.tsx | 9 ++ plugins/hubspot/src/components/Icons.tsx | 9 -- plugins/hubspot/src/pages/canvas/CMS.tsx | 102 +++++++++++++++++++++ plugins/hubspot/src/pages/canvas/Menu.tsx | 10 +- plugins/hubspot/src/pages/canvas/index.tsx | 1 + yarn.lock | 4 +- 7 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 plugins/hubspot/src/pages/canvas/CMS.tsx diff --git a/plugins/hubspot/package.json b/plugins/hubspot/package.json index 69a5edada..49b388ca3 100644 --- a/plugins/hubspot/package.json +++ b/plugins/hubspot/package.json @@ -15,7 +15,7 @@ "dependencies": { "@tanstack/react-query": "^5.87.4", "classnames": "^2.5.1", - "framer-plugin": "^3.6.0", + "framer-plugin": "^3.10.2", "motion": "^12.23.12", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/plugins/hubspot/src/App.tsx b/plugins/hubspot/src/App.tsx index ebdf2d65e..271b3485c 100644 --- a/plugins/hubspot/src/App.tsx +++ b/plugins/hubspot/src/App.tsx @@ -9,6 +9,7 @@ import { AccountPage, CanvasMenuPage, ChatPage, + CMSPage, FormsInstallationPage, FormsPage, LearnMoreTrackingPage, @@ -83,6 +84,14 @@ const routes: Route[] = [ }, ], }, + { + path: "/cms", + element: CMSPage, + title: "CMS", + size: { + height: 345, + }, + }, ], }, { diff --git a/plugins/hubspot/src/components/Icons.tsx b/plugins/hubspot/src/components/Icons.tsx index 6f1db2ec2..a85674331 100644 --- a/plugins/hubspot/src/components/Icons.tsx +++ b/plugins/hubspot/src/components/Icons.tsx @@ -49,15 +49,6 @@ export const MessageIcon = () => ( ) -export const LightningIcon = () => ( - - - -) - export const CaretLeftIcon = () => ( ([]) + const [isLoading, setIsLoading] = useState(true) + const [isCreating, setIsCreating] = useState(false) + const isAllowedToCreateCollection = useIsAllowedTo("createManagedCollection") + + useEffect(() => { + const loadCollections = async () => { + try { + const allCollections = await framer.getCollections() + const thisPluginCollections = allCollections + .filter(collection => collection.managedBy === "thisPlugin") + .map(collection => ({ + id: collection.id, + name: collection.name, + })) + setCollections(thisPluginCollections) + } catch (error) { + console.error("Failed to load collections:", error) + framer.notify("Failed to load collections", { variant: "error" }) + } finally { + setIsLoading(false) + } + } + + void loadCollections() + }, []) + + const handleCollectionClick = async (collectionId: string) => { + try { + await framer.navigateTo(collectionId) + } catch (error) { + console.error("Failed to navigate to collection:", error) + framer.notify("Failed to open collection", { variant: "error" }) + } + } + + const handleCreateCollection = async () => { + if (!isAllowedToCreateCollection) { + framer.notify("You are not allowed to create collections", { variant: "error" }) + return + } + + try { + setIsCreating(true) + const collection = await framer.createManagedCollection("HubSpot") + framer.notify("Created a collection. Click Sync to sync data from HubSpot.") + await framer.navigateTo(collection.id) + } catch (error) { + console.error("Failed to create collection:", error) + framer.notify(`Failed to create collection: ${error instanceof Error ? error.message : "Unknown error"}`, { + variant: "error", + }) + } finally { + setIsCreating(false) + } + } + + if (isLoading) return + + return ( +
+ {collections.length > 0 ? ( + + {collections.map(collection => ( + + ))} + + ) : ( +
+

+ No HubSpot collections yet. Create one to get started. +

+
+ )} + +
+
+ +
+
+ ) +} diff --git a/plugins/hubspot/src/pages/canvas/Menu.tsx b/plugins/hubspot/src/pages/canvas/Menu.tsx index 5cda72f7b..e9391e63a 100644 --- a/plugins/hubspot/src/pages/canvas/Menu.tsx +++ b/plugins/hubspot/src/pages/canvas/Menu.tsx @@ -1,9 +1,8 @@ import cx from "classnames" -import { framer } from "framer-plugin" import { useEffect } from "react" import { useLocation } from "wouter" import { useAccountQuery, useFormsQuery, useInboxesQuery, useMeetingsQuery, useUserQuery } from "../../api" -import { ChartIcon, FormsIcon, LightningIcon, MeetingsIcon, MessageIcon, PersonIcon } from "../../components/Icons" +import { ChartIcon, DatabaseIcon, FormsIcon, MeetingsIcon, MessageIcon, PersonIcon } from "../../components/Icons" import { Logo } from "../../components/Logo" const queryHooks = { @@ -76,12 +75,7 @@ export default function MenuPage() { } /> } /> } className="gap-[7px]" /> - } - onClick={() => framer.notify("The events feature will be out soon", { variant: "info" })} - /> + } /> } /> diff --git a/plugins/hubspot/src/pages/canvas/index.tsx b/plugins/hubspot/src/pages/canvas/index.tsx index 8bf6165f8..76cfa892c 100644 --- a/plugins/hubspot/src/pages/canvas/index.tsx +++ b/plugins/hubspot/src/pages/canvas/index.tsx @@ -1,5 +1,6 @@ export { default as AccountPage } from "./Account" export { default as ChatPage } from "./Chat" +export { default as CMSPage } from "./CMS" export { default as FormsPage } from "./forms" export { default as FormsInstallationPage } from "./forms/installation" export { default as MeetingsPage } from "./Meetings" diff --git a/yarn.lock b/yarn.lock index f261d270e..90ab46583 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4573,7 +4573,7 @@ __metadata: languageName: node linkType: hard -"framer-plugin@npm:3.10.2": +"framer-plugin@npm:3.10.2, framer-plugin@npm:^3.10.2": version: 3.10.2 resolution: "framer-plugin@npm:3.10.2" peerDependencies: @@ -4899,7 +4899,7 @@ __metadata: "@types/react": "npm:^18.3.24" "@types/react-dom": "npm:^18.3.7" classnames: "npm:^2.5.1" - framer-plugin: "npm:^3.6.0" + framer-plugin: "npm:^3.10.2" motion: "npm:^12.23.12" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" From 9e0befe820a3f7d88c095201848832dfe41c716e Mon Sep 17 00:00:00 2001 From: Isaac Roberts <119639439+madebyisaacr@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:37:29 -0500 Subject: [PATCH 2/5] Fix duplicate names --- plugins/hubspot/src/pages/canvas/CMS.tsx | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/plugins/hubspot/src/pages/canvas/CMS.tsx b/plugins/hubspot/src/pages/canvas/CMS.tsx index f3230c686..9cb1df016 100644 --- a/plugins/hubspot/src/pages/canvas/CMS.tsx +++ b/plugins/hubspot/src/pages/canvas/CMS.tsx @@ -49,7 +49,8 @@ export default function CMSPage() { try { setIsCreating(true) - const collection = await framer.createManagedCollection("HubSpot") + const name = await findAvailableCollectionName("HubSpot") + const collection = await framer.createManagedCollection(name) framer.notify("Created a collection. Click Sync to sync data from HubSpot.") await framer.navigateTo(collection.id) } catch (error) { @@ -93,6 +94,7 @@ export default function CMSPage() { onClick={() => void handleCreateCollection()} isLoading={isCreating} disabled={!isAllowedToCreateCollection} + title={isAllowedToCreateCollection ? undefined : "Insufficient permissions"} > Create New Collection @@ -100,3 +102,23 @@ export default function CMSPage() { ) } + +async function findAvailableCollectionName(baseName: string): Promise { + const collections = await framer.getCollections() + const existingNames = new Set(collections.map(c => c.name)) + + // Check if base name is available + if (!existingNames.has(baseName)) { + return baseName + } + + // Try numbered variants: "HubSpot 2", "HubSpot 3", etc. + let counter = 2 + let candidateName = `${baseName} ${counter}` + while (existingNames.has(candidateName)) { + counter++ + candidateName = `${baseName} ${counter}` + } + + return candidateName +} From 794389a6bce3c0e74205f489a37dc276d247ba75 Mon Sep 17 00:00:00 2001 From: Isaac Roberts <119639439+madebyisaacr@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:43:08 -0500 Subject: [PATCH 3/5] Improve buttons --- plugins/hubspot/src/pages/canvas/CMS.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/hubspot/src/pages/canvas/CMS.tsx b/plugins/hubspot/src/pages/canvas/CMS.tsx index 9cb1df016..d7b6b7404 100644 --- a/plugins/hubspot/src/pages/canvas/CMS.tsx +++ b/plugins/hubspot/src/pages/canvas/CMS.tsx @@ -51,7 +51,7 @@ export default function CMSPage() { setIsCreating(true) const name = await findAvailableCollectionName("HubSpot") const collection = await framer.createManagedCollection(name) - framer.notify("Created a collection. Click Sync to sync data from HubSpot.") + framer.notify("Created a new collection. Click Sync to sync data from HubSpot.") await framer.navigateTo(collection.id) } catch (error) { console.error("Failed to create collection:", error) @@ -68,15 +68,15 @@ export default function CMSPage() { return (
{collections.length > 0 ? ( - + {collections.map(collection => ( - + {collection.name} +
))} ) : ( From ed59ecdd87d3be537b2dc78fdf435a79648b8f2c Mon Sep 17 00:00:00 2001 From: Isaac Roberts <119639439+madebyisaacr@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:49:52 -0500 Subject: [PATCH 4/5] Add collection icon --- plugins/hubspot/src/components/Icons.tsx | 9 +++++++++ plugins/hubspot/src/pages/canvas/CMS.tsx | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/hubspot/src/components/Icons.tsx b/plugins/hubspot/src/components/Icons.tsx index a85674331..55b81f38f 100644 --- a/plugins/hubspot/src/components/Icons.tsx +++ b/plugins/hubspot/src/components/Icons.tsx @@ -72,6 +72,15 @@ export const DatabaseIcon = () => ( ) +export const CMSCollectionIcon = () => ( + + + +) + export const IconChevron = ({ className }: { className?: string }) => ( (
void handleCollectionClick(collection.id)} > + {collection.name}
))} From 69ecba0e343eda2b7dbe523cef9509e409d10fb2 Mon Sep 17 00:00:00 2001 From: Isaac Roberts <119639439+madebyisaacr@users.noreply.github.com> Date: Mon, 19 Jan 2026 10:00:35 -0500 Subject: [PATCH 5/5] Update icon color --- plugins/hubspot/src/components/Icons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hubspot/src/components/Icons.tsx b/plugins/hubspot/src/components/Icons.tsx index 55b81f38f..d20d9368d 100644 --- a/plugins/hubspot/src/components/Icons.tsx +++ b/plugins/hubspot/src/components/Icons.tsx @@ -67,7 +67,7 @@ export const DatabaseIcon = () => ( )