Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
20 changes: 10 additions & 10 deletions plugins/google-sheets/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Google Sheets</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Google Sheets</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1 change: 0 additions & 1 deletion plugins/google-sheets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^6.0.0",
"react-intersection-observer": "^9.16.0",
"tailwindcss": "^4.1.13",
"valibot": "^1.1.0"
},
Expand Down
14 changes: 9 additions & 5 deletions plugins/google-sheets/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { framer } from "framer-plugin"
import { useEffect, useLayoutEffect, useState } from "react"
import auth from "./auth"
import { CenteredSpinner } from "./components/CenteredSpinner"
import { logSyncResult, PLUGIN_LOG_SYNC_KEY } from "./debug"
import { Authenticate } from "./pages/Authenticate"
import { MapSheetFieldsPage } from "./pages/MapSheetFields"
Expand Down Expand Up @@ -72,10 +71,9 @@ export function AuthenticatedApp({ pluginContext, setContext }: AuthenticatedApp

if (result.status === "success") {
framer.closePlugin("Synchronization successful")
return
}
},
onError: e => framer.notify(e.message, { variant: "error" }),
onError: e => framer.notify(e.message, { variant: "error", durationMs: Infinity }),
})

useEffect(() => {
Expand Down Expand Up @@ -142,7 +140,13 @@ export function AuthenticatedApp({ pluginContext, setContext }: AuthenticatedApp
)
}

if (isSheetPending) return <CenteredSpinner />
if (isSheetPending) {
return (
<main className="size-full flex items-center justify-center select-none">
<div className="framer-spinner" />
</main>
)
}

const [headerRow, ...rows] = sheet?.values ?? []
if (!headerRow) {
Expand Down Expand Up @@ -235,7 +239,7 @@ export function App({ pluginContext }: AppProps) {
<p className="text-content">
Your Google Account does not have access to the synced spreadsheet. Check your access and try again
or{" "}
<a href="#" className="text-sheets-green" onClick={() => void auth.logout()}>
<a href="#" onClick={() => void auth.logout()}>
log out
</a>{" "}
and try a different account.
Expand Down
30 changes: 0 additions & 30 deletions plugins/google-sheets/src/components/Button.tsx

This file was deleted.

7 changes: 0 additions & 7 deletions plugins/google-sheets/src/components/CenteredSpinner.tsx

This file was deleted.

16 changes: 6 additions & 10 deletions plugins/google-sheets/src/components/CheckboxTextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ export function CheckboxTextfield({ value, darken, checked, onChange, disabled }

return (
<div
className={cx("flex bg-tertiary rounded-lg items-center pl-[10px] select-none", {
"opacity-50": darken,
})}
className={cx(
"flex bg-tertiary rounded-lg items-center pl-[10px] select-none h-[30px] cursor-pointer",
darken && "opacity-50"
)}
onClick={disabled ? undefined : toggle}
role={disabled ? undefined : "button"}
>
Expand All @@ -32,15 +33,10 @@ export function CheckboxTextfield({ value, darken, checked, onChange, disabled }
onClick={e => {
e.stopPropagation()
}}
className="checked:bg-sheets-green! focus:ring-1 focus:ring-sheets-green checked:border-none dark:bg-[#777]! bg-[#CCC]!"
disabled={disabled}
className="cursor-pointer"
/>
<input
className="bg-transparent w-full shrink pointer-events-none select-none"
type="text"
disabled
value={value}
/>
<span className="w-full pl-2 text-primary">{value}</span>
</div>
)
}
2 changes: 1 addition & 1 deletion plugins/google-sheets/src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import hero from "../assets/hero.png"

export const Hero = () => (
<div className="min-h-[200px] flex items-center justify-center bg-[rgba(0,189,66,0.08)] rounded-[10px]">
<img src={hero} alt="Floating sheet" className="object-contain w-[160px] h-[160px]" />
<img src={hero} alt="Floating sheet" draggable={false} className="object-contain w-[160px] h-[160px]" />
</div>
)
40 changes: 0 additions & 40 deletions plugins/google-sheets/src/components/Spinner.tsx

This file was deleted.

60 changes: 0 additions & 60 deletions plugins/google-sheets/src/components/spinner.module.css

This file was deleted.

29 changes: 13 additions & 16 deletions plugins/google-sheets/src/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

@custom-variant dark (&:where([data-framer-theme="dark"], [data-framer-theme="dark"] *));

main {
--framer-color-tint: #00c43e;
--framer-color-tint-dark: #00b539;
--framer-color-tint-extra-dark: #00ab36;
Comment thread
madebyisaacr marked this conversation as resolved.
}

select:not(:disabled) {
cursor: pointer;
}

@theme inline {
--background-color-primary: var(--framer-color-bg);
--background-color-secondary: var(--framer-color-bg-secondary);
Expand All @@ -20,7 +30,6 @@
--color-tertiary: var(--framer-color-text-tertiary);
--color-inverted: var(--framer-color-text-inverted);
--color-content: #999;
--color-sheets-green: #00c43e;
--color-framer-red: #ff3366;

--border-color-divider: var(--framer-color-divider);
Expand Down Expand Up @@ -92,21 +101,9 @@
z-index: 10;
position: absolute;
left: 0;
bottom: 63px;

[data-framer-theme="light"] & {
background: linear-gradient(to bottom, transparent, white);
}

[data-framer-theme="dark"] & {
background: linear-gradient(180deg, rgba(18, 18, 18, 0) 0%, rgb(17, 17, 17) 97.8%);
}
}

@layer components {
[data-framer-theme="dark"] input[type="checkbox"]:checked {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiI+PHBhdGggZD0iTSAzIDYgTCA1IDggTCA5IDQiIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMmIyYjJiIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1kYXNoYXJyYXk9IiI+PC9wYXRoPjwvc3ZnPg==");
}
bottom: 61px;
background: linear-gradient(to bottom, transparent, var(--framer-color-bg));
pointer-events: none;
}

#root {
Expand Down
23 changes: 12 additions & 11 deletions plugins/google-sheets/src/pages/Authenticate.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { framer } from "framer-plugin"
import { useLayoutEffect, useRef, useState } from "react"
import auth from "../auth"
import { Button } from "../components/Button"
import { GoogleLogo } from "../components/GoogleLogo"
import { Hero } from "../components/Hero"
import { getPluginContext, type PluginContext } from "../sheets"
Expand Down Expand Up @@ -69,7 +68,7 @@ export function Authenticate({ onAuthenticated }: AuthenticationProps) {
}

return (
<div className="col-lg pb-[15px]">
<main className="col-lg pb-[15px] select-none">
<Hero />
<ol className="list-decimal list-inside space-y-2.5 marker:text-secondary *:text-content *:leading-none *:tracking-normal py-[7px]">
<li>
Expand All @@ -82,14 +81,16 @@ export function Authenticate({ onAuthenticated }: AuthenticationProps) {
<span className="pl-[10px]">Map the column fields to the CMS</span>
</li>
</ol>
<Button
variant="secondary"
onClick={login}
isLoading={isLoading}
className="w-full inline-flex gap-[8px] items-center"
>
<GoogleLogo /> <span className="relative">Sign In</span>
</Button>
</div>
{/* Don't disable button because we want to allow the user to reopen the log in page if they close it without finishing */}
<button onClick={login} className="flex flex-row gap-[8px]">
{isLoading ? (
<div className="framer-spinner" />
) : (
<>
<GoogleLogo /> Sign In
</>
)}
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Button Clicks Not Disabled During Loading

The "Sign In" button and the field mapping form's submit button lack a disabled prop when isLoading or isPending is true. This allows multiple clicks, which can lead to race conditions or duplicate operations.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Collaborator Author

@madebyisaacr madebyisaacr Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. If you close the Google sign in tab after it opens, it will still show as loading in the plugin, but you need to be able to open it again by clicking the same button. MapSheetFields handles this by checking isPending in handleSubmit, so clicking multiple times there isn't a problem.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding the explanation in a code comment? That helps the future you and all of us with a bit of added context

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment right above the button.

</main>
)
}
Loading
Loading