From ca2ef6d65df26a408f44fda527b2d73cf79b1056 Mon Sep 17 00:00:00 2001 From: Mat Jordan Date: Wed, 4 Dec 2024 09:59:19 -0500 Subject: [PATCH] Add AI `expires` value to local storage. --- components/Header/Super.tsx | 5 +++-- hooks/useGenerativeAISearchToggle.ts | 19 ++++++++++++++----- hooks/useLocalStorage.ts | 2 +- pages/_app.tsx | 8 ++++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/components/Header/Super.tsx b/components/Header/Super.tsx index dcafb641..75951330 100644 --- a/components/Header/Super.tsx +++ b/components/Header/Super.tsx @@ -15,6 +15,7 @@ import { NavResponsiveOnly } from "@/components/Nav/Nav.styled"; import { NorthwesternWordmark } from "@/components/Shared/SVG/Northwestern"; import React from "react"; import { UserContext } from "@/context/user-context"; +import { defaultAIState } from "@/hooks/useGenerativeAISearchToggle"; import useLocalStorage from "@/hooks/useLocalStorage"; const nav = [ @@ -35,7 +36,7 @@ const nav = [ export default function HeaderSuper() { const [isLoaded, setIsLoaded] = React.useState(false); const [isExpanded, setIsExpanded] = React.useState(false); - const [ai, setAI] = useLocalStorage("ai", "false"); + const [ai, setAI] = useLocalStorage("ai", defaultAIState); React.useEffect(() => { setIsLoaded(true); @@ -45,7 +46,7 @@ export default function HeaderSuper() { const handleMenu = () => setIsExpanded(!isExpanded); const handleLogout = () => { - if (ai === "true") setAI("false"); + if (ai.enabled === "true") setAI(defaultAIState); window.location.href = `${DCAPI_ENDPOINT}/auth/logout`; }; diff --git a/hooks/useGenerativeAISearchToggle.ts b/hooks/useGenerativeAISearchToggle.ts index 0c4f4445..b0fb7bb7 100644 --- a/hooks/useGenerativeAISearchToggle.ts +++ b/hooks/useGenerativeAISearchToggle.ts @@ -5,7 +5,12 @@ import { UserContext } from "@/context/user-context"; import useLocalStorage from "@/hooks/useLocalStorage"; import { useRouter } from "next/router"; -const defaultModalState = { +export const defaultAIState = { + enabled: "false", + expires: undefined, +}; + +export const defaultModalState = { isOpen: false, title: "Use Generative AI", }; @@ -13,12 +18,13 @@ const defaultModalState = { export default function useGenerativeAISearchToggle() { const router = useRouter(); - const [ai, setAI] = useLocalStorage("ai", "false"); + const [ai, setAI] = useLocalStorage("ai", defaultAIState); const { user } = React.useContext(UserContext); const [dialog, setDialog] = useState(defaultModalState); - const isAIPreference = ai === "true"; + const expires = Date.now() + 1000 * 60 * 1; + const isAIPreference = ai.enabled === "true"; const isChecked = isAIPreference && user?.isLoggedIn; const loginUrl = `${DCAPI_ENDPOINT}/auth/login?goto=${goToLocation()}`; @@ -36,7 +42,7 @@ export default function useGenerativeAISearchToggle() { if (router.isReady) { const { query } = router; if (query.ai === "true") { - setAI("true"); + setAI({ enabled: "true", expires }); } } }, [router.asPath]); @@ -61,7 +67,10 @@ export default function useGenerativeAISearchToggle() { if (!user?.isLoggedIn) { setDialog({ ...dialog, isOpen: checked }); } else { - setAI(checked ? "true" : "false"); + setAI({ + enabled: checked ? "true" : "false", + expires: checked ? expires : undefined, + }); } } diff --git a/hooks/useLocalStorage.ts b/hooks/useLocalStorage.ts index 5488a5b8..a4f79b10 100644 --- a/hooks/useLocalStorage.ts +++ b/hooks/useLocalStorage.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from "react"; -function useLocalStorage(key: string, initialValue: string) { +function useLocalStorage(key: string, initialValue: any) { // Get the initial value from localStorage or use the provided initialValue const [storedValue, setStoredValue] = useState(() => { if (typeof window !== "undefined") { diff --git a/pages/_app.tsx b/pages/_app.tsx index e2bba277..ef8f731d 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -16,6 +16,7 @@ import React from "react"; import { SearchProvider } from "@/context/search-context"; import { User } from "@/types/context/user"; import { UserProvider } from "@/context/user-context"; +import { defaultAIState } from "@/hooks/useGenerativeAISearchToggle"; import { defaultOpenGraphData } from "@/lib/open-graph"; import { getUser } from "@/lib/user-helpers"; import globalStyles from "@/styles/global"; @@ -37,8 +38,8 @@ function MyApp({ Component, pageProps }: MyAppProps) { const [mounted, setMounted] = React.useState(false); const [user, setUser] = React.useState(); - const [ai] = useLocalStorage("ai", "false"); - const isUsingAI = ai === "true"; + const [ai, setAI] = useLocalStorage("ai", defaultAIState); + const isUsingAI = ai?.enabled === "true"; React.useEffect(() => { async function getData() { @@ -47,6 +48,9 @@ function MyApp({ Component, pageProps }: MyAppProps) { setMounted(true); } getData(); + + // Check if AI is enabled and if it has expired + if (ai?.expires && ai.expires < Date.now()) setAI(defaultAIState); }, []); React.useEffect(() => {