Skip to content

Commit

Permalink
feat: add api keys, globals, pages, other previewer updates
Browse files Browse the repository at this point in the history
  • Loading branch information
drewbo committed Feb 18, 2025
1 parent a733faa commit f73cfbc
Show file tree
Hide file tree
Showing 23 changed files with 608 additions and 512 deletions.
1 change: 1 addition & 0 deletions .cloudgov/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ applications:
SHARP_IGNORE_GLOBAL_LIBVIPS: true
OPTIMIZE_MEMORY: true
PUBLIC_URL: https://pages-editor-((env)).app.cloud.gov
PREVIEW_URL: https://pages-editor-preview-((env)).app.cloud.gov
health-check-type: http
health-check-http-endpoint: /admin
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ public/media/
public/robots.txt
public/sitemap*.xml

# payload-types should be dynamically generated for now
# src/payload-types.ts
# payload-types should be dynamically generated
src/payload-types.ts
1 change: 0 additions & 1 deletion .profile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export PAYLOAD_SECRET="$(echo "$VCAP_SERVICES" | jq --raw-output --arg service_n
export OAUTH_CLIENT_ID="$(echo "$VCAP_SERVICES" | jq --raw-output --arg service_name "pages-editor-creds" ".[][] | select(.name == \$service_name) | .credentials.OAUTH_CLIENT_ID")"
export OAUTH_CLIENT_SECRET="$(echo "$VCAP_SERVICES" | jq --raw-output --arg service_name "pages-editor-creds" ".[][] | select(.name == \$service_name) | .credentials.OAUTH_CLIENT_SECRET")"
export PREVIEW_URL="$(echo "$VCAP_SERVICES" | jq --raw-output --arg service_name "pages-editor-creds" ".[][] | select(.name == \$service_name) | .credentials.PREVIEW_URL")"
export PROMPT_URL="$(echo "$VCAP_SERVICES" | jq --raw-output --arg service_name "pages-editor-creds" ".[][] | select(.name == \$service_name) | .credentials.PROMPT_URL")"
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"lucide-react": "^0.378.0",
"next": "^15.0.3",
"next-sitemap": "^4.2.3",
"p-debounce": "^4.0.0",
"payload": "latest",
"payload-admin-bar": "^1.0.6",
"payload-oauth2": "^1.0.9",
Expand Down
34 changes: 34 additions & 0 deletions src/Footer/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { getCachedGlobal } from '@/utilities/getGlobals'
import Link from 'next/link'
import React from 'react'

import type { Footer } from '@/payload-types'

import { ThemeSelector } from '@/providers/Theme/ThemeSelector'
import { CMSLink } from '@/components/Link'
import { Logo } from '@/components/Logo/Logo'

export async function Footer() {
const footerData: Footer = await getCachedGlobal('footer', 1)()

const navItems = footerData?.navItems || []

return (
<footer className="mt-auto border-t border-border bg-black dark:bg-card text-white">
<div className="container py-8 gap-8 flex flex-col md:flex-row md:justify-between">
<Link className="flex items-center" href="/">
<Logo />
</Link>

<div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center">
<ThemeSelector />
<nav className="flex flex-col md:flex-row gap-4">
{navItems.map(({ link }, i) => {
return <CMSLink className="text-white" key={i} {...link} />
})}
</nav>
</div>
</div>
</footer>
)
}
13 changes: 13 additions & 0 deletions src/Footer/RowLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'
import { Header } from '@/payload-types'
import { RowLabelProps, useRowLabel } from '@payloadcms/ui'

