はじめに
Next.jsで認証の仕組みを作っていくチュートリアルの具体的な作業[第二回]となります。
今回のゴール
この記事のゴールはTailwind CSSとshadcnを駆使して下記のようなアカウント登録画面を作成するところまでとなります。
既にTailwind CSSやshadcnは使い方を知っているという方はこの記事は飛ばして頂いても問題ありません。
カードコンポーネントの活用
shadcnのカードコンポーネントを活用してアカウント登録画面の大枠を作っていきます。
下記のコマンドでshadcnのカードコンポーネントをインストールします。
$ npx shadcn@latest add card
インストールが終わると、/components/ui
配下にcard.tsx
ファイルが作成されます。
一部抜粋
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
一番最後にexport
されているコンポーネントがありますが幾つかあります。
アカウント登録画面とログイン画面は比較的似たデザインにしようと考えていますので、これらのコンポーネントをまとめたCardWrapper
コンポーネントを/components/auth
配下に作成し、それを使っていきます。
'use client'
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
interface CardWrapperProps {
children: React.ReactNode
headerLabel: string
buttonLabel?: string
buttonHref?: string
showSocial?: boolean
}
export const CardWrapper = ({
children,
buttonLabel,
buttonHref,
showSocial,
}: CardWrapperProps) => {
return (
<Card className="w-[400px] shadow-md">
<CardHeader></CardHeader>
<CardContent>{children}</CardContent>
{showSocial && <CardFooter></CardFooter>}
{buttonLabel && buttonHref && <CardFooter></CardFooter>}
</Card>
)
}
このコンポーネントは使用する際に幾つかのpropsを受け取るようにしており、その用途をまとめました。
- children: 入力フォームを受け取る
- headerLabel: カードのタイトルの文字列を受け取る
- buttonLabel: カードのフッターに設置するボタンの名称を受け取る
- buttonHref: ボタンをクリックした際の遷移先を設定する
- showSocial: ソーシャルアイコンを表示するかどうかの設定
カードのヘッダー部分のコンポーネント作成
カードの枠が完成しましたのでその中身を作成していきます。
まずはヘッダー部分に当たるコンポーネントになります。
/components/auth
配下にheader.tsx
作成し、それを使っていきます。
interface HeaderProps {
label: string
}
export const Header = ({ label }: HeaderProps) => {
return (
<div className="flex w-full flex-col items-center justify-center gap-y-4">
<h1 className='text-2xl font-semibold'>認証チュートリアル</h1>
<p className="text-sm text-muted-foreground">{label}</p>
</div>
)
}
フッターに設置するボタンのコンポーネント作成
import Link from 'next/link'
import { Button } from '@/components/ui/button'
interface FooterButtonProps {
href: string
label: string
}
export const FooterButton = ({ href, label }: FooterButtonProps) => {
return (
<Button variant="link" className="w-full font-normal" size="sm" asChild>
<Link href={href}>{label}</Link>
</Button>
)
}
ボタンコンポーネントを再び定義しました。
Next.jsの提供しているLinkコンポーネントを使って画面遷移できるようにしてあります。
またデザインはshadcnのボタンコンポーネントを活用しています。
ソーシャルアイコンを表示するコンポーネントの作成
CardWrapper
で使用する最後のコンポーネントとなります。
今回の認証チュートリアルでは最初にメールアドレス/パスワードでログインできる仕組みを構築します。その後、GoogleやGithubのアカウントでもログインできる方法もご紹介していきます。そこの段階で初めて役に立つコンポーネントなのですがこのタイミングで作成しておきます。
まず最初にアイコンを使用するため下記のコマンドでライブラリを追加します。
$ npm i react-icons
react-iconsというアイコンがまとまっているライブラリになります。
Next.jsのサーバーコンポーネント、クライアントコンポーネントどちらでも動く便利なライブラリです。
2024年9月現在で約48,000種類も提供されているようです。
48,000種類を一つずつ見ていくのは大変なので先ほどのホームページの検索画面でgoogle
やgithub
などを入力して探します。このような感じでアイコンを探して、使いたいものが見つかればインポートの書き方を表示してくれますので、そのままコピペで画面上にアイコンが表示されます。
このサイトからGoogleとGithubのアイコンを探して、/components/auth
配下にsocial.tsx
作成しアイコンを使用します。
import { FaGithub } from 'react-icons/fa'
import { FcGoogle } from 'react-icons/fc'
import { Button } from '@/components/ui/button'
export const Social = () => {
return (
<div className="flex w-full items-center gap-x-2">
<Button size="lg" className="w-full" variant="outline">
<FcGoogle className="size-5" />
</Button>
<Button size="lg" className="w-full" variant="outline">
<FaGithub className="size-5" />
</Button>
</div>
)
}
これでアカウント登録画面を作成するのに必要なコンポーネントが一通り揃いました。
これらを組み立てて実際の表示できることを確認していきます。
アカウント登録画面の実装
まずはCardWrapper
の修正
'use client'
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
+import { FooterButton } from './footer-button'
+import { Header } from './header'
+import { Social } from './social'
interface CardWrapperProps {
children: React.ReactNode
headerLabel: string
buttonLabel?: string
buttonHref?: string
showSocial?: boolean
}
export const CardWrapper = ({
children,
+ headerLabel,
buttonLabel,
buttonHref,
showSocial,
}: CardWrapperProps) => {
return (
<Card className="w-[400px] shadow-md">
- <CardHeader></CardHeader>
+ <CardHeader>
+ <Header label={headerLabel} />
+ </CardHeader>
<CardContent>{children}</CardContent>
- {showSocial && <CardFooter></CardFooter>}
+ {showSocial && (
+ <CardFooter>
+ <Social />
+ </CardFooter>
)}
- {buttonLabel && buttonHref && <CardFooter></CardFooter>}
+ {buttonLabel && buttonHref && (
+ <CardFooter>
+ <FooterButton label={buttonLabel} href={buttonHref} />
+ </CardFooter>
)}
</Card>
)
}
基本的には先ほど作成したFooterButton
,Header
,Social
をそれぞれ必要な場所に配置していくこととなります。
次はアカウント登録専用のコンポーネントを作成します。
/components/auth
配下にregister-form.tsx
ファイルを作成し、上記で作成したCardWrapper
を使ってコンポーネントを作成していきます。
import { CardWrapper } from './card-wrapper'
export const RegisterForm = () => {
return (
<CardWrapper
headerLabel="各項目を入力してアカウントを作成"
buttonLabel="既にアカウントを登録済みの方はコチラ"
buttonHref="/auth/login"
showSocial
>
入力フォーム
</CardWrapper>
)
}
このコンポーネントに所謂メールアドレスやパスワードなどを入力できる入力フォームを作っていきますが、それは次の記事でご紹介しますので、ここでは一旦、テキストだけ入れておきます。
登録画面では、既にアカウント登録を済ませている方向けにログイン画面に遷移できるボタンを別途用意しています。
次は上記のRegisterForm
を使って実際に画面に表示する作業となります。
/app/auth/register
配下のpage.tsx
を修正します。
+import { RegisterForm } from '@/components/auth/register-form'
const RegisterPage = () => {
- return <div>アカウント登録画面</div>
+ return <RegisterForm />
}
export default RegisterPage
先ほどまでテキストで「アカウント登録画面」とだけ表示されてたところを、RegisterForm
に置き換えています。
最後に画面のレイアウトを整えていきます。
/app/auth
配下にlayout.tsx
を作成しデザインを整えていきます。
const AuthLayout = ({ children }: { children: React.ReactNode }) => {
return (
<div className="flex h-full items-center justify-center bg-gradient-to-br from-sky-100 to-blue-300">
{children}
</div>
)
}
export default AuthLayout
Next.jsを起動し、トップ画面からアカウント登録画面に遷移すると下記のような画面が表示されたらOKです。
「既にアカウントを登録済みの方はコチラ」というテキストが表示されているかと思いますが、こちらをクリックすると、ログイン画面に遷移できるかと思いますので合わせてご確認ください。
さいごに
今回はTailwind CSSやshadcnを用いて幾つかのコンポーネントを作成し、そしてそれらをまとめ実際に表示できるところまで行いました。
shadcnは一般的に使われるコンポーネントの用意しているので少ない作業でそれらしいコンポーネントを作ることが可能だとイメージが湧いてきたら幸いです。
次回はこの画面に入力フォームを作りながら入力内容のチェックをするバリデーション機能を実装してきます。
次の記事はこちら