From 9b860ee3c05836c6e58447f7a554b1461f36f6b1 Mon Sep 17 00:00:00 2001 From: Josh Berman Date: Mon, 21 Sep 2026 15:32:56 +1000 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20Turn=20the=20admin=20link=20into?= =?UTF-8?q?=20an=20orange=20Edit=20button=20with=20the=20Tina=20llama?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- src/app/docs-layout.tsx | 2 - src/components/docs/layout/top-nav.tsx | 2 + src/components/icons/tina-icon.svg | 12 ------ src/components/icons/tina-icon.tsx | 13 ++++++ src/components/ui/admin-link.tsx | 59 ++++++++++++-------------- 5 files changed, 43 insertions(+), 45 deletions(-) delete mode 100644 src/components/icons/tina-icon.svg create mode 100644 src/components/icons/tina-icon.tsx diff --git a/src/app/docs-layout.tsx b/src/app/docs-layout.tsx index 8818544f..31996c42 100644 --- a/src/app/docs-layout.tsx +++ b/src/app/docs-layout.tsx @@ -1,5 +1,4 @@ import "@/styles/global.css"; -import AdminLink from "@/components/ui/admin-link"; import { TailwindIndicator } from "@/components/ui/tailwind-indicator"; import { ThemeSelector } from "@/components/ui/theme-selector"; import settings from "@/content/settings/config.json"; @@ -70,7 +69,6 @@ export function DocsLayout({ const Content = ({ children }: { children?: React.ReactNode }) => ( <> -
{children}
diff --git a/src/components/docs/layout/top-nav.tsx b/src/components/docs/layout/top-nav.tsx index 52557abd..8b2b452b 100644 --- a/src/components/docs/layout/top-nav.tsx +++ b/src/components/docs/layout/top-nav.tsx @@ -2,6 +2,7 @@ import { MobileNavSidebar } from "@/components/navigation/mobile-navigation-side import * as Tabs from "@radix-ui/react-tabs"; import type React from "react"; import { Search } from "../../search-docs/search"; +import AdminLink from "../../ui/admin-link"; import LightDarkSwitch from "../../ui/light-dark-switch"; import { CtaButton } from "./cta-button"; import { LanguageSwitcher } from "./language-switcher"; @@ -51,6 +52,7 @@ export const TopNav = ({
+
diff --git a/src/components/icons/tina-icon.svg b/src/components/icons/tina-icon.svg deleted file mode 100644 index b02b7bfa..00000000 --- a/src/components/icons/tina-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - Tina - A proud llama - - - \ No newline at end of file diff --git a/src/components/icons/tina-icon.tsx b/src/components/icons/tina-icon.tsx new file mode 100644 index 00000000..18eab0a1 --- /dev/null +++ b/src/components/icons/tina-icon.tsx @@ -0,0 +1,13 @@ +export const TinaIcon = ({ className }: { className?: string }) => ( + + + + +); diff --git a/src/components/ui/admin-link.tsx b/src/components/ui/admin-link.tsx index b002f3c4..cb464870 100644 --- a/src/components/ui/admin-link.tsx +++ b/src/components/ui/admin-link.tsx @@ -1,46 +1,43 @@ "use client"; -import { XMarkIcon } from "@heroicons/react/24/outline"; -import React from "react"; -import { useEffect } from "react"; +import { TinaIcon } from "@/components/icons/tina-icon"; +import { useEffect, useState } from "react"; import { useEditState } from "tinacms/dist/react"; +const hasTinaSession = () => { + const raw = window.localStorage.getItem("tinacms-auth"); + if (!raw) return false; + try { + const auth: unknown = JSON.parse(raw); + return ( + typeof auth === "object" && + auth !== null && + "access_token" in auth && + Boolean(auth.access_token) + ); + } catch { + return false; + } +}; + const AdminLink = () => { const { edit } = useEditState(); - const [showAdminLink, setShowAdminLink] = React.useState(false); + const [showAdminLink, setShowAdminLink] = useState(false); useEffect(() => { - setShowAdminLink( - !edit && - JSON.parse((window.localStorage.getItem("tinacms-auth") as any) || "{}") - ?.access_token - ); + setShowAdminLink(!edit && hasTinaSession()); }, [edit]); - const handleDismiss = () => { - setShowAdminLink(false); - }; + if (!showAdminLink) return null; return ( - <> - {showAdminLink && ( -
- - Edit This Page - - -
- )} - + + + Edit ✏️ + ); };