【後編】All GaiXerで1からプロジェクト作ってみた!
2024-05-24
azblob://2024/05/24/eyecatch/2024-05-24-create-project-in-all-gaixer-latter-part-000.jpg

こんにちは。24年入社の玉置です。

All GaiXerで1からプロジェクトを作ってみた!』の後編です。

~ 前編の振り返り ~

前編では、GaiXerに漠然と「なにか開発したい!」と伝えて、読書記録アプリを提案してもらいました。

その後、読書記録アプリの機能やページの仕様を決定しました。

前編の最後ではGaiXerの手順通りにセットアップを行い、開発の準備が整いました。

~ 開発 ~

1つずつGaiXerに作成してもらいます。

index.tsxを生成してください

生成されたコードがこちら。

以下は、pages/index.tsxの例です。

import { useState } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useAuth } from '../hooks/useAuth';

const Home: React.FC = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const router = useRouter();
  const { signIn } = useAuth();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');

    try {
      await signIn(email, password);
      router.push('/dashboard');
    } catch (error) {
      setError('Invalid email or password');
    }
  };

  return (
    <div>
      <h1>Welcome to Book Tracker</h1>
      <p>Keep track of your reading journey!</p>

      <h2>Login</h2>
      {error && <p>{error}</p>}
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="email">Email:</label>
          <input
            type="email"
            id="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div>
          <label htmlFor="password">Password:</label>
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <button type="submit">Login</button>
      </form>

      <p>
        Don't have an account? <Link href="/register">Register</Link>
      </p>
    </div>
  );
};

export default Home;

このファイルでは、以下の機能を実装しています。

  1. ログインフォームを表示し、ユーザーがメールアドレスとパスワードを入力できるようにしています。
  2. フォームの送信時に、useAuthフックのsignIn関数を呼び出して認証を行います。認証が成功した場合、ユーザーはダッシュボードページ(/dashboard)にリダイレクトされます。
  3. 認証が失敗した場合、エラーメッセージを表示します。
  4. ユーザー登録ページへのリンクを提供し、ユーザーがアカウントを作成できるようにしています。

このファイルでは、useStateフックを使用して、フォームの状態(メールアドレス、パスワード、エラーメッセージ)を管理しています。また、useRouterフックを使用して、認証後のリダイレクトを処理しています。

useAuthフックは、認証関連の機能を提供するカスタムフックであると想定しています。このフックは、hooks/useAuth.tsファイルに実装されている必要があります。

スタイリングについては、この例では割愛していますが、必要に応じてCSSやCSS-in-JSを使用してスタイルを適用してください。

コードとその説明、今後のアドバイスが返ってきます。

同じようにすべてのファイルを作成します。

作成し終わった時点で、DBと連携がとれていないところがあるので修正します。

まずは、必要なコードや情報を聞きます。

AuthContext.tsで実際のデータベースと通信しユーザー登録するためのコードを作成するためにはほかにどのようなコードの情報が必要ですか

これだけで動くコードが返ってきました。(返答が非常に長いため省略)

さらにDBの情報に触るAPIを作成します。

pages/api/signup.tsを作成してください

はい、pages/api/signup.tsファイルを作成し、ユーザー登録のAPIエンドポイントを実装しましょう。以下は、signup.tsの例です。

(コードは省略)

このsignup.tsファイルでは、以下の処理を行っています。

  1. pgパッケージを使用して、PostgreSQLデータベースへの接続を設定します。
    • process.env.DATABASE_URLは、データベースの接続URLを環境変数から取得します。実際の接続情報を設定してください。
  2. handler関数をエクスポートし、APIエンドポイントとして機能させます。
  3. リクエストのHTTPメソッドがPOSTの場合にユーザー登録の処理を行います。
    • リクエストボディからemailpasswordを取得します。
  4. メールアドレスの重複をチェックします。
    • SELECTクエリを使用して、指定されたメールアドレスが既に存在するかどうかを確認します。
    • 重複が見つかった場合は、ステータスコード400とエラーメッセージを返します。
  5. 新しいユーザーを登録します。
    • INSERTクエリを使用して、usersテーブルに新しいユーザーを挿入します。
    • 挿入されたユーザーの情報を取得します。
  6. 登録されたユーザーの情報をレスポンスとして返します。
    • ステータスコード200とユーザー情報を含むJSONレスポンスを返します。
  7. エラーが発生した場合は、エラーメッセージをログに出力し、ステータスコード500とエラーメッセージを返します。
  8. リクエストのHTTPメソッドがPOST以外の場合は、ステータスコード405とエラーメッセージを返します。

このsignup.tsファイルをpages/apiディレクトリに配置することで、/api/signupエンドポイントが作成されます。フロントエンドからPOSTリクエストを送信することで、ユーザー登録の処理が実行されます。

ただし、この例では、パスワードはプレーンテキストで保存されています。実際のアプリケーションでは、パスワードをハッシュ化して保存することが重要です。また、エラーハンドリングやバリデーションなどの追加の処理が必要になる場合があります。

セキュリティと適切なエラーハンドリングを確保しながら、アプリケーションの要件に合わせてsignup.tsファイルを適宜修正してください。

他のAPIも作成してもらいます。

