diff --git a/job-tracker-ui/src/components/GoogleAuthCard.tsx b/job-tracker-ui/src/components/GoogleAuthCard.tsx index a4c5ac0..dc1e74d 100644 --- a/job-tracker-ui/src/components/GoogleAuthCard.tsx +++ b/job-tracker-ui/src/components/GoogleAuthCard.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useRef, useState } from "react"; -import { Box, Button, Paper, Typography } from "@mui/material"; +import { Box, Button, Chip, Paper, Typography } from "@mui/material"; import { api } from "../api"; import { clearAuthToken, decodeJwtPayload, getAuthToken, setAuthToken } from "../auth"; @@ -30,7 +30,7 @@ function loadGoogleScript(): Promise { if (window.google?.accounts?.id) return resolve(); const existing = document.getElementById("google-gsi"); if (existing) { - existing.addEventListener("load", () => resolve()); + existing.addEventListener("load", () => resolve(), { once: true }); return; } const s = document.createElement("script"); @@ -97,17 +97,20 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void }, [token, isRawGoogleToken, onSignedIn, toast]); useEffect(() => { - if (!clientId || !hostRef.current) return; + const host = hostRef.current; + if (!clientId || !host) return; + const shouldRenderButton = !token || isRawGoogleToken || (me?.provider === "local" && !me?.googleLink?.linked); + host.replaceChildren(); if (!shouldRenderButton) { - hostRef.current.innerHTML = ""; return; } + let active = true; void loadGoogleScript() .then(() => { - if (!window.google?.accounts?.id || !hostRef.current) return; - hostRef.current.innerHTML = ""; + if (!active || !window.google?.accounts?.id || !hostRef.current) return; + hostRef.current.replaceChildren(); window.google.accounts.id.initialize({ client_id: clientId, callback: async (resp: any) => { @@ -143,6 +146,11 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void }); }) .catch(() => toast("Google auth script failed to load.", "error")); + + return () => { + active = false; + host.replaceChildren(); + }; }, [clientId, me?.provider, me?.googleLink?.linked, onSignedIn, isRawGoogleToken, token, toast]); return ( @@ -159,6 +167,11 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void {clientId && ( + + + {me?.googleLink?.linkedAt ? : null} + + {!token ? ( Sign in with a Google account that has already been linked to your Job Tracker user.