Skip to content

Commit

Permalink
Replace config page global message with new scheduled summer message (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish authored Jan 8, 2025
1 parent 3fb0bca commit d86dd59
Show file tree
Hide file tree
Showing 9 changed files with 4,176 additions and 20,529 deletions.
9 changes: 3 additions & 6 deletions app/search/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {H1} from "@components/elements/headers"
import {getAlgoliaCredential} from "@lib/gql/gql-queries"
import AlgoliaSiteSearch from "@components/algolia/algolia-site-search"
import {IndexUiState} from "instantsearch.js/es/types/ui-state"

// https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
export const revalidate = false
export const dynamic = "force-static"

export const metadata = {
title: "Search",
Expand All @@ -15,18 +15,15 @@ export const metadata = {
noarchive: true,
},
}
const Page = async (props: {searchParams?: Promise<{[_key: string]: string}>}) => {
const searchParams = await props.searchParams
const Page = async () => {
const [appId, indexName, apiKey] = await getAlgoliaCredential()
const initialState: IndexUiState = {}
if (searchParams?.q) initialState.query = searchParams.q

return (
<div className="centered mt-32">
<H1>Search</H1>

{appId && indexName && apiKey && (
<AlgoliaSiteSearch appId={appId} searchIndex={indexName} searchApiKey={apiKey} initialUiState={initialState} />
<AlgoliaSiteSearch appId={appId} searchIndex={indexName} searchApiKey={apiKey} />
)}
<noscript>Please enable Javascript in your browser to view search results.</noscript>
</div>
Expand Down
46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,41 @@
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@mui/base": "5.0.0-beta.66",
"@next/third-parties": "15.1.0",
"@mui/base": "5.0.0-beta.68",
"@next/third-parties": "15.1.4",
"@tailwindcss/container-queries": "^0.1.1",
"@types/node": "^22.10.2",
"@types/react": "^19.0.1",
"@types/node": "^22.10.5",
"@types/react": "^19.0.4",
"@types/react-dom": "19.0.2",
"algoliasearch": "^5.17.0",
"algoliasearch": "^5.19.0",
"autoprefixer": "^10.4.20",
"clsx": "^2.1.1",
"decanter": "^7.3.0",
"drupal-jsonapi-params": "^2.3.2",
"graphql": "^16.9.0",
"graphql": "^16.10.0",
"graphql-request": "^7.1.2",
"graphql-tag": "^2.12.6",
"html-entities": "^2.5.2",
"html-react-parser": "^5.2.0",
"next": "15.1.0",
"html-react-parser": "^5.2.2",
"next": "^15.2.0-canary.1",
"postcss": "^8.4.49",
"qs": "^6.13.1",
"react": "19.0.0",
"react-cookiebot": "^1.0.10",
"react-dom": "19.0.0",
"react-error-boundary": "^4.1.2",
"react-focus-lock": "^2.13.2",
"react-instantsearch": "^7.13.9",
"react-instantsearch-nextjs": "^0.3.20",
"react-slick": "^0.30.2",
"react-super-responsive-table": "^6.0.0",
"react-error-boundary": "^5.0.0",
"react-focus-lock": "^2.13.5",
"react-instantsearch": "^7.13.10",
"react-instantsearch-nextjs": "^0.3.21",
"react-slick": "^0.30.3",
"react-super-responsive-table": "^6.0.1",
"react-tiny-oembed": "^1.1.0",
"react-youtube": "^10.1.0",
"react-zendesk": "^0.1.13",
"sharp": "^0.33.5",
"tailwind-merge": "^2.5.5",
"tailwindcss": "^3.4.16",
"typescript": "^5.7.2",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.3",
"usehooks-ts": "^3.1.0"
},
"devDependencies": {
Expand All @@ -58,7 +58,7 @@
"@graphql-codegen/import-types-preset": "^3.0.0",
"@graphql-codegen/typescript-graphql-request": "^6.2.0",
"@graphql-codegen/typescript-operations": "^4.4.0",
"@next/bundle-analyzer": "15.1.0",
"@next/bundle-analyzer": "15.1.4",
"@storybook/addon-essentials": "^8.4.7",
"@storybook/addon-interactions": "^8.4.7",
"@storybook/addon-links": "^8.4.7",
Expand All @@ -69,20 +69,20 @@
"@storybook/testing-library": "^0.2.2",
"@types/react-cookiebot": "^1.0.5",
"@types/react-slick": "^0.23.13",
"concurrently": "^9.1.0",
"concurrently": "^9.1.2",
"encoding": "^0.1.13",
"eslint": "^9.16.0",
"eslint-config-next": "15.1.0",
"eslint": "^9.17.0",
"eslint-config-next": "15.1.4",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-storybook": "^0.11.1",
"eslint-plugin-storybook": "^0.11.2",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.9",
"react-docgen": "^7.1.0",
"storybook": "^8.4.7",
"storybook-addon-module-mock": "^1.3.4",
"tsconfig-paths-webpack-plugin": "^4.2.0",
"typescript-eslint": "^8.18.0"
"typescript-eslint": "^8.19.1"
},
"packageManager": "[email protected]",
"resolutions": {
Expand Down
22 changes: 19 additions & 3 deletions src/components/algolia/algolia-site-search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {liteClient} from "algoliasearch/lite"
import {useHits, useSearchBox, usePagination} from "react-instantsearch"
import {InstantSearchNext} from "react-instantsearch-nextjs"
import {HTMLAttributes, useEffect, useLayoutEffect, useMemo, useRef} from "react"
import {HTMLAttributes, useEffect, useLayoutEffect, useMemo, useRef, useState} from "react"
import Button from "@components/elements/button"
import {useRouter, useSearchParams} from "next/navigation"
import {Hit as HitType} from "instantsearch.js"
Expand All @@ -13,6 +13,7 @@ import DefaultResult, {AlgoliaHit} from "@components/algolia/results/default"
import {H2} from "@components/elements/headers"
import {useBoolean} from "usehooks-ts"
import AlgoliaPager from "@components/algolia/algolia-pager"
import {ArrowPathIcon} from "@heroicons/react/16/solid"

type Props = {
appId: string
Expand All @@ -21,9 +22,20 @@ type Props = {
initialUiState?: IndexUiState
}

const AlgoliaSiteSearch = ({appId, searchIndex, searchApiKey, initialUiState = {}}: Props) => {
const AlgoliaSiteSearch = ({appId, searchIndex, searchApiKey}: Props) => {
const initialRender = useRef(true)
const searchClient = useMemo(() => liteClient(appId, searchApiKey), [appId, searchApiKey])
const [initialUiState, setInitialUiState] = useState<IndexUiState>({})

useEffect(() => {
if (!initialRender.current) return
initialRender.current = false
const searchParams = new URLSearchParams(window.location.search)
const query = searchParams.get("q")
if (query) setInitialUiState({query})
}, [])

if (initialRender.current) return <ArrowPathIcon className="mx-auto animate-spin" width={50} />
return (
<div>
{/*@ts-expect-error React 19 types don't match with the library.*/}
Expand Down Expand Up @@ -139,7 +151,11 @@ const HitItem = ({
useLayoutEffect(() => {
if (focus) {
const reduceMotion = !!window.matchMedia("(prefers-reduced-motion: reduce)")?.matches
ref.current?.scrollIntoView({behavior: reduceMotion ? "instant" : "smooth", block: "end", inline: "nearest"})
ref.current?.scrollIntoView({
behavior: reduceMotion ? "instant" : "smooth",
block: "end",
inline: "nearest",
})
ref.current?.focus({preventScroll: true})
}
}, [focus])
Expand Down
21 changes: 21 additions & 0 deletions src/components/config-pages/global-message.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client"

import twMerge from "@lib/utils/twMergeConfig"
import {HTMLAttributes} from "react"
import {clsx} from "clsx"
import {usePathname} from "next/navigation"

type Props = HTMLAttributes<HTMLElement> & {
hidePaths?: Array<string>
}

const GlobalMessageClient = ({hidePaths, children, ...props}: Props) => {
const pathName = usePathname()
const hideOnPage = hidePaths?.includes(pathName)
return (
<article {...props} className={twMerge(props.className, clsx({hidden: hideOnPage}))}>
{children}
</article>
)
}
export default GlobalMessageClient
47 changes: 29 additions & 18 deletions src/components/config-pages/global-message.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,58 @@
import Wysiwyg from "@components/elements/wysiwyg"
import {StanfordGlobalMessage} from "@lib/gql/__generated__/drupal.d"
import {SummerGlobalMsg} from "@lib/gql/__generated__/drupal.d"
import ActionLink from "@components/elements/action-link"
import {twMerge} from "tailwind-merge"
import {HTMLAttributes} from "react"
import {getConfigPage} from "@lib/gql/gql-queries"
import {H2} from "@components/elements/headers"
import {unstable_cache as nextCache} from "next/cache"
import {graphqlClient} from "@lib/gql/gql-client"
import GlobalMessageClient from "@components/config-pages/global-message.client"

type Props = HTMLAttributes<HTMLElement> & {}

const GlobalMessage = async ({...props}: Props) => {
const globalMessageConfig = await getConfigPage<StanfordGlobalMessage>("StanfordGlobalMessage")
if (!globalMessageConfig?.suGlobalMsgEnabled) return
const getGlobalMessage = nextCache(
async (): Promise<SummerGlobalMsg | undefined> => {
const messages = await graphqlClient().GlobalMessages()
if (messages.summerGlobalMsgs.nodes?.[0]?.label) return messages.summerGlobalMsgs.nodes[0] as SummerGlobalMsg
},
[],
{tags: ["global-message"]}
)

const ElementWrapper = globalMessageConfig.suGlobalMsgHeader ? "article" : "div"
const GlobalMessage = async ({...props}: Props) => {
const globalMessageConfig = await getGlobalMessage()
if (!globalMessageConfig) return

return (
<ElementWrapper
<GlobalMessageClient
{...props}
className={twMerge("bg-fog-light", props.className)}
aria-labelledby={globalMessageConfig.suGlobalMsgHeader ? globalMessageConfig.id : undefined}
aria-labelledby={globalMessageConfig.id}
hidePaths={globalMessageConfig.sumGlobalMsgHide
?.replace(/\r/, "")
.split("\n")
.map(path => path.trim())}
>
<div className="md:centered">
<div className="flex w-full flex-col items-center justify-between gap-10 rounded-b-[25px] bg-illuminating-dark px-16 py-10 md:flex-row lg:w-3/4">
<div>
{globalMessageConfig.suGlobalMsgHeader && (
<H2 id={globalMessageConfig.id} className="mb-3 text-23">
{globalMessageConfig.suGlobalMsgHeader}
</H2>
)}
<Wysiwyg html={globalMessageConfig.suGlobalMsgMessage?.processed} />
<H2 id={globalMessageConfig.id} className="mb-3 text-23">
{globalMessageConfig.label}
</H2>
<Wysiwyg html={globalMessageConfig.sumGlobalMsgBody?.processed} />
</div>

{globalMessageConfig.suGlobalMsgLink?.url && (
{globalMessageConfig.sumGlobalMsgLink?.url && (
<ActionLink
href={globalMessageConfig.suGlobalMsgLink.url}
href={globalMessageConfig.sumGlobalMsgLink.url}
className="w-full max-w-fit text-black no-underline hocus:underline"
>
{globalMessageConfig.suGlobalMsgLink.title}
{globalMessageConfig.sumGlobalMsgLink.title}
</ActionLink>
)}
</div>
</div>
</ElementWrapper>
</GlobalMessageClient>
)
}

Expand Down
Loading

0 comments on commit d86dd59

Please sign in to comment.