Skip to content

Commit

Permalink
feat(basic-starter): upgrade starters to NextDrupal classes
Browse files Browse the repository at this point in the history
Issue #601
  • Loading branch information
JohnAlbin committed Apr 22, 2024
1 parent 21b6c74 commit fb81e6d
Show file tree
Hide file tree
Showing 25 changed files with 269 additions and 161 deletions.
6 changes: 3 additions & 3 deletions examples/example-router-migration/lib/drupal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {
// NextDrupal
} from "next-drupal"

const baseUrl: string = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL || ""
const clientId = process.env.DRUPAL_CLIENT_ID || ""
const clientSecret = process.env.DRUPAL_CLIENT_SECRET || ""
const baseUrl = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL as string
const clientId = process.env.DRUPAL_CLIENT_ID as string
const clientSecret = process.env.DRUPAL_CLIENT_SECRET as string

export const drupal = new DrupalClient(baseUrl, {
auth: {
Expand Down
3 changes: 1 addition & 2 deletions starters/basic-starter/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
.pnp.js
.yarn/install-state.gz

# build/test artifacts
/.turbo
# testing
/coverage

# next.js
Expand Down
2 changes: 1 addition & 1 deletion starters/basic-starter/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Basic Starter

A simple starter for building your site with Next.js and Drupal.
A simple starter for building your site with Next.js' Pages Router and Drupal.

## How to use

Expand Down
20 changes: 3 additions & 17 deletions starters/basic-starter/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
import Link from "next/link"
import { PreviewAlert } from "@/components/PreviewAlert"
import { HeaderNav } from "@/components/navigation/HeaderNav"
import { PreviewAlert } from "@/components/misc/PreviewAlert"
import type { ReactNode } from "react"

export function Layout({ children }: { children: ReactNode }) {
return (
<>
<PreviewAlert />
<div className="max-w-screen-md px-6 mx-auto">
<header>
<div className="container flex items-center justify-between py-6 mx-auto">
<Link href="/" className="text-2xl font-semibold no-underline">
Next.js for Drupal
</Link>
<Link
href="https://next-drupal.org/docs"
target="_blank"
rel="external"
className="hover:text-blue-600"
>
Read the docs
</Link>
</div>
</header>
<HeaderNav />
<main className="container py-10 mx-auto">{children}</main>
</div>
</>
Expand Down
2 changes: 1 addition & 1 deletion starters/basic-starter/components/drupal/ArticleTeaser.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Image from "next/image"
import Link from "next/link"
import { Link } from "@/components/navigation/Link"
import { absoluteUrl, formatDate } from "@/lib/utils"
import type { DrupalNode } from "next-drupal"

Expand Down
21 changes: 21 additions & 0 deletions starters/basic-starter/components/navigation/HeaderNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Link } from "@/components/navigation/Link"

export function HeaderNav() {
return (
<header>
<div className="container flex items-center justify-between py-6 mx-auto">
<Link href="/" className="text-2xl font-semibold no-underline">
Next.js for Drupal
</Link>
<Link
href="https://next-drupal.org/docs"
target="_blank"
rel="external"
className="hover:text-blue-600"
>
Read the docs
</Link>
</div>
</header>
)
}
23 changes: 23 additions & 0 deletions starters/basic-starter/components/navigation/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { forwardRef } from "react"
import NextLink from "next/link"
import type { AnchorHTMLAttributes, ReactNode } from "react"
import type { LinkProps as NextLinkProps } from "next/link"

type LinkProps = NextLinkProps &
Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof NextLinkProps> & {
children?: ReactNode
}

export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
function LinkWithRef(
{
// Turn next/link prefetching off by default.
// @see https://github.com/vercel/next.js/discussions/24009
prefetch = false,
...rest
},
ref
) {
return <NextLink prefetch={prefetch} {...rest} ref={ref} />
}
)
12 changes: 7 additions & 5 deletions starters/basic-starter/lib/drupal.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { DrupalClient } from "next-drupal"
import { NextDrupalPages } from "next-drupal"

const baseUrl: string = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL || ""
const clientId = process.env.DRUPAL_CLIENT_ID || ""
const clientSecret = process.env.DRUPAL_CLIENT_SECRET || ""
const baseUrl = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL as string
const clientId = process.env.DRUPAL_CLIENT_ID as string
const clientSecret = process.env.DRUPAL_CLIENT_SECRET as string

export const drupal = new DrupalClient(baseUrl, {
export const drupal = new NextDrupalPages(baseUrl, {
auth: {
clientId,
clientSecret,
},
useDefaultEndpoints: true,
// debug: true,
})
7 changes: 6 additions & 1 deletion starters/basic-starter/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
3 changes: 1 addition & 2 deletions starters/graphql-starter/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
.pnp.js
.yarn/install-state.gz

# build/test artifacts
/.turbo
# testing
/coverage

# next.js
Expand Down
4 changes: 4 additions & 0 deletions starters/graphql-starter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ A next-drupal starter for building your site with Next.js and GraphQL.

`npx create-next-app -e https://github.com/chapter-three/next-drupal-graphql-starter`

## Deploy to Vercel

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fchapter-three%2Fnext-drupal-graphql-starter&env=NEXT_PUBLIC_DRUPAL_BASE_URL,NEXT_IMAGE_DOMAIN,DRUPAL_CLIENT_ID,DRUPAL_CLIENT_SECRET&envDescription=Learn%20more%20about%20environment%20variables&envLink=https%3A%2F%2Fnext-drupal.org%2Fdocs%2Fenvironment-variables&project-name=next-drupal&demo-title=Next.js%20for%20Drupal&demo-description=A%20next-generation%20front-end%20for%20your%20Drupal%20site.&demo-url=https%3A%2F%2Fdemo.next-drupal.org&demo-image=https%3A%2F%2Fnext-drupal.org%2Fimages%2Fdemo-screenshot.jpg)

## Documentation

See https://next-drupal.org
20 changes: 3 additions & 17 deletions starters/graphql-starter/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
import Link from "next/link"
import { PreviewAlert } from "@/components/PreviewAlert"
import { HeaderNav } from "@/components/navigation/HeaderNav"
import { PreviewAlert } from "@/components/misc/PreviewAlert"
import type { ReactNode } from "react"

export function Layout({ children }: { children: ReactNode }) {
return (
<>
<PreviewAlert />
<div className="max-w-screen-md px-6 mx-auto">
<header>
<div className="container flex items-center justify-between py-6 mx-auto">
<Link href="/" className="text-2xl font-semibold no-underline">
Next.js for Drupal
</Link>
<Link
href="https://next-drupal.org/docs"
target="_blank"
rel="external"
className="hover:text-blue-600"
>
Read the docs
</Link>
</div>
</header>
<HeaderNav />
<main className="container py-10 mx-auto">{children}</main>
</div>
</>
Expand Down
11 changes: 5 additions & 6 deletions starters/graphql-starter/components/drupal/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import Image from "next/image"
import { formatDate } from "@/lib/utils"
import type { NodeArticle } from "@/types"
import type { DrupalArticle } from "@/types"

interface ArticleProps {
node: NodeArticle
node: DrupalArticle
}

export function Article({ node, ...props }: ArticleProps) {
return (
<article {...props}>
<h1 className="mb-4 text-6xl font-black leading-tight">{node.title}</h1>
<div className="mb-4 text-gray-600">
{node.author?.displayName ? (
{node.author?.name ? (
<span>
Posted by{" "}
<span className="font-semibold">{node.author.displayName}</span>
Posted by <span className="font-semibold">{node.author.name}</span>
</span>
) : null}
<span> - {formatDate(node.created)}</span>
<span> - {formatDate(node.created.time)}</span>
</div>
{node.image && (
<figure>
Expand Down
13 changes: 6 additions & 7 deletions starters/graphql-starter/components/drupal/ArticleTeaser.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Image from "next/image"
import Link from "next/link"
import { Link } from "@/components/navigation/Link"
import { formatDate } from "@/lib/utils"
import type { NodeArticle } from "@/types"
import type { DrupalArticle } from "@/types"

interface ArticleTeaserProps {
node: Partial<NodeArticle>
node: Partial<DrupalArticle>
}

export function ArticleTeaser({ node, ...props }: ArticleTeaserProps) {
Expand All @@ -14,13 +14,12 @@ export function ArticleTeaser({ node, ...props }: ArticleTeaserProps) {
<h2 className="mb-4 text-4xl font-bold">{node.title}</h2>
</Link>
<div className="mb-4 text-gray-600">
{node.author?.displayName ? (
{node.author?.name ? (
<span>
Posted by{" "}
<span className="font-semibold">{node.author.displayName}</span>
Posted by <span className="font-semibold">{node.author.name}</span>
</span>
) : null}
{node.created && <span> - {formatDate(node.created)}</span>}
{node.created && <span> - {formatDate(node.created.time)}</span>}
</div>
{node.image && (
<figure className="my-4">
Expand Down
4 changes: 2 additions & 2 deletions starters/graphql-starter/components/drupal/BasicPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { NodePage } from "@/types"
import type { DrupalPage } from "@/types"

interface BasicPageProps {
node: NodePage
node: DrupalPage
}

export function BasicPage({ node, ...props }: BasicPageProps) {
Expand Down
21 changes: 21 additions & 0 deletions starters/graphql-starter/components/navigation/HeaderNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Link } from "@/components/navigation/Link"

export function HeaderNav() {
return (
<header>
<div className="container flex items-center justify-between py-6 mx-auto">
<Link href="/" className="text-2xl font-semibold no-underline">
Next.js for Drupal
</Link>
<Link
href="https://next-drupal.org/docs"
target="_blank"
rel="external"
className="hover:text-blue-600"
>
Read the docs
</Link>
</div>
</header>
)
}
23 changes: 23 additions & 0 deletions starters/graphql-starter/components/navigation/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { forwardRef } from "react"
import NextLink from "next/link"
import type { AnchorHTMLAttributes, ReactNode } from "react"
import type { LinkProps as NextLinkProps } from "next/link"

type LinkProps = NextLinkProps &
Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof NextLinkProps> & {
children?: ReactNode
}

export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
function LinkWithRef(
{
// Turn next/link prefetching off by default.
// @see https://github.com/vercel/next.js/discussions/24009
prefetch = false,
...rest
},
ref
) {
return <NextLink prefetch={prefetch} {...rest} ref={ref} />
}
)
50 changes: 6 additions & 44 deletions starters/graphql-starter/lib/drupal.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,13 @@
import { DrupalClient } from "next-drupal"
import { NextDrupalGraphQL } from "./next-drupal-graphql"

const baseUrl: string = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL || ""
const clientId = process.env.DRUPAL_CLIENT_ID || ""
const clientSecret = process.env.DRUPAL_CLIENT_SECRET || ""
const baseUrl = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL as string
const clientId = process.env.DRUPAL_CLIENT_ID as string
const clientSecret = process.env.DRUPAL_CLIENT_SECRET as string

export const drupal = new DrupalClient(baseUrl, {
export const drupal = new NextDrupalGraphQL(baseUrl, {
auth: {
clientId,
clientSecret,
},
// debug: true,
})

export const graphqlEndpoint = drupal.buildUrl("/graphql")

type QueryPayload = {
query: string
variables?: Record<string, string>
}

type QueryJsonResponse<DataType> = {
data?: DataType
errors?: { message: string }[]
}

// This is a wrapper around drupal.fetch.
// Acts as a query helper.
export async function query<DataType>(payload: QueryPayload) {
const response = await drupal.fetch(graphqlEndpoint.toString(), {
method: "POST",
body: JSON.stringify(payload),
withAuth: true, // Make authenticated requests using OAuth.
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
})

if (!response?.ok) {
throw new Error(response.statusText)
}

const { data, errors }: QueryJsonResponse<DataType> = await response.json()

if (errors) {
console.log(errors)
throw new Error(errors?.map((e) => e.message).join("\n") ?? "unknown")
}

return data
}
Loading

0 comments on commit fb81e6d

Please sign in to comment.