export const RowLabel: React.FC<RowLabelProps> = () => {
const data = useRowLabel<NonNullable<Header['navItems']>[number]>()

const label = data?.data?.link?.label
? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}`
: 'Row'

return <div>{label}</div>
}
32 changes: 32 additions & 0 deletions src/Footer/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { GlobalConfig } from 'payload'

import { link } from '@/fields/link'
import { revalidateFooter } from './hooks/revalidateFooter'

export const Footer: GlobalConfig = {
slug: 'footer',
access: {
read: () => true,
},
fields: [
{
name: 'navItems',
type: 'array',
fields: [
link({
appearances: false,
}),
],
maxRows: 6,
admin: {
initCollapsed: true,
components: {
RowLabel: '@/Footer/RowLabel#RowLabel',
},
},
},
],
hooks: {
afterChange: [revalidateFooter],
},
}
13 changes: 13 additions & 0 deletions src/Footer/hooks/revalidateFooter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { GlobalAfterChangeHook } from 'payload'

import { revalidateTag } from 'next/cache'

export const revalidateFooter: GlobalAfterChangeHook = ({ doc, req: { payload, context } }) => {
if (!context.disableRevalidate) {
payload.logger.info(`Revalidating footer`)

revalidateTag('global_footer')
}

return doc
}
42 changes: 42 additions & 0 deletions src/Header/Component.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use client'
import { useHeaderTheme } from '@/providers/HeaderTheme'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import React, { useEffect, useState } from 'react'

import type { Header } from '@/payload-types'

import { Logo } from '@/components/Logo/Logo'
import { HeaderNav } from './Nav'

interface HeaderClientProps {
data: Header
}

export const HeaderClient: React.FC<HeaderClientProps> = ({ data }) => {
/* Storing the value in a useState to avoid hydration errors */
const [theme, setTheme] = useState<string | null>(null)
const { headerTheme, setHeaderTheme } = useHeaderTheme()
const pathname = usePathname()

useEffect(() => {
setHeaderTheme(null)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname])

useEffect(() => {
if (headerTheme && headerTheme !== theme) setTheme(headerTheme)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [headerTheme])

return (
<header className="container relative z-20 " {...(theme ? { 'data-theme': theme } : {})}>
<div className="py-8 flex justify-between">
<Link href="/">
<Logo loading="eager" priority="high" className="invert dark:invert-0" />
</Link>
<HeaderNav data={data} />
</div>
</header>
)
}
11 changes: 11 additions & 0 deletions src/Header/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { HeaderClient } from './Component.client'
import { getCachedGlobal } from '@/utilities/getGlobals'
import React from 'react'

import type { Header } from '@/payload-types'

export async function Header() {
const headerData: Header = await getCachedGlobal('header', 1)()

return <HeaderClient data={headerData} />
}
25 changes: 25 additions & 0 deletions src/Header/Nav/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client'

import React from 'react'

import type { Header as HeaderType } from '@/payload-types'

import { CMSLink } from '@/components/Link'
import Link from 'next/link'
import { SearchIcon } from 'lucide-react'

export const HeaderNav: React.FC<{ data: HeaderType }> = ({ data }) => {
const navItems = data?.navItems || []

return (
<nav className="flex gap-3 items-center">
{navItems.map(({ link }, i) => {
return <CMSLink key={i} {...link} appearance="link" />
})}
<Link href="/search">
<span className="sr-only">Search</span>
<SearchIcon className="w-5 text-primary" />
</Link>
</nav>
)
}
13 changes: 13 additions & 0 deletions src/Header/RowLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'
import { Header } from '@/payload-types'
import { RowLabelProps, useRowLabel } from '@payloadcms/ui'

export const RowLabel: React.FC<RowLabelProps> = () => {
const data = useRowLabel<NonNullable<Header['navItems']>[number]>()

const label = data?.data?.link?.label
? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}`
: 'Row'

return <div>{label}</div>
}
32 changes: 32 additions & 0 deletions src/Header/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { GlobalConfig } from 'payload'

import { link } from '@/fields/link'
import { revalidateHeader } from './hooks/revalidateHeader'

export const Header: GlobalConfig = {
slug: 'header',
access: {
read: () => true,
},
fields: [
{
name: 'navItems',
type: 'array',
fields: [
link({
appearances: false,
}),
],
maxRows: 6,
admin: {
initCollapsed: true,
components: {
RowLabel: '@/Header/RowLabel#RowLabel',
},
},
},
],
hooks: {
afterChange: [revalidateHeader],
},
}
13 changes: 13 additions & 0 deletions src/Header/hooks/revalidateHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { GlobalAfterChangeHook } from 'payload'

import { revalidateTag } from 'next/cache'

export const revalidateHeader: GlobalAfterChangeHook = ({ doc, req: { payload, context } }) => {
if (!context.disableRevalidate) {
payload.logger.info(`Revalidating header`)

revalidateTag('global_header')
}

return doc
}
48 changes: 34 additions & 14 deletions src/app/(payload)/admin/importMap.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f73cfbc

Please sign in to comment.