アカウントの登録画面をNext.js/Tailwindcss/shadcnで作る

2024/01/20に公開

はじめに

Next.jsで認証の仕組みを作っていくチュートリアルの具体的な作業[第二回]となります。

今回のゴール

この記事のゴールはTailwind CSSとshadcnを駆使して下記のようなアカウント登録画面を作成するところまでとなります。

Image from Gyazo

https://shinagawa-web.com/blogs/nextjs-tailwind-shadcn-homepage

既にTailwind CSSやshadcnは使い方を知っているという方はこの記事は飛ばして頂いても問題ありません。

カードコンポーネントの活用

shadcnのカードコンポーネントを活用してアカウント登録画面の大枠を作っていきます。

https://ui.shadcn.com/docs/components/card

下記のコマンドでshadcnのカードコンポーネントをインストールします。

$ npx shadcn@latest add card

インストールが終わると、/components/ui配下にcard.tsxファイルが作成されます。

card.tsx
一部抜粋

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

一番最後にexportされているコンポーネントがありますが幾つかあります。

アカウント登録画面とログイン画面は比較的似たデザインにしようと考えていますので、これらのコンポーネントをまとめたCardWrapperコンポーネントを/components/auth配下に作成し、それを使っていきます。

card-wrapper.tsx
'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作成し、それを使っていきます。

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>
  )
}

フッターに設置するボタンのコンポーネント作成

footer-button.tsx
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のサーバーコンポーネント、クライアントコンポーネントどちらでも動く便利なライブラリです。

https://react-icons.github.io/react-icons/

2024年9月現在で約48,000種類も提供されているようです。

https://github.com/react-icons/react-icons

48,000種類を一つずつ見ていくのは大変なので先ほどのホームページの検索画面でgooglegithubなどを入力して探します。このような感じでアイコンを探して、使いたいものが見つかればインポートの書き方を表示してくれますので、そのままコピペで画面上にアイコンが表示されます。

Image from Gyazo

このサイトからGoogleとGithubのアイコンを探して、/components/auth配下にsocial.tsx作成しアイコンを使用します。

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の修正

card-wrapper.tsx
'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を使ってコンポーネントを作成していきます。

register-form.tsx
import { CardWrapper } from './card-wrapper'

export const RegisterForm = () => {
  return (
    <CardWrapper
      headerLabel="各項目を入力してアカウントを作成"
      buttonLabel="既にアカウントを登録済みの方はコチラ"
      buttonHref="/auth/login"
      showSocial
    >
      入力フォーム
    </CardWrapper>
  )
}

このコンポーネントに所謂メールアドレスやパスワードなどを入力できる入力フォームを作っていきますが、それは次の記事でご紹介しますので、ここでは一旦、テキストだけ入れておきます。

登録画面では、既にアカウント登録を済ませている方向けにログイン画面に遷移できるボタンを別途用意しています。

次は上記のRegisterFormを使って実際に画面に表示する作業となります。

/app/auth/register配下のpage.tsx を修正します。

page.tsx
+import { RegisterForm } from '@/components/auth/register-form'

const RegisterPage = () => {
- return <div>アカウント登録画面</div>
+ return <RegisterForm />
}

export default RegisterPage

先ほどまでテキストで「アカウント登録画面」とだけ表示されてたところを、RegisterFormに置き換えています。

最後に画面のレイアウトを整えていきます。

/app/auth配下にlayout.tsxを作成しデザインを整えていきます。

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です。

Image from Gyazo

「既にアカウントを登録済みの方はコチラ」というテキストが表示されているかと思いますが、こちらをクリックすると、ログイン画面に遷移できるかと思いますので合わせてご確認ください。

さいごに

今回はTailwind CSSやshadcnを用いて幾つかのコンポーネントを作成し、そしてそれらをまとめ実際に表示できるところまで行いました。

shadcnは一般的に使われるコンポーネントの用意しているので少ない作業でそれらしいコンポーネントを作ることが可能だとイメージが湧いてきたら幸いです。

次回はこの画面に入力フォームを作りながら入力内容のチェックをするバリデーション機能を実装してきます。

次の記事はこちら

https://shinagawa-web.com/blogs/react-hook-form-validation-with-nextjs

記事に関するお問い合わせ📝

記事の内容に関するご質問、ご意見などは、下記よりお気軽にお問い合わせください。
ご質問フォームへ

技術支援などお仕事に関するお問い合わせ📄

技術支援やお仕事のご依頼に関するお問い合わせは、下記よりお気軽にお問い合わせください。
お問い合わせフォームへ