作成して実行した状態がこちらです。

ログイン画面
ログイン画面
ダッシュボード画面
ダッシュボード画面
本追加画面
本の追加画面
本の一覧画面
本の一覧画面

この状態ではただ画面上にボタンやテキストボックスが並んでいるだけなのでスタイルを変更したいと思います。

以下のbooks/index.tsxをpages/index.tsxのようにユーザーフレンドリーなUIにしてください
(コードは省略)

以下は、books/index.tsxをモダンでユーザーフレンドリーなUIにした例です。

(コードは省略)

styles/BooksPage.module.cssに追加するスタイル:

(コードは省略)

これらの変更により、books/index.tsxのスタイルがモダンでユーザーフレンドリーなUIになります。主な変更点は以下の通りです。

  1. ページ全体のレイアウトを中央揃えにし、最大幅を設定して読みやすくしました。
  2. ヘッダー部分のスタイルを調整し、「Back to Dashboard」ボタンと「Add Book」ボタンを左右に配置しました。
  3. タイトルの色をプライマリーカラーに設定し、強調しました。
  4. ボタンのスタイルを調整し、ホバー効果を追加してインタラクティブな感覚を与えました。
  5. エラーメッセージの色を赤色に設定し、注目を集めるようにしました。
  6. ローディング中のメッセージを中央揃えにし、色を調整して読みやすくしました。

これらの変更により、本の一覧ページがより使いやすく魅力的なUIになります。必要に応じて、さらにスタイルを調整したり、他の要素にもスタイルを適用したりすることができます。

実行してみると以下のようになります。

スタイルを変更した本の一覧
スタイルを追加した本の一覧画面

「ユーザーフレンドリーなUIにしてください」のようにフワっとしたような要求でもいい感じに形にしてくれます。

同じように他のファイルにも適用していきます。

よさそうですが画面のグラデーションが縞模様になっているので修正してみます。

現在,styles/globals.cssではグラデーションがかかっていますが,この状態では各要素ごとにグラデーションされて縞模様になってしまうため,画面全体にグラデーションを掛けられるように修正してください

以下のようにstyles/globals.cssを修正することで、画面全体にグラデーションを適用できます。

(コードは省略)

主な変更点は以下の通りです。

  1. bodyからグラデーションの背景を削除しました。
  2. #__nextセレクタを追加し、アプリケーションのルート要素に対してグラデーションの背景を適用しました。
    • #__nextは、Next.jsアプリケーションのルート要素のIDです。
    • min-height: 100vh;を設定することで、グラデーションが画面全体に適用されるようにしました。

これらの変更により、画面全体にグラデーションが適用され、各要素ごとにグラデーションが適用されることがなくなります。アプリケーションのルート要素に対してグラデーションを適用することで、一貫したデザインを実現できます。

他の部分のスタイルは変更していないため、それ以外のスタイルは元のままになります。

作成されたコードを適用します。

スタイルを修正した本の一覧表示画面
修正後の一覧表示画面

自分でも雑な要求だと思いますが、GaiXerはちゃんと修正してくれました。

そして、最終的に完成したアプリがこちらになります!

最終的なログイン画面
ログイン画面
最終的なユーザー登録画面
ユーザー登録画面
最終的なダッシュボード画面
ダッシュボード画面
最終的な本の一覧表示画面
本の一覧表示画面
最終的な本の登録画面
本の登録画面
最終的な本の詳細画面
本の詳細画面

~ まとめ ~

開発パートは駆け足になってしまいましたがまとめに入ろうと思います。

結果としては、かなりそれっぽいアプリを作ることができたのではないでしょうか。

そして、作っていて気づいたことがあります。

それは、GaiXerに思い通りの出力をさせるためには意外と自分の知識が必要だということです。
GaiXerで作成したコードでもエラーとなることがありますし、思った通りの動作をしないこともあります。

そんなときに、自分のイメージを正しく伝えるためにはそれなりに知識が必要だと感じました。(例えば、ハンバーガーメニューを作りたいとき、「押したら開くメニューを作ってください」と「ハンバーガーメニューを作ってください」では出力結果が変わることがあります。)

正しく動作を伝えるためには知識が必要で、これができないと何度もGaiXerとやりとりする必要があり時間がかかってしまいます。(なんだか人間とのコミュニケーションに似ています......)

軌道修正や要求に意外と自分自身の開発スキルが必要なので、知識0からGaiXerだけで開発するのはやはり難しいかもと思いました。

さて、前編と後編に分けてやってきたGaiXerで1からプロジェクトを作る企画でしたがいかがだったでしょうか。

まとめでは知識0からの開発は難しいと思うと書きました。

しかし、

  • これまでGitHubリポジトリなどを見て勉強していた実際のコードを生成AIによって、自分が求めている実装で生成することができる
  • コードの解説やポイントを簡潔にまとめてくれる

上記2点のメリットがあります。

このメリットを活かすと初心者がドキュメントやチュートリアルを読みながら勉強した次の段階の実際に自分で開発してみる段階で大きく役立つのではないでしょうか。

今回はすべてGaiXerで開発しましたが、使用者のレベルに合わせたGaiXerの使い方を探していけたらと思います。