From 16f96e0532b40b75eb0fe01e3d74118f8303d6cd Mon Sep 17 00:00:00 2001 From: Mike Decker Date: Tue, 9 Jul 2024 09:41:34 -0700 Subject: [PATCH] Add async and mock functionality to storybook and adjusted eslint --- .eslintrc.json | 23 +- .storybook/main.ts | 11 +- .storybook/preview.ts | 1 + .../config-pages/GlobalMessage.stories.tsx | 121 ++ .../config-pages/LocalFooter.stories.tsx | 146 +- .../config-pages/SuperFooter.stories.tsx | 54 +- app/@modal/default.tsx | 3 + app/api/draft/disable/route.tsx | 2 +- app/api/draft/route.tsx | 2 +- app/page.tsx | 10 +- package.json | 12 +- .../config-pages/global-message.tsx | 15 +- src/components/config-pages/local-footer.tsx | 62 +- src/components/config-pages/super-footer.tsx | 29 +- src/components/elements/select-list.tsx | 2 +- src/components/global/page-footer.tsx | 11 +- .../stanford-page/stanford-page-page.tsx | 20 +- .../events-filtered-list-view.tsx | 2 +- src/lib/drupal/get-taxonomy-tree.tsx | 25 - src/lib/hooks/useActiveTrail.tsx | 7 +- src/lib/hooks/useFocusOnRender.tsx | 5 +- src/lib/hooks/usePagination.tsx | 3 + src/styles/centered-container.tsx | 1 + yarn.lock | 1361 ++++------------- 24 files changed, 687 insertions(+), 1241 deletions(-) create mode 100644 .storybook/stories/config-pages/GlobalMessage.stories.tsx delete mode 100644 src/lib/drupal/get-taxonomy-tree.tsx diff --git a/.eslintrc.json b/.eslintrc.json index d5b655a7..746bb778 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,18 +7,37 @@ }, "extends": [ "next/core-web-vitals", + "plugin:jsdoc/recommended-typescript", "plugin:storybook/recommended", + "plugin:prettier/recommended", "plugin:deprecation/recommended" ], "rules": { + "prettier/prettier": "warn", "@typescript-eslint/no-unused-vars": "off", "unused-imports/no-unused-imports": "error", "unused-imports/no-unused-vars": [ "warn", { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } ], - "no-console": ["error", { "allow": ["warn"] }], - "quotes": ["error", "double"] + "no-console": ["error", { "allow": ["warn", "error"] }], + "quotes": ["error", "double"], + "jsdoc/require-returns": "off", + "jsdoc/tag-lines": [ + "warn", + "any", + { + "endLines":0, + "startLines":1 + } + ] + }, + "settings": { + "jsdoc": { + "tagNamePreference": { + "returns": "return" + } + } }, "plugins": ["unused-imports"], "ignorePatterns": ["**/__generated__/**/*"] diff --git a/.storybook/main.ts b/.storybook/main.ts index 227e8f62..917cd329 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,5 +1,4 @@ import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin"; -import path from "path"; import type {StorybookConfig} from "@storybook/nextjs"; const config: StorybookConfig = { @@ -11,6 +10,9 @@ const config: StorybookConfig = { }, }, }, + features: { + experimentalRSC: true, + }, typescript: { reactDocgen: 'react-docgen', check: false, @@ -23,9 +25,9 @@ const config: StorybookConfig = { "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions", - '@storybook/addon-styling', + "storybook-addon-module-mock", { - name: '@storybook/addon-styling', + name: '@storybook/addon-styling-webpack', options: { // Check out https://github.com/storybookjs/addon-styling/blob/main/docs/api.md // For more details on this addon's options. @@ -33,9 +35,6 @@ const config: StorybookConfig = { }, }, ], - docs: { - autodocs: "tag", - }, webpackFinal: async (config) => { if (config.resolve) config.resolve.plugins = [new TsconfigPathsPlugin()]; return config diff --git a/.storybook/preview.ts b/.storybook/preview.ts index fa0e2274..be70c86f 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -3,6 +3,7 @@ import '../src/styles/index.css'; import './storybook.css'; const preview: Preview = { + tags: ['autodocs'], parameters: { actions: { argTypesRegex: "^on[A-Z].*" }, controls: { diff --git a/.storybook/stories/config-pages/GlobalMessage.stories.tsx b/.storybook/stories/config-pages/GlobalMessage.stories.tsx new file mode 100644 index 00000000..e82d4cac --- /dev/null +++ b/.storybook/stories/config-pages/GlobalMessage.stories.tsx @@ -0,0 +1,121 @@ +import type {Meta, StoryObj} from "@storybook/react" +import GlobalMessage from "@components/config-pages/global-message" +import {ComponentProps} from "react" +import {Link, StanfordGlobalMessage, Text} from "@lib/gql/__generated__/drupal" +import {createMock} from "storybook-addon-module-mock" +import * as gql from "@lib/gql/gql-queries" + +type ComponentStoryProps = ComponentProps & { + messageText?: Text["processed"] + linkUrl?: Link["url"] + linkTitle?: Link["title"] +} + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Design/Config Pages/Global Message", + component: GlobalMessage, + tags: ["autodocs"], + argTypes: {}, +} + +export default meta +type Story = StoryObj + +const globalMessage = { + id: "message", + metatag: [], + suGlobalMsgEnabled: true, + suGlobalMsgHeader: "Global Message Header", + suGlobalMsgLabel: "Global Message Label", + suGlobalMsgMessage: { + processed: "

Erat euismod nunc ipsum morbi tincidunt accumsan bibendum elementum mi vel leo elit urna bibendum sit metus varius leo enim ex tristique amet elit interdum.

", + }, + suGlobalMsgType: "success", + suGlobalMsgLink: { + internal: false, + url: "https://localhost", + title: "Local Link", + }, +} satisfies StanfordGlobalMessage + +// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args +export const SuccessMessage: Story = { + render: ({linkUrl, linkTitle, messageText, ...args}) => { + return + }, + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve(globalMessage)) + return [mock] + }, + }, + }, +} + +export const ErrorMessage: Story = { + render: ({linkUrl, linkTitle, messageText, ...args}) => { + return + }, + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve({...globalMessage, suGlobalMsgType: "error"})) + return [mock] + }, + }, + }, +} + +export const InfoMessage: Story = { + render: ({linkUrl, linkTitle, messageText, ...args}) => { + return + }, + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve({...globalMessage, suGlobalMsgType: "info"})) + return [mock] + }, + }, + }, +} + +export const WarningMessage: Story = { + render: ({linkUrl, linkTitle, messageText, ...args}) => { + return + }, + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve({...globalMessage, suGlobalMsgType: "warning"})) + return [mock] + }, + }, + }, +} + +export const PlainMessage: Story = { + render: ({linkUrl, linkTitle, messageText, ...args}) => { + return + }, + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve({...globalMessage, suGlobalMsgType: "plain"})) + return [mock] + }, + }, + }, +} diff --git a/.storybook/stories/config-pages/LocalFooter.stories.tsx b/.storybook/stories/config-pages/LocalFooter.stories.tsx index 495d97cd..6e5415cd 100644 --- a/.storybook/stories/config-pages/LocalFooter.stories.tsx +++ b/.storybook/stories/config-pages/LocalFooter.stories.tsx @@ -1,81 +1,89 @@ -import type {Meta, StoryObj} from '@storybook/react'; - -import LocalFooter from "@components/config-pages/local-footer"; -import {ComponentProps} from "react"; +import type {Meta, StoryObj} from "@storybook/react" +import LocalFooter from "@components/config-pages/local-footer" +import {ComponentProps} from "react" +import {createMock} from "storybook-addon-module-mock" +import * as gql from "@lib/gql/gql-queries" +import {StanfordLocalFooter} from "@lib/gql/__generated__/drupal" type ComponentStoryProps = ComponentProps & {} // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: 'Design/Config Pages/Local Footer', + title: "Design/Config Pages/Local Footer", component: LocalFooter, - tags: ['autodocs'], - argTypes: { - suLocalFootLocOp: { - description: "Lockup Options", - options: ['a', 'b', 'd', 'e', 'h', 'i', 'm', 'o', 'p', 'r', 's', 't', 'none'], - control: {type: "select"} - }, - suFooterEnabled: {control: "boolean"} - } -}; + tags: ["autodocs"], + argTypes: {}, +} -export default meta; -type Story = StoryObj; +export default meta +type Story = StoryObj + +const localFooterConfig = { + id: "local-footer", + metatag: [], + suFooterEnabled: true, + suLocalFootAction: [ + {title: "Action link 1", url: "https://localhost", internal: false}, + {title: "Action link 2", url: "https://localhost", internal: false}, + ], + suLocalFootAddress: { + additionalName: "additional_name", + addressLine1: "address_line1", + addressLine2: "address_line2", + administrativeArea: "administrative_area", + country: {code: "country_code"}, + familyName: "family_name", + givenName: "given_name", + locality: "locality", + organization: "organization", + postalCode: "postal_code", + sortingCode: "sorting_code", + }, + suLocalFootFButton: "suLocalFoot_f_button", + suLocalFootFIntro: {processed: "suLocalFoot_f_intro"}, + suLocalFootFMethod: "suLocalFoot_f_method", + suLocalFootFUrl: {title: "Form Action url", url: "https://localhost", internal: false}, + suLocalFootLine1: "suLocalFoot_line_1", + suLocalFootLine2: "suLocalFoot_line_2", + suLocalFootLine3: "suLocalFoot_line_3", + suLocalFootLine4: "suLocalFoot_line_4", + suLocalFootLine5: "suLocalFoot_line_5", + suLocalFootLocImg: null, + suLocalFootLocLink: {title: "suLocalFoot_loc_link", url: "https://localhost", internal: false}, + suLocalFootPrCo: {processed: "suLocalFoot_pr_co"}, + suLocalFootPrimary: [ + {title: "Primary link 1", url: "https://localhost", internal: false}, + {title: "Primary link 2", url: "https://localhost", internal: false}, + ], + suLocalFootPrimeH: "suLocalFoot_prime_h", + suLocalFootSeCo: {processed: "suLocalFoot_se_co"}, + suLocalFootSecond: [ + {title: "Second Link 1", url: "https://localhost", internal: false}, + {title: "Second Link 2", url: "https://localhost", internal: false}, + ], + suLocalFootSecondH: "suLocalFoot_second_h", + suLocalFootSocial: [ + {title: "Facebook", url: "https://localhost", internal: false}, + {title: "YouTube", url: "https://localhost", internal: false}, + ], + suLocalFootSunetT: "suLocalFoot_sunet_t", + suLocalFootTr2Co: {processed: "suLocalFoot_tr2_co"}, + suLocalFootTrCo: {processed: "suLocalFoot_tr_co"}, + suLocalFootUseLoc: true, + suLocalFootUseLogo: true, + suLocalFootLocOp: "suLocalFoot_loc_op", +} satisfies StanfordLocalFooter // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args export const LocalFooterDisplay: Story = { - args: { - suFooterEnabled: true, - suLocalFootAction: [ - {title: "Action link 1", url: "https://localhost", internal: false}, - {title: "Action link 2", url: "https://localhost", internal: false} - ], - suLocalFootAddress: { - additionalName: "additional_name", - addressLine1: "address_line1", - addressLine2: "address_line2", - administrativeArea: "administrative_area", - country: {code: "country_code"}, - familyName: "family_name", - givenName: "given_name", - locality: "locality", - organization: "organization", - postalCode: "postal_code", - sortingCode: "sorting_code", + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve(localFooterConfig)) + return [mock] + }, }, - suLocalFootFButton: "suLocalFoot_f_button", - suLocalFootFIntro: {processed: "suLocalFoot_f_intro"}, - suLocalFootFMethod: "suLocalFoot_f_method", - suLocalFootFUrl: {title: "Form Action url", url: "https://localhost", internal: false}, - suLocalFootLine1: "suLocalFoot_line_1", - suLocalFootLine2: "suLocalFoot_line_2", - suLocalFootLine3: "suLocalFoot_line_3", - suLocalFootLine4: "suLocalFoot_line_4", - suLocalFootLine5: "suLocalFoot_line_5", - suLocalFootLocImg: null, - suLocalFootLocLink: {title: "suLocalFoot_loc_link", url: "https://localhost", internal: false}, - suLocalFootPrCo: {processed: "suLocalFoot_pr_co"}, - suLocalFootPrimary: [ - {title: "Primary link 1", url: "https://localhost", internal: false}, - {title: "Primary link 2", url: "https://localhost", internal: false} - ], - suLocalFootPrimeH: "suLocalFoot_prime_h", - suLocalFootSeCo: {processed: "suLocalFoot_se_co"}, - suLocalFootSecond: [ - {title: "Second Link 1", url: "https://localhost", internal: false}, - {title: "Second Link 2", url: "https://localhost", internal: false} - ], - suLocalFootSecondH: "suLocalFoot_second_h", - suLocalFootSocial: [ - {title: "Facebook", url: "https://localhost", internal: false}, - {title: "YouTube", url: "https://localhost", internal: false} - ], - suLocalFootSunetT: "suLocalFoot_sunet_t", - suLocalFootTr2Co: {processed: "suLocalFoot_tr2_co"}, - suLocalFootTrCo: {processed: "suLocalFoot_tr_co"}, - suLocalFootUseLoc: true, - suLocalFootUseLogo: true, - suLocalFootLocOp: "suLocalFoot_loc_op", }, -}; +} diff --git a/.storybook/stories/config-pages/SuperFooter.stories.tsx b/.storybook/stories/config-pages/SuperFooter.stories.tsx index 6e759c6e..21bab04a 100644 --- a/.storybook/stories/config-pages/SuperFooter.stories.tsx +++ b/.storybook/stories/config-pages/SuperFooter.stories.tsx @@ -1,7 +1,9 @@ -import type {Meta, StoryObj} from '@storybook/react'; -import SuperFooter from "@components/config-pages/super-footer"; -import {ComponentProps} from "react"; -import {Text} from "@lib/gql/__generated__/drupal"; +import type {Meta, StoryObj} from "@storybook/react" +import SuperFooter from "@components/config-pages/super-footer" +import {ComponentProps} from "react" +import {StanfordSuperFooter, Text} from "@lib/gql/__generated__/drupal" +import {createMock} from "storybook-addon-module-mock" +import * as gql from "@lib/gql/gql-queries" type ComponentStoryProps = ComponentProps & { footerHtml?: Text["processed"] @@ -9,28 +11,38 @@ type ComponentStoryProps = ComponentProps & { // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: 'Design/Config Pages/Super Footer', + title: "Design/Config Pages/Super Footer", component: SuperFooter, - tags: ['autodocs'], - argTypes: { - suSuperFootEnabled: {control: "boolean"} - } -}; + tags: ["autodocs"], + argTypes: {}, +} + +export default meta +type Story = StoryObj -export default meta; -type Story = StoryObj; +const superFooterConfig = { + id: "super-footer", + metatag: [], + suSuperFootEnabled: true, + suSuperFootIntranet: {title: "suSuperFoot_intranet", url: "http://localhost", internal: false}, + suSuperFootLink: [{title: "suSuperFoot_link", url: "http://localhost", internal: false}], + suSuperFootText: {processed: "suSuperFoot_text"}, + suSuperFootTitle: "suSuperFoot_title", +} satisfies StanfordSuperFooter // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args export const SuperFooterDisplay: Story = { render: ({footerHtml, ...args}) => { - if (footerHtml) args.suSuperFootText = {processed: footerHtml} - return + return }, - args: { - suSuperFootEnabled: true, - suSuperFootIntranet: {title: "suSuperFoot_intranet", url: "http://localhost", internal: false}, - suSuperFootLink: [{title: "suSuperFoot_link", url: "http://localhost", internal: false}], - footerHtml: "suSuperFoot_text", - suSuperFootTitle: "suSuperFoot_title", + args: {}, + parameters: { + moduleMock: { + mock: () => { + const mock = createMock(gql, "getConfigPage") + mock.mockReturnValue(Promise.resolve(superFooterConfig)) + return [mock] + }, + }, }, -}; +} diff --git a/app/@modal/default.tsx b/app/@modal/default.tsx index 86b9e9a3..c639d0dc 100644 --- a/app/@modal/default.tsx +++ b/app/@modal/default.tsx @@ -1,3 +1,6 @@ +/** + * Placeholder for modal functionality to work. + */ export default function Default() { return null } diff --git a/app/api/draft/disable/route.tsx b/app/api/draft/disable/route.tsx index 80816f0e..5abe1142 100644 --- a/app/api/draft/disable/route.tsx +++ b/app/api/draft/disable/route.tsx @@ -3,7 +3,7 @@ import {cookies} from "next/headers" export const revalidate = 0 -export async function GET() { +export const GET = async () => { cookies().delete("preview") return NextResponse.json({disabled: true}, {status: 200}) } diff --git a/app/api/draft/route.tsx b/app/api/draft/route.tsx index 510443bf..e3b80a9d 100644 --- a/app/api/draft/route.tsx +++ b/app/api/draft/route.tsx @@ -4,7 +4,7 @@ import {cookies} from "next/headers" export const revalidate = 0 -export async function GET(request: NextRequest) { +export const GET = async (request: NextRequest) => { const secret = request.nextUrl.searchParams.get("secret") const slug = request.nextUrl.searchParams.get("slug") diff --git a/app/page.tsx b/app/page.tsx index 137e6aa2..5abe09b2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -20,10 +20,12 @@ const Home = async () => { return (
{entity.suPageBanner?.__typename === "ParagraphStanfordBanner" && ( - +
+ +
)} {entity.suPageComponents && }
diff --git a/package.json b/package.json index 16e0c9da..c64fd60a 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,12 @@ "next": "^14.2.4", "next-drupal": "^1.6.0", "postcss": "^8.4.39", - "qs": "^6.12.2", + "qs": "^6.12.3", "react": "^18.3.1", "react-dom": "^18.3.1", "react-focus-lock": "^2.12.1", - "react-instantsearch": "^7.12.0", - "react-instantsearch-nextjs": "^0.3.5", + "react-instantsearch": "^7.12.1", + "react-instantsearch-nextjs": "^0.3.6", "react-slick": "^0.30.2", "react-tiny-oembed": "^1.1.0", "sharp": "^0.33.4", @@ -63,7 +63,7 @@ "@storybook/addon-essentials": "^8.1.11", "@storybook/addon-interactions": "^8.1.11", "@storybook/addon-links": "^8.1.11", - "@storybook/addon-styling": "^1.3.7", + "@storybook/addon-styling-webpack": "^1.0.0", "@storybook/blocks": "^8.1.11", "@storybook/nextjs": "^8.1.11", "@storybook/react": "^8.1.11", @@ -71,13 +71,17 @@ "@types/react-slick": "^0.23.13", "concurrently": "^8.2.2", "encoding": "^0.1.13", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-deprecation": "^3.0.0", + "eslint-plugin-jsdoc": "^48.5.2", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-storybook": "^0.8.0", "eslint-plugin-unused-imports": "^4.0.0", "prettier": "^3.3.2", "prettier-plugin-tailwindcss": "^0.6.5", "react-docgen": "^7.0.3", "storybook": "^8.1.11", + "storybook-addon-module-mock": "^1.3.0", "tsconfig-paths-webpack-plugin": "^4.1.0" }, "packageManager": "yarn@4.3.0" diff --git a/src/components/config-pages/global-message.tsx b/src/components/config-pages/global-message.tsx index c21f4bcd..ea397bdc 100644 --- a/src/components/config-pages/global-message.tsx +++ b/src/components/config-pages/global-message.tsx @@ -29,15 +29,24 @@ const GlobalMessage = async () => { {globalMessageConfig.suGlobalMsgLabel}: -
+
{globalMessageConfig.suGlobalMsgHeader &&

{globalMessageConfig.suGlobalMsgHeader}

} - + {globalMessageConfig.suGlobalMsgLink?.url && ( {globalMessageConfig.suGlobalMsgLink.title} diff --git a/src/components/config-pages/local-footer.tsx b/src/components/config-pages/local-footer.tsx index 6ab93c56..82891d79 100644 --- a/src/components/config-pages/local-footer.tsx +++ b/src/components/config-pages/local-footer.tsx @@ -14,30 +14,38 @@ import LockupP from "@components/elements/lockup/lockup-p" import LockupR from "@components/elements/lockup/lockup-r" import LockupS from "@components/elements/lockup/lockup-s" import LockupT from "@components/elements/lockup/lockup-t" -import {JSX} from "react" +import {HTMLAttributes, JSX} from "react" import {H2} from "@components/elements/headers" import TwitterIcon from "@components/elements/icons/TwitterIcon" import YoutubeIcon from "@components/elements/icons/YoutubeIcon" import FacebookIcon from "@components/elements/icons/FacebookIcon" import {Maybe, StanfordLocalFooter} from "@lib/gql/__generated__/drupal.d" import {buildUrl} from "@lib/drupal/utils" +import {getConfigPage} from "@lib/gql/gql-queries" +import {twMerge} from "tailwind-merge" -const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, suLocalFootLine1, suLocalFootLine2, suLocalFootLine3, suLocalFootLine4, suLocalFootLine5, suLocalFootLocImg, suLocalFootLocOp, suLocalFootPrCo, suLocalFootPrimary, suLocalFootPrimeH, suLocalFootSeCo, suLocalFootSecond, suLocalFootSecondH, suLocalFootSocial, suLocalFootTr2Co, suLocalFootTrCo, suLocalFootUseLoc, suLocalFootUseLogo}: StanfordLocalFooter) => { - if (!suFooterEnabled) return +type Props = HTMLAttributes + +const LocalFooter = async ({...props}: Props) => { + const localFooterConfig = await getConfigPage("StanfordLocalFooter") + if (!localFooterConfig?.suFooterEnabled) return const lockupProps = { - useDefault: suLocalFootUseLoc, - lockupOption: suLocalFootLocOp, - line1: suLocalFootLine1, - line2: suLocalFootLine2, - line3: suLocalFootLine3, - line4: suLocalFootLine4, - line5: suLocalFootLine5, - logoUrl: !suLocalFootUseLogo && suLocalFootLocImg?.url ? buildUrl(suLocalFootLocImg?.url).toString() : undefined, + useDefault: localFooterConfig.suLocalFootUseLoc, + lockupOption: localFooterConfig.suLocalFootLocOp, + line1: localFooterConfig.suLocalFootLine1, + line2: localFooterConfig.suLocalFootLine2, + line3: localFooterConfig.suLocalFootLine3, + line4: localFooterConfig.suLocalFootLine4, + line5: localFooterConfig.suLocalFootLine5, + logoUrl: !localFooterConfig.suLocalFootUseLogo && localFooterConfig.suLocalFootLocImg?.url ? buildUrl(localFooterConfig.suLocalFootLocImg?.url).toString() : undefined, } return ( -
+
@@ -45,11 +53,11 @@ const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, su
- {suLocalFootAddress &&
} + {localFooterConfig.suLocalFootAddress &&
} - {suLocalFootAction && ( + {localFooterConfig.suLocalFootAction && (
    - {suLocalFootAction.map((link, index) => { + {localFooterConfig.suLocalFootAction.map((link, index) => { if (!link.url) return return (
  • @@ -60,9 +68,9 @@ const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, su
)} - {suLocalFootSocial && ( + {localFooterConfig.suLocalFootSocial && (
    - {suLocalFootSocial.map((link, index) => { + {localFooterConfig.suLocalFootSocial.map((link, index) => { if (!link.url) return return (
  • @@ -76,14 +84,14 @@ const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, su
)} - +
- {suLocalFootPrimeH &&

{suLocalFootPrimeH}

} - {suLocalFootPrimary && ( + {localFooterConfig.suLocalFootPrimeH &&

{localFooterConfig.suLocalFootPrimeH}

} + {localFooterConfig.suLocalFootPrimary && (
    - {suLocalFootPrimary.map((link, index) => { + {localFooterConfig.suLocalFootPrimary.map((link, index) => { if (!link.url) return return (
  • @@ -93,15 +101,15 @@ const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, su })}
)} - +
- {suLocalFootSecondH &&

{suLocalFootSecondH}

} + {localFooterConfig.suLocalFootSecondH &&

{localFooterConfig.suLocalFootSecondH}

} - {suLocalFootSecond && ( + {localFooterConfig.suLocalFootSecond && (
    - {suLocalFootSecond.map((link, index) => { + {localFooterConfig.suLocalFootSecond.map((link, index) => { if (!link.url) return return (
  • @@ -112,10 +120,10 @@ const LocalFooter = ({suFooterEnabled, suLocalFootAction, suLocalFootAddress, su
)} - +
- +
diff --git a/src/components/config-pages/super-footer.tsx b/src/components/config-pages/super-footer.tsx index be6fc327..58d1fafe 100644 --- a/src/components/config-pages/super-footer.tsx +++ b/src/components/config-pages/super-footer.tsx @@ -3,24 +3,33 @@ import Link from "@components/elements/link" import {LockClosedIcon} from "@heroicons/react/24/outline" import {H2} from "@components/elements/headers" import {StanfordSuperFooter} from "@lib/gql/__generated__/drupal.d" +import {getConfigPage} from "@lib/gql/gql-queries" +import {HTMLAttributes} from "react" +import {twMerge} from "tailwind-merge" -const SuperFooter = ({suSuperFootEnabled, suSuperFootTitle, suSuperFootText, suSuperFootLink, suSuperFootIntranet}: StanfordSuperFooter) => { - if (!suSuperFootEnabled) return +type Props = HTMLAttributes + +const SuperFooter = async ({...props}: Props) => { + const superFooterConfig = await getConfigPage("StanfordSuperFooter") + if (!superFooterConfig?.suSuperFootEnabled) return return ( -
+
- {suSuperFootTitle &&

{suSuperFootTitle}

} + {superFooterConfig.suSuperFootTitle &&

{superFooterConfig.suSuperFootTitle}

} - +
- {suSuperFootLink && ( + {superFooterConfig.suSuperFootLink && ( <> - {suSuperFootLink.map((link, index) => { + {superFooterConfig.suSuperFootLink.map((link, index) => { if (!link.url) return return ( )} - {suSuperFootIntranet?.url && ( + {superFooterConfig.suSuperFootIntranet?.url && ( - {suSuperFootIntranet.title} + {superFooterConfig.suSuperFootIntranet.title} , options: Selec return selectedOption ? selectedOption.label : null } -function CustomOption(props: OptionProps) { +const CustomOption = (props: OptionProps) => { const {children, value, rootRef, disabled = false} = props const {getRootProps, highlighted, selected} = useOption({ rootRef: rootRef, diff --git a/src/components/global/page-footer.tsx b/src/components/global/page-footer.tsx index df8971ec..c47ae69a 100644 --- a/src/components/global/page-footer.tsx +++ b/src/components/global/page-footer.tsx @@ -1,19 +1,14 @@ import LocalFooter from "@components/config-pages/local-footer" import SuperFooter from "@components/config-pages/super-footer" -import {getConfigPage} from "@lib/gql/gql-queries" -import {StanfordLocalFooter, StanfordSuperFooter} from "@lib/gql/__generated__/drupal.d" import {HTMLAttributes} from "react" type Props = HTMLAttributes -const PageFooter = async ({...props}: Props) => { - const superFooterConfig = await getConfigPage("StanfordSuperFooter") - const localFooterConfig = await getConfigPage("StanfordLocalFooter") - +const PageFooter = ({...props}: Props) => { return (