diff --git a/plugins/hubspot/src/App.tsx b/plugins/hubspot/src/App.tsx index ebdf2d65e..e964c6076 100644 --- a/plugins/hubspot/src/App.tsx +++ b/plugins/hubspot/src/App.tsx @@ -41,15 +41,15 @@ const routes: Route[] = [ element: AccountPage, title: "Account", size: { - height: 197, + height: 204, }, }, { path: "/chat", element: ChatPage, - title: "Chat", + title: "Chats", size: { - height: 380, + height: 401, }, }, { @@ -71,14 +71,14 @@ const routes: Route[] = [ element: TrackingPage, title: "Tracking", size: { - height: 172, + height: 179, }, children: [ { path: "/learn-more", element: LearnMoreTrackingPage, size: { - height: 184, + height: 201, }, }, ], @@ -89,7 +89,7 @@ const routes: Route[] = [ path: "/cms", element: CMSMenuPage, size: { - height: 141, + height: 320, }, children: [ { @@ -103,7 +103,6 @@ const routes: Route[] = [ { path: "/hubdb", element: HubDBPage, - showTopDivider: false, size: { width: 320, height: 305, diff --git a/plugins/hubspot/src/components/Button.tsx b/plugins/hubspot/src/components/Button.tsx index 313ef979b..f407f323f 100644 --- a/plugins/hubspot/src/components/Button.tsx +++ b/plugins/hubspot/src/components/Button.tsx @@ -1,13 +1,16 @@ import cx from "classnames" -import { Spinner } from "./Spinner" interface Props extends React.ButtonHTMLAttributes { - variant?: "primary" | "secondary" | "destructive" + variant?: "primary" | "secondary" isLoading?: boolean } -export const Button = ({ variant = "primary", children, className, isLoading = false, disabled, ...rest }: Props) => ( - ) diff --git a/plugins/hubspot/src/components/CenteredSpinner.tsx b/plugins/hubspot/src/components/CenteredSpinner.tsx index 134ffdc18..65f639d96 100644 --- a/plugins/hubspot/src/components/CenteredSpinner.tsx +++ b/plugins/hubspot/src/components/CenteredSpinner.tsx @@ -1,8 +1,7 @@ import cx from "classnames" -import { Spinner, type SpinnerProps } from "./Spinner" -export const CenteredSpinner = ({ className, size }: { className?: string; size?: SpinnerProps["size"] }) => ( +export const CenteredSpinner = ({ className }: { className?: string }) => (
- +
) diff --git a/plugins/hubspot/src/components/CheckboxTextField.tsx b/plugins/hubspot/src/components/CheckboxTextField.tsx index 6f2fa4dfc..e3ba0e424 100644 --- a/plugins/hubspot/src/components/CheckboxTextField.tsx +++ b/plugins/hubspot/src/components/CheckboxTextField.tsx @@ -27,13 +27,7 @@ export function CheckboxTextfield({ value, disabled, checked: initialChecked, on onClick={toggle} role="button" > - + ( +
+ +
+
Welcome to HubSpot
+

{description}

+
+
+) diff --git a/plugins/hubspot/src/components/Icons.tsx b/plugins/hubspot/src/components/Icons.tsx index 6f1db2ec2..2eb7836ca 100644 --- a/plugins/hubspot/src/components/Icons.tsx +++ b/plugins/hubspot/src/components/Icons.tsx @@ -1,85 +1,265 @@ import cx from "classnames" +import { useIsPrerelease } from "../utils" -export const FormsIcon = () => ( - - - -) +export const FormsIcon = () => { + const isPrerelease = useIsPrerelease() -export const MeetingsIcon = () => ( - - - -) + return isPrerelease ? ( + + + + + ) : ( + + + + ) +} -export const ChartIcon = () => ( - - - -) +export const MeetingsIcon = () => { + const isPrerelease = useIsPrerelease() -export const PersonIcon = () => ( - - - -) + return isPrerelease ? ( + + + + + + + + + + ) : ( + + + + ) +} -export const MessageIcon = () => ( - - - - -) +export const ChartIcon = () => { + const isPrerelease = useIsPrerelease() -export const LightningIcon = () => ( - - - -) + return isPrerelease ? ( + + + + ) : ( + + + + ) +} + +export const PersonIcon = () => { + const isPrerelease = useIsPrerelease() + + return isPrerelease ? ( + + + + + ) : ( + + + + ) +} + +export const MessageIcon = () => { + const isPrerelease = useIsPrerelease() + + return isPrerelease ? ( + + + + ) : ( + + + + + ) +} + +export const LightningIcon = () => { + const isPrerelease = useIsPrerelease() + + return isPrerelease ? ( + + ) : ( + + + + ) +} export const CaretLeftIcon = () => ( - + ) -export const DatabaseIcon = () => ( - - - -) +export const DatabaseIcon = () => { + const isPrerelease = useIsPrerelease() + + return isPrerelease ? ( + + ) : ( + + + + ) +} export const IconChevron = ({ className }: { className?: string }) => ( ( -
-
-
-) - -interface TitleProps { - title: string - animateForward?: boolean - goBack: () => void -} - -const Title = ({ title, animateForward, goBack }: TitleProps) => ( - - -
-
- -
- -
{title}
-
-
-
-) - interface Props { children: React.ReactNode className?: string title?: string - animateForward?: boolean - showTopDivider?: boolean goBack: () => void } -export const Layout = ({ children, className, title, showTopDivider = true, animateForward, goBack }: Props) => ( +export const Layout = ({ children, className, title, goBack }: Props) => (
- {title && } - {showTopDivider && <PageDivider />} + {title && ( + <> + <div className="relative flex gap-[5px] items-center justify-center overflow-hidden min-h-[48px]"> + <div + onClick={goBack} + className="absolute left-0 flex items-center justify-center h-full w-10 cursor-pointer" + > + <CaretLeftIcon /> + </div> + <h6>{title}</h6> + </div> + <div className="px-[15px]"> + <hr /> + </div> + </> + )} <div className="col-lg w-full h-full">{children}</div> </div> ) diff --git a/plugins/hubspot/src/components/Logo.tsx b/plugins/hubspot/src/components/Logo.tsx index 47ba228f0..3527b80dc 100644 --- a/plugins/hubspot/src/components/Logo.tsx +++ b/plugins/hubspot/src/components/Logo.tsx @@ -1,5 +1,5 @@ export const Logo = () => ( - <div className="w-[30px] h-[30px] flex justify-center items-center bg-hs-orange rounded-lg"> + <div className="w-[30px] h-[30px] flex justify-center items-center bg-tint rounded-lg"> <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"> <path d="M 18.439 19.068 C 16.921 19.068 15.69 17.831 15.69 16.307 C 15.69 14.781 16.921 13.546 18.439 13.546 C 19.958 13.546 21.188 14.781 21.188 16.307 C 21.188 17.832 19.958 19.068 18.439 19.068 M 19.262 10.991 L 19.262 8.534 C 19.901 8.231 20.347 7.583 20.347 6.83 L 20.347 6.773 C 20.347 5.734 19.501 4.885 18.467 4.885 L 18.411 4.885 C 17.377 4.885 16.53 5.734 16.53 6.773 L 16.53 6.83 C 16.53 7.583 16.977 8.231 17.616 8.534 L 17.616 10.991 C 16.689 11.133 15.815 11.519 15.081 12.111 L 8.367 6.865 C 8.411 6.695 8.442 6.519 8.443 6.334 C 8.443 5.156 7.495 4.201 6.323 4.2 C 5.152 4.199 4.201 5.151 4.2 6.328 C 4.199 7.505 5.147 8.459 6.318 8.461 C 6.7 8.461 7.054 8.353 7.364 8.175 L 13.968 13.337 C 13.387 14.215 13.076 15.249 13.077 16.307 C 13.077 17.456 13.438 18.52 14.05 19.394 L 12.04 21.413 C 11.879 21.362 11.711 21.334 11.542 21.332 C 10.58 21.332 9.8 22.116 9.8 23.082 C 9.8 24.049 10.58 24.832 11.542 24.832 C 12.505 24.832 13.285 24.048 13.285 23.082 C 13.283 22.912 13.256 22.743 13.205 22.581 L 15.191 20.586 C 16.125 21.305 17.266 21.693 18.438 21.693 C 21.4 21.693 23.8 19.282 23.8 16.307 C 23.8 13.614 21.83 11.39 19.261 10.991" diff --git a/plugins/hubspot/src/components/MenuOption.tsx b/plugins/hubspot/src/components/MenuOption.tsx index 574694c62..df44e874e 100644 --- a/plugins/hubspot/src/components/MenuOption.tsx +++ b/plugins/hubspot/src/components/MenuOption.tsx @@ -1,5 +1,6 @@ import cx from "classnames" import { useLocation } from "wouter" +import { useIsPrerelease } from "../utils" interface Props { icon: React.ReactElement @@ -11,10 +12,15 @@ interface Props { export const MenuOption = ({ icon, title, to, className, onClick }: Props) => { const [, navigate] = useLocation() + const isPrerelease = useIsPrerelease() return ( <button - className={cx("h-[110px] w-full col items-center justify-center rounded-md", className)} + className={cx( + "h-[110px] w-full col items-center justify-center", + isPrerelease ? "text-secondary rounded-[10px] tile-border" : "text-tertiary rounded-md", + className + )} onClick={() => { if (onClick) { onClick() @@ -24,7 +30,7 @@ export const MenuOption = ({ icon, title, to, className, onClick }: Props) => { }} > {icon} - <p className="font-semibold text-tertiary">{title}</p> + <span className="font-semibold">{title}</span> </button> ) } diff --git a/plugins/hubspot/src/components/SegmentedControls.tsx b/plugins/hubspot/src/components/SegmentedControls.tsx index c4ada709b..a964d4688 100644 --- a/plugins/hubspot/src/components/SegmentedControls.tsx +++ b/plugins/hubspot/src/components/SegmentedControls.tsx @@ -20,15 +20,15 @@ export const SegmentedControls = ({ options, value, onValueChange, disabled, tit const segmentWidth = 130 / options.length return ( - <div className="relative bg-tertiary w-[134px] h-[32px] p-0.5 rounded-lg flex items-center justify-center gap-1 font-semibold text-xs select-none"> + <div className="relative bg-tertiary w-[134px] h-[30px] p-0.5 rounded-lg flex items-center justify-center font-semibold text-xs select-none"> <motion.div style={{ width: `${segmentWidth}px`, }} - className="absolute top-[2px] left-[2px] h-[28px] bg-white dark:bg-[#555555] rounded-md segment-control-shadow" + className="absolute top-[2px] left-[2px] h-[26px] bg-white dark:bg-[#474747] rounded-md segmented-control-shadow" initial={false} animate={{ x: `${selectedIndex * segmentWidth}px` }} - transition={{ type: "spring", stiffness: 700, damping: 50 }} + transition={{ type: "spring", duration: 0.2, bounce: 0 }} /> {options.map(option => ( <div @@ -40,11 +40,11 @@ export const SegmentedControls = ({ options, value, onValueChange, disabled, tit onValueChange(option.value) } } - className={cx("relative grow text-center z-10", { - "text-tint dark:text-white cursor-default": value === option.value, - "text-tertiary hover:text-tertiary cursor-pointer": value !== option.value, - "opacity-50": disabled, - })} + className={cx( + "relative flex-1 z-10 h-full flex items-center justify-center transition-colors duration-200", + value === option.value ? "text-tint dark:text-white" : "text-[#999]", + disabled ? "opacity-50 cursor-default" : "cursor-pointer" + )} title={title} > {option.label} diff --git a/plugins/hubspot/src/components/Spinner.tsx b/plugins/hubspot/src/components/Spinner.tsx deleted file mode 100644 index 594ad9d98..000000000 --- a/plugins/hubspot/src/components/Spinner.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import cx from "classnames" -import styles from "./spinner.module.css" - -export interface SpinnerProps { - /** Size of the spinner */ - size?: "normal" | "medium" | "large" - /** Set the spinner to have a static position inline with other content */ - inline?: boolean - className?: string - inheritColor?: boolean -} - -function styleForSize(size: SpinnerProps["size"]) { - switch (size) { - case "normal": - return styles.normalStyle - case "medium": - return styles.mediumStyle - case "large": - return styles.largeStyle - } -} - -function spinnerClassNames(size: SpinnerProps["size"] = "normal") { - return cx(styles.spin, styles.baseStyle, styleForSize(size)) -} - -export const Spinner = ({ size, inline = false, inheritColor, className, ...rest }: SpinnerProps) => { - return ( - <div - className={cx( - className, - spinnerClassNames(size), - inheritColor && styles.buttonWithDepthSpinner, - !inline && styles.centeredStyle - )} - {...rest} - /> - ) -} diff --git a/plugins/hubspot/src/components/spinner.module.css b/plugins/hubspot/src/components/spinner.module.css deleted file mode 100644 index a0d1a7ac3..000000000 --- a/plugins/hubspot/src/components/spinner.module.css +++ /dev/null @@ -1,60 +0,0 @@ -.baseStyle { - --spinner-translate: 0; - background-color: #fff; -} - -.buttonWithDepthSpinner { - background-color: currentColor; -} - -.normalStyle { - width: 12px; - height: 12px; - -webkit-mask: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAApNJREFUSA2tlUtLlFEYgEe7mtFFQ8NLFBG1SJAwahtiLVy5ceVSEPQH1LZf0Lp9FO1bdYNyI7gyBFcS2kAzilYq3sfxeYZ55Zv6FGfohWfOd97vnPd23u9MXeZoaeb1Q7gPHXAFzsAS5GACxiEPqVKXqs1kmtAPQi+cAtedToz1PJ8ExxPwDl7CAlRImoN7rBiF86ABHTiGAzMIh8n3O+ifwWc4EL0n5TGTYQijvjNSxbUadozInUeGZ3nuh1WYgpIkM+hGMwYajAgdrfUn+AaLoLTCAxiAOxCZxL4RdB+gZMjxEjwHo4hS8Jh5DR9hz0mKaNizegoNEI7Wee6FXJTISG6AUgDr+QImoAiHie+mwZJow/PRps4uwnsnRj8Epqc4voVJJ8eULOtW4BFYYjPpgjc+3IWI2sh/wFeoVl6xYQ48dDGLfjOwc/ygQqz595hUMVouS9QHBm4l6k3HWpnBLqicgVrlCxujSbR1Swd+UDpQYRS/oVaZZ2MWwlZBB9Zdxf+QTYw8SRgq6sAvz7vH6JULEB9USVHFjzZskgPRQR4ayxoXXIdaHdg9HrB2rErByWxZERnYtrWUzD0esDbtTmXPhzXwHrKLxEUbYGbVyDkWWwkdadfqbPmwDXZSCyh2VAf8BM/nOOJH5Y0QopMt2I5U/KO4DZZJB47XwEX+ex0mGroMV8sLwp56gyuGwiyW4SZ4c8bt2cZzO7jBNeqtsRHbeZ1g9krsMbhfYPv/c5gecA+4yAVuitFszE5Hjva872OMdXagF19JIoOYWyozMTI3J0tmA6gLvXPfO1cc/XOqOLe/HbjwD8yCXRD3VNJROEgatiRZMJsKsbZHia3nAdphtq8fkiWyXJbBe8uM1aXKPouNnz2Bm1kwAAAAAElFTkSuQmCC"); - mask: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAApNJREFUSA2tlUtLlFEYgEe7mtFFQ8NLFBG1SJAwahtiLVy5ceVSEPQH1LZf0Lp9FO1bdYNyI7gyBFcS2kAzilYq3sfxeYZ55Zv6FGfohWfOd97vnPd23u9MXeZoaeb1Q7gPHXAFzsAS5GACxiEPqVKXqs1kmtAPQi+cAtedToz1PJ8ExxPwDl7CAlRImoN7rBiF86ABHTiGAzMIh8n3O+ifwWc4EL0n5TGTYQijvjNSxbUadozInUeGZ3nuh1WYgpIkM+hGMwYajAgdrfUn+AaLoLTCAxiAOxCZxL4RdB+gZMjxEjwHo4hS8Jh5DR9hz0mKaNizegoNEI7Wee6FXJTISG6AUgDr+QImoAiHie+mwZJow/PRps4uwnsnRj8Epqc4voVJJ8eULOtW4BFYYjPpgjc+3IWI2sh/wFeoVl6xYQ48dDGLfjOwc/ygQqz595hUMVouS9QHBm4l6k3HWpnBLqicgVrlCxujSbR1Swd+UDpQYRS/oVaZZ2MWwlZBB9Zdxf+QTYw8SRgq6sAvz7vH6JULEB9USVHFjzZskgPRQR4ayxoXXIdaHdg9HrB2rErByWxZERnYtrWUzD0esDbtTmXPhzXwHrKLxEUbYGbVyDkWWwkdadfqbPmwDXZSCyh2VAf8BM/nOOJH5Y0QopMt2I5U/KO4DZZJB47XwEX+ex0mGroMV8sLwp56gyuGwiyW4SZ4c8bt2cZzO7jBNeqtsRHbeZ1g9krsMbhfYPv/c5gecA+4yAVuitFszE5Hjva872OMdXagF19JIoOYWyozMTI3J0tmA6gLvXPfO1cc/XOqOLe/HbjwD8yCXRD3VNJROEgatiRZMJsKsbZHia3nAdphtq8fkiWyXJbBe8uM1aXKPouNnz2Bm1kwAAAAAElFTkSuQmCC"); - -webkit-mask-size: 12px; - mask-size: 12px; -} - -.mediumStyle { - width: 24px; - height: 24px; - -webkit-mask: url("data:image/png;base64,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"); - mask: url("data:image/png;base64,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"); - -webkit-mask-size: 24px; - mask-size: 24px; -} - -.largeStyle { - width: 30px; - height: 30px; - -webkit-mask: url("data:image/png;base64,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"); - mask: url("data:image/png;base64,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"); - -webkit-mask-size: 30px; - mask-size: 30px; -} - -.centeredStyle { - --spinner-translate: -50%; - position: absolute; - top: 50%; - left: 50%; - transform: translate(var(--spinner-translate), var(--spinner-translate)); -} - -.spin { - animation-duration: 800ms; - animation-iteration-count: infinite; - animation-name: spin; - animation-timing-function: linear; -} - -@keyframes spin { - 0% { - transform: translate(var(--spinner-translate), var(--spinner-translate)) rotate(0deg); - } - - 100% { - transform: translate(var(--spinner-translate), var(--spinner-translate)) rotate(360deg); - } -} diff --git a/plugins/hubspot/src/globals.css b/plugins/hubspot/src/globals.css index aeab34fe7..abe791a3d 100644 --- a/plugins/hubspot/src/globals.css +++ b/plugins/hubspot/src/globals.css @@ -13,7 +13,6 @@ --background-color-tint-dimmed: var(--framer-color-tint-dimmed); --background-color-tint-dark: var(--framer-color-tint-dark); --background-color-black-dimmed: rgba(0, 0, 0, 0.5); - --background-color-hs-orange: #ff5c35; --background-color-framer-red: #ff3366; --background-color-framer-blue: #0099ff; @@ -22,7 +21,6 @@ --color-tertiary: var(--framer-color-text-tertiary); --color-inverted: var(--framer-color-text-inverted); --color-tint: var(--framer-color-tint); - --color-hs-orange: #ff5c35; --color-framer-red: #ff3366; --border-color-divider: var(--framer-color-divider); @@ -86,19 +84,19 @@ } @utility framer-button-destructive { - @apply bg-framer-red text-white; + @apply bg-framer-red/10 text-framer-red dark:bg-framer-red/15; &:hover { - background-color: #e15; + @apply bg-framer-red/15 dark:bg-framer-red/10; } &:focus { - background-color: #e15; + @apply bg-framer-red/15 dark:bg-framer-red/10; } } @utility input-container { - @apply row items-center justify-between pl-[15px] text-tertiary; + @apply row items-center justify-between pl-[15px] text-secondary; & > p { @apply max-w-[134px] truncate text-primary; @@ -109,10 +107,30 @@ @apply bg-tertiary-dimmed-light dark:bg-tertiary-dimmed-dark dark:hover:bg-tertiary hover:bg-tertiary; } -@utility segment-control-shadow { +[data-framer-theme="light"] .segmented-control-shadow { box-shadow: - 0px 2px 4px 0px rgba(0, 0, 0, 0.1), - 0px 1px 0px 0px rgba(0, 0, 0, 0.05); + 0px 0px 0px 1px rgba(0, 0, 0, 0.04), + 0px 1px 0px 0px rgba(0, 0, 0, 0.04), + 0px 2px 4px 0px rgba(0, 0, 0, 0.08); +} + +[data-framer-theme="dark"] .segmented-control-shadow { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.03); +} + +[data-framer-theme="dark"] .segmented-control-shadow::after { + content: ""; + position: absolute; + inset: 0px; + border-radius: 6px; + pointer-events: none; + box-shadow: inset 0 0 0 1px #ffffff0d; + mask-image: linear-gradient(to bottom, black 0%, transparent 100%); + --webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%); +} + +@utility tile-border { + box-shadow: inset 0 0 0 1px var(--color-tile-border); } @layer base { @@ -137,3 +155,31 @@ main { flex-direction: column; gap: 15px; } + +#root { + --framer-color-tint: #ff5c35; + --framer-color-tint-dark: #f25730; + --framer-color-tint-extra-dark: #e34e29; +} + +body { + --color-tile-border: rgba(0, 0, 0, 0.05); +} + +body[data-framer-theme="dark"] { + --color-tile-border: rgba(255, 255, 255, 0.07); +} + +[data-framer-theme="light"] .framer-button-primary { + --framer-color-tint: #111; + --framer-color-tint-dark: #333; + --framer-color-tint-extra-dark: #444; + --framer-color-text-reversed: #fff; +} + +[data-framer-theme="dark"] .framer-button-primary { + --framer-color-tint: #fff; + --framer-color-tint-dark: #ddd; + --framer-color-tint-extra-dark: #c5c5c5; + --framer-color-text-reversed: #000; +} diff --git a/plugins/hubspot/src/pages/Auth.tsx b/plugins/hubspot/src/pages/Auth.tsx index fc2b68acb..4577854de 100644 --- a/plugins/hubspot/src/pages/Auth.tsx +++ b/plugins/hubspot/src/pages/Auth.tsx @@ -64,7 +64,7 @@ export default function AuthPage() { </p> </div> </div> - <Button className="w-full" onClick={login} isLoading={isLoading} variant="secondary"> + <Button className="w-full" onClick={login} isLoading={isLoading}> Log In </Button> </main> diff --git a/plugins/hubspot/src/pages/canvas/Chat.tsx b/plugins/hubspot/src/pages/canvas/Chat.tsx index ae3820cd6..93165e777 100644 --- a/plugins/hubspot/src/pages/canvas/Chat.tsx +++ b/plugins/hubspot/src/pages/canvas/Chat.tsx @@ -74,6 +74,7 @@ export default function ChatPage() { <Link to="/canvas/tracking"> tracking </Link> is enabled. </p> + <hr /> <h6>Inboxes</h6> {inboxes.length > 0 ? ( inboxes.map((inbox, i) => ( @@ -95,53 +96,55 @@ export default function ChatPage() { )} <hr /> <h6>Settings</h6> - <div className="input-container"> - <label htmlFor="enableWidgetCookieBanner">Banner</label> - <select - name="enableWidgetCookieBanner" - id="enableWidgetCookieBanner" - value={JSON.stringify(settings.enableWidgetCookieBanner)} - onChange={value => { - setSettings({ - ...settings, - enableWidgetCookieBanner: v.parse( - EnableWidgetCookieBannerSchema, - JSON.parse(value.target.value) - ), - }) - }} - disabled={!isAllowedToSetCustomCode} - title={isAllowedToSetCustomCode ? undefined : "Insufficient permissions"} - className={isAllowedToSetCustomCode ? undefined : "opacity-50"} - > - <option value="true">Enabled</option> - <option value="false">Disabled</option> - {/* The double quotes are intentional, as these values are the output of JSON.stringify */} - <option value='"ON_EXIT_INTENT"'>On Exit Intent</option> - </select> - </div> - <div className="input-container"> - <label htmlFor="disableAttachment">Attachment</label> - <SegmentedControls - name="disableAttachment" - options={[ - { value: "false", label: "Show" }, - { value: "true", label: "Hide" }, - ]} - value={JSON.stringify(settings.disableAttachment)} - onValueChange={value => { - setSettings({ - ...settings, - disableAttachment: v.parse(DisableAttachmentSchema, JSON.parse(value)), - }) - }} - disabled={!isAllowedToSetCustomCode} - title={isAllowedToSetCustomCode ? undefined : "Insufficient permissions"} - /> + <div className="col"> + <div className="input-container"> + <label htmlFor="enableWidgetCookieBanner">Banner</label> + <select + name="enableWidgetCookieBanner" + id="enableWidgetCookieBanner" + value={JSON.stringify(settings.enableWidgetCookieBanner)} + onChange={value => { + setSettings({ + ...settings, + enableWidgetCookieBanner: v.parse( + EnableWidgetCookieBannerSchema, + JSON.parse(value.target.value) + ), + }) + }} + disabled={!isAllowedToSetCustomCode} + title={isAllowedToSetCustomCode ? undefined : "Insufficient permissions"} + className={isAllowedToSetCustomCode ? undefined : "opacity-50"} + > + <option value="true">Enabled</option> + <option value="false">Disabled</option> + {/* The double quotes are intentional, as these values are the output of JSON.stringify */} + <option value='"ON_EXIT_INTENT"'>On Exit Intent</option> + </select> + </div> + <div className="input-container"> + <label htmlFor="disableAttachment">Attachment</label> + <SegmentedControls + name="disableAttachment" + options={[ + { value: "false", label: "Show" }, + { value: "true", label: "Hide" }, + ]} + value={JSON.stringify(settings.disableAttachment)} + onValueChange={value => { + setSettings({ + ...settings, + disableAttachment: v.parse(DisableAttachmentSchema, JSON.parse(value)), + }) + }} + disabled={!isAllowedToSetCustomCode} + title={isAllowedToSetCustomCode ? undefined : "Insufficient permissions"} + /> + </div> </div> <hr /> <button - className="framer-button-primary w-full" + className="w-full" onClick={() => { window.open(`https://app-eu1.hubspot.com/chatflows/${account.portalId}/`, "_blank") }} diff --git a/plugins/hubspot/src/pages/canvas/Meetings.tsx b/plugins/hubspot/src/pages/canvas/Meetings.tsx index e63a91ce5..ac513da54 100644 --- a/plugins/hubspot/src/pages/canvas/Meetings.tsx +++ b/plugins/hubspot/src/pages/canvas/Meetings.tsx @@ -41,10 +41,7 @@ export default function MeetingsPage() { <div className="col-lg sticky top-0 left-0"> <hr /> - <button - className="framer-button-primary" - onClick={() => window.open(`https://${uiDomain}/meetings/${portalId}`, "_blank")} - > + <button onClick={() => window.open(`https://${uiDomain}/meetings/${portalId}`, "_blank")}> View Meetings </button> </div> diff --git a/plugins/hubspot/src/pages/canvas/Menu.tsx b/plugins/hubspot/src/pages/canvas/Menu.tsx index 0882e4d34..0250ee89a 100644 --- a/plugins/hubspot/src/pages/canvas/Menu.tsx +++ b/plugins/hubspot/src/pages/canvas/Menu.tsx @@ -3,8 +3,9 @@ import { framer } from "framer-plugin" import { useEffect } from "react" import { useLocation } from "wouter" import { useAccountQuery, useFormsQuery, useInboxesQuery, useMeetingsQuery, useUserQuery } from "../../api" +import { HeroSection } from "../../components/HeroSection" import { ChartIcon, FormsIcon, LightningIcon, MeetingsIcon, MessageIcon, PersonIcon } from "../../components/Icons" -import { Logo } from "../../components/Logo" +import { useIsPrerelease } from "../../utils" const queryHooks = { "/canvas/forms": { hook: useFormsQuery, shouldRefetch: true }, @@ -28,10 +29,15 @@ const MenuOption = ({ onClick?: () => void }) => { const [, navigate] = useLocation() + const isPrerelease = useIsPrerelease() return ( <button - className={cx("h-[110px] w-full col items-center justify-center rounded-md", className)} + className={cx( + "h-[110px] w-full col items-center justify-center", + isPrerelease ? "text-secondary rounded-[10px] tile-border" : "text-tertiary rounded-md", + className + )} onClick={() => { if (onClick) { onClick() @@ -41,7 +47,7 @@ const MenuOption = ({ }} > {icon} - <p className="font-semibold text-tertiary">{title}</p> + <span className="font-semibold">{title}</span> </button> ) } @@ -62,15 +68,7 @@ export default function MenuPage() { return ( <main> - <div className="col-lg items-center py-[30px]"> - <Logo /> - <div className="col items-center"> - <h6>Welcome to HubSpot</h6> - <p className="text-center text-tertiary max-w-[200px]"> - View forms, monitor site traffic, embed widgets and much more. - </p> - </div> - </div> + <HeroSection description="View forms, monitor site traffic, embed widgets and much more." /> <div className="grid grid-cols-2 gap-2.5"> <MenuOption title="Forms" to="/canvas/forms" icon={<FormsIcon />} /> <MenuOption title="Tracking" to="/canvas/tracking" icon={<ChartIcon />} /> diff --git a/plugins/hubspot/src/pages/canvas/forms/index.tsx b/plugins/hubspot/src/pages/canvas/forms/index.tsx index eb3f643d9..f71a3946e 100644 --- a/plugins/hubspot/src/pages/canvas/forms/index.tsx +++ b/plugins/hubspot/src/pages/canvas/forms/index.tsx @@ -47,10 +47,7 @@ export default function FormsPage() { <div className="col-lg sticky top-0 left-0 pb-[15px]"> <hr /> - <button - className="framer-button-primary" - onClick={() => window.open(`https://${uiDomain}/forms/${portalId}`, "_blank")} - > + <button onClick={() => window.open(`https://${uiDomain}/forms/${portalId}`, "_blank")}> View Forms </button> </div> diff --git a/plugins/hubspot/src/pages/cms/Blog.tsx b/plugins/hubspot/src/pages/cms/Blog.tsx index c191044f3..473f0d4c6 100644 --- a/plugins/hubspot/src/pages/cms/Blog.tsx +++ b/plugins/hubspot/src/pages/cms/Blog.tsx @@ -98,7 +98,6 @@ export default function Blog({ blogPluginContext }: PageProps) { /> <div className="sticky left-0 bottom-0 flex justify-between bg-primary pt-[15px] border-t border-divider items-center max-w-full"> <Button - variant="secondary" className="w-full" isLoading={isSyncing} disabled={!isAllowedToManage} diff --git a/plugins/hubspot/src/pages/cms/Menu.tsx b/plugins/hubspot/src/pages/cms/Menu.tsx index 7e77c8946..e4c209397 100644 --- a/plugins/hubspot/src/pages/cms/Menu.tsx +++ b/plugins/hubspot/src/pages/cms/Menu.tsx @@ -1,9 +1,11 @@ +import { HeroSection } from "../../components/HeroSection" import { DatabaseIcon, FormsIcon } from "../../components/Icons" import { MenuOption } from "../../components/MenuOption" export default function MenuPage() { return ( <div className="col-lg p-[15px]"> + <HeroSection description="Sync blog posts and HubDB tables to a CMS collection." /> <div className="grid grid-cols-2 gap-2.5"> <MenuOption title="Blog" to="/cms/blog" icon={<FormsIcon />} /> <MenuOption title="HubDB" to="/cms/hubdb" icon={<DatabaseIcon />} /> diff --git a/plugins/hubspot/src/pages/cms/hubdb/MapFields.tsx b/plugins/hubspot/src/pages/cms/hubdb/MapFields.tsx index 889c86348..653633f19 100644 --- a/plugins/hubspot/src/pages/cms/hubdb/MapFields.tsx +++ b/plugins/hubspot/src/pages/cms/hubdb/MapFields.tsx @@ -99,7 +99,7 @@ export default function MapHubDBFieldsPage({ hubDbPluginContext }: PageProps) { const isAllowedToManage = useIsAllowedTo("ManagedCollection.setFields", ...syncMethods) - if (isLoadingTable) return <CenteredSpinner size="medium" /> + if (isLoadingTable) return <CenteredSpinner /> if (!tableId) return <div>Expected `tableId` query param</div> @@ -150,7 +150,6 @@ export default function MapHubDBFieldsPage({ hubDbPluginContext }: PageProps) { /> <div className="sticky left-0 bottom-0 flex justify-between bg-primary pt-[15px] border-t border-divider items-center max-w-full"> <Button - variant="secondary" className="w-full" isLoading={isSyncing} disabled={!isAllowedToManage} diff --git a/plugins/hubspot/src/pages/cms/hubdb/index.tsx b/plugins/hubspot/src/pages/cms/hubdb/index.tsx index 58a27376a..992b2fc6e 100644 --- a/plugins/hubspot/src/pages/cms/hubdb/index.tsx +++ b/plugins/hubspot/src/pages/cms/hubdb/index.tsx @@ -31,7 +31,7 @@ export default function HubDBPage() { navigate(`/cms/hubdb/map?tableId=${selectedTableId}`) } - if (isLoading) return <CenteredSpinner size="medium" /> + if (isLoading) return <CenteredSpinner /> if (!tables) return null diff --git a/plugins/hubspot/src/router.tsx b/plugins/hubspot/src/router.tsx index a5200872c..070cf4948 100644 --- a/plugins/hubspot/src/router.tsx +++ b/plugins/hubspot/src/router.tsx @@ -24,7 +24,6 @@ export interface Route { element: React.ComponentType<PageProps> title?: string | (() => string) children?: Route[] - showTopDivider?: boolean size?: PluginSize } @@ -38,7 +37,7 @@ interface UseRoutesProps extends PluginContexts { } const DEFAULT_PLUGIN_WIDTH = 260 -const DEFAULT_PLUGIN_HEIGHT = 345 +const DEFAULT_PLUGIN_HEIGHT = 352 function useRoutes({ routes, hubDbPluginContext, blogPluginContext }: UseRoutesProps) { const [location] = useLocation() @@ -87,7 +86,7 @@ function useRoutes({ routes, hubDbPluginContext, blogPluginContext }: UseRoutesP for (const { match, route } of matches) { const [isMatch, params] = match - const { title, showTopDivider, size, element: Element } = route + const { title, size, element: Element } = route if (!isMatch) continue @@ -117,7 +116,7 @@ function useRoutes({ routes, hubDbPluginContext, blogPluginContext }: UseRoutesP transition: { x: { ease: [0.25, 0.1, 0.25, 1], - duration: 0.3, + duration: 0.2, }, opacity: { duration: 0.2, @@ -128,12 +127,7 @@ function useRoutes({ routes, hubDbPluginContext, blogPluginContext }: UseRoutesP return { page: ( <motion.div {...(animationProps as MotionProps)} className="w-full h-full"> - <Layout - title={pageTitle} - animateForward={animationDirection === 1} - showTopDivider={showTopDivider} - goBack={goBack} - > + <Layout title={pageTitle} goBack={goBack}> <PageErrorBoundaryFallback> <Element params={params} @@ -178,18 +172,23 @@ export function Router({ routes, hubDbPluginContext, blogPluginContext }: Router useEffect(() => { void framer.showUI({ - width: size?.width ?? 260, - height: size?.height ?? 345, + width: size?.width ?? DEFAULT_PLUGIN_WIDTH, + height: size?.height ?? DEFAULT_PLUGIN_HEIGHT, }) }, [size]) return ( - <div className="relative w-full h-full overflow-hidden"> - <AnimatePresence> - <SizePreserver size={size} key={location.pathname}> - {cloneElement(page, { key: location.pathname })} - </SizePreserver> - </AnimatePresence> + <div className="relative flex flex-col w-full h-full overflow-hidden"> + <div className="px-[15px] shrink-0"> + <hr /> + </div> + <div className="relative flex-1 min-h-0 overflow-hidden"> + <AnimatePresence> + <SizePreserver size={size} key={location.pathname}> + {cloneElement(page, { key: location.pathname })} + </SizePreserver> + </AnimatePresence> + </div> </div> ) } diff --git a/plugins/hubspot/src/utils.ts b/plugins/hubspot/src/utils.ts index 534406ebc..10463c402 100644 --- a/plugins/hubspot/src/utils.ts +++ b/plugins/hubspot/src/utils.ts @@ -1,4 +1,5 @@ import type { ProtectedMethod } from "framer-plugin" +import { useMemo } from "react" export function assert(condition: unknown, ...msg: unknown[]): asserts condition { if (condition) return @@ -31,3 +32,7 @@ export const syncMethods = [ "ManagedCollection.addItems", "ManagedCollection.setPluginData", ] as const satisfies ProtectedMethod[] + +export const useIsPrerelease = () => { + return useMemo(() => document.body.getAttribute("data-framer-styles") === "prerelease", []) +}