この記事では、WebSocket を使用し、データベース サポート、Vercel AI SDK による AI サポート、Tolgee によるローカリゼーションを備えた Next.js でリアルタイム カンバン ボードを構築します。
学ぶ内容: ✨
Tolgee リポジトリにスターを付ける ⭐
AI とローカリゼーション サポートを備えた独自のかんばんボードを構築する準備はできていますか? ?
次のコマンドを使用して、新しい Next.js アプリケーションを初期化します。
ℹ️ 任意のパッケージ マネージャーを使用できます。このプロジェクトでは、npm を使用します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
次に、新しく作成した Next.js プロジェクトに移動します。
cd kanban-ai-realtime-localization
いくつかの依存関係が必要になります。次のコマンドを実行して、プロジェクトに必要なすべての依存関係をインストールします:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
UI コンポーネントの場合は、shadcn/ui を使用します。次のコマンドを使用してデフォルト設定で初期化します:
npx shadcn@latest init -d
ここで、後でアプリケーションで使用する UI コンポーネントを追加しましょう。再利用可能なコンポーネントを shadcn/ui から追加するには、次のコマンドを実行します:
npx shadcn@latest add button card input label select textarea toast
app/components/ui ディレクトリ内に、これらのコンポーネント用にいくつかの追加ファイルが追加されます。これらのファイルは、アプリケーションの UI を構築するときに使用します。
次のコマンドを使用して Prisma を初期化します:
npx prisma init
このコマンドを実行すると、プロジェクトのルートにある prisma ディレクトリに新しい schema.prisma ファイルが作成されます。
新しく作成した schema.prisma ファイルを変更して、データベースとして PostgreSQL を使用し、ユーザー モデルとタスク モデルを含めます。
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
モデルは単純です。各ユーザーは複数のタスクを持つことができ、各タスクは特定のユーザーにリンクされています。タスクには、そのステータスを表す整数列値があります (進行中は 0、保留中は 1、完了は 2)。順序の値によって、割り当てられた列内での各タスクの位置が決まります。
モデルの準備ができたので、それをデータベースにプッシュする必要があります。このためには、接続 URL が必要です。
Neon または別のサービスを使用してデータベースにすでにアクセスできる場合は、それが最適です。 .env ファイルに接続 URL を入力します。 docker を使用してデータベースをローカルにセットアップする必要はありません。
手順に従って、Docker を使用してローカル PostgreSQL データベースでプロジェクトを試してみたい場合は、この接続文字列値を含む DATABASE_URL という名前の新しい変数を .env ファイルに追加します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
データベースをローカルで実行するには、Docker がインストールされていることを確認してください。プロジェクトのルートに script という名前の新しいディレクトリを作成し、次のコード行を含む start-local-db-docker.sh というファイルを追加します。
cd kanban-ai-realtime-localization
このスクリプトは基本的に、DATABASE_URL 変数の .env ファイルを読み取り、ユーザー名、パスワード、データベース名などの関連データをすべて抽出し、コンテナーが存在しない場合はコンテナーを作成します。すでに実行されている場合は、単に既存のコンテナを起動します。
このスクリプトを実行して、アプリケーションのすべてのユーザー データをホストする PostgreSQL コンテナを作成して実行します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
これで、PostgreSQL を使用したコンテナが実行されるはずです。これに該当するかどうかは、次のコマンドを実行して確認できます:
npx shadcn@latest init -d
次に、データベースと対話するために Prisma クライアントをインスタンス化する方法が必要です。
src/db ディレクトリ内に新しいファイル index.ts を作成し、次のコード行を追加します。
npx shadcn@latest add button card input label select textarea toast
PrismaClient のシングルトン インスタンスをセットアップして、インスタンスが 1 つだけ作成され、アプリケーション全体で再利用されるようにします。これは特に開発モードで役立ちます。
エクスポートした定数 db を使用して、アプリケーション内のデータベースと対話できるようになりました。
次のコマンドを実行して、スキーマの変更をデータベースにプッシュします。
npx prisma init
ここで、更新された型を IDE で機能させるには、次のコマンドを実行して、更新されたスキーマに基づいて新しい型を生成します。
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
アプリケーション データベースをセットアップするために必要なのはこれだけです。 ?
Tolgee を使用して Next.js アプリケーションでローカリゼーションを有効にするには、次の手順に従います。
このファイルは言語検出と Cookie 管理を処理します。
// ? .env # If you are using local DB with docker DATABASE_URL=postgresql://postgres:password@localhost:5432/kanban-board
setLanguage 関数は、選択した言語 (ロケール) を 1 年間の有効期限を持つ Cookie として保存し、アプリがセッション間でユーザーの言語設定を記憶できるようにします。
getLanguage 関数は、Cookie に保存されている言語を確認します。有効な言語が見つかった場合は、それを返します。それ以外の場合、ブラウザで実行されている場合は、ブラウザのヘッダーから言語を検出しようとします。検出が失敗した場合、または環境がブラウザではない場合、デフォルトは DEFAULT_LANGUAGE になります。
このファイルには、翻訳用の静的データの取得など、ローカリゼーションを処理するための共有定数と関数が含まれています
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
getStaticData 関数は、特定の言語と名前空間の翻訳をロードして、ローカライズされたコンテンツをプリフェッチする役割を果たします。言語と名前空間ごとにメッセージ ディレクトリから JSON ファイルを取得し、すべてを 1 つのオブジェクトにバンドルして返します。
アプリケーションでの言語選択では、4 つの異なる言語の選択肢 (英語、チェコ語、フランス語、ドイツ語) がユーザーに提供されます。必要に応じて、他の言語のサポートを追加できます。
プロジェクトのルートにあるメッセージ ディレクトリ内に、さまざまな単語や文の異なる静的データを保存します。
ℹ️ これらの静的翻訳ファイルへのリンクは私のリポジトリにあります。このファイルは他の言語の翻訳文の束であるため、説明することは何もありません。
TolgeeBase 関数は、翻訳を処理するツールを使用して Tolgee をセットアップします。 ICU メッセージ形式 (FormatIcu) のサポートが追加され、デバッグ用の DevTools が含まれています。この関数は、環境変数の API キーと URL を使用し、フォールバック言語として英語 (en) を設定します。
2 つの異なる環境変数を使用し、.env ファイルにこれらの API キーを設定します。 Tolgee でアカウントにサインアップして TOLGEE_API_KEYS にアクセスしますが、このアプリケーションの場合、その API キーを持っている必要はありません。
cd kanban-ai-realtime-localization
このファイルは、サーバー側レンダリング用に Tolgee インスタンスを構成し、翻訳処理を設定します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
このコードは、サーバー側の翻訳処理用の Tolgee インスタンスを作成します。まず、ユーザーの優先言語を取得する getLanguage 関数を使用するように getLocale を設定します。次に、createTolgee で、getStaticData を通じて、サポートされているすべての言語の翻訳データを使用して Tolgee を初期化します。
また、(getLanguage から) 提供された言語を使用するように Tolgee を設定し、revalidate: 0 を設定して常に新しいデータをロードするようにカスタム フェッチ関数を構成し、翻訳リクエストのキャッシュを防ぎます。
これにより、クライアント側レンダリング用の Tolgee プロバイダーが設定されます。
npx shadcn@latest init -d
このコードは、翻訳用にクライアント側の Tolgee プロバイダーを設定します。 TolgeeProviderClient は、言語、staticData、および子を小道具として受け取り、指定された言語とデータで Tolgee を初期化します。 useEffect 内では、permanentChange で言語の変更をリッスンし、言語が更新されるたびに router.refresh() を通じてページを更新します。
最後に、TolgeeProvider は子をレンダリングします。ssr オプションを使用して翻訳をプリロードし、翻訳がすぐに準備できない場合は「読み込み中...」を表示します。
最後に、アプリケーションを
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
ここではまず、ヘッダーまたは関数から設定した Cookie に基づいてユーザーのロケールにアクセスします。次に、そのロケールを
に提供します。タグ。Next.js アプリケーションで Tolgee を設定するために必要なのはこれだけです。 ✨これは、Next.js アプリケーションで Tolgee を使用して位置情報を実装するために実行する必要がある標準プロセスになります。
アプリケーションでは認証に NextAuth を使用します。まず、ユーザーが渡したデータを検証するために使用する新しい Zod スキーマを定義することから始めましょう。
ログインおよび登録時に電子メールとパスワードのユーザー入力を検証するための Zod スキーマ (AuthSchema) を定義します。これにより、電子メールの形式が正しく、パスワードが指定された長さの要件を満たしていることが保証されます。
cd kanban-ai-realtime-localization
電子メールフィールドには他の文字列ではなく正確な電子メールを指定する必要があり、パスワードフィールドは最小長 8 文字、最大長 20 文字にする必要があります。この検証スキーマを複数の場所で使用して、ログイン/登録フォームでユーザーが渡したデータを検証し、基準を満たしているかどうかを確認します。
認証に CredentialsProvider を使用して、route.ts の src/app/api/auth/[...nextauth] に NextAuth を設定します。承認関数は、資格情報を検証し、ユーザーの存在を確認し、パスワードを検証します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
承認関数ロジックは、ユーザーがログインするかどうかを決定します。このセットアップの関数は、指定された電子メールとパスワードがデータベース内の既存のユーザーと一致するかどうかを確認します。
資格情報ベースの認証のみを使用しています。まず、フィールド検証に AuthSchema を使用して資格情報を検証します。検証が成功すると、データベース内のユーザーを電子メールで検索します。ユーザーが見つかると、データベース内のハッシュされたパスワードと入力されたパスワードが比較されます。両方のチェックに合格すると、ユーザーのデータ (パスワードを除く) が返されます。
ご想像のとおり、ここでは .env ファイル内で NEXTAUTH_SECRET 変数を定義する必要があります。 .env ファイルに次の 2 つの変数を入力します:
npx shadcn@latest init -d
src/app/api/auth/register/route.ts で、パスワードをハッシュしてユーザー データをデータベースに保存するユーザー登録用のエンドポイントを作成します。その後、検証の成功に基づいて適切な応答を返します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
ここでは、クライアントから受信したデータを解析し、前に作成した AuthSchema を使用して検証します。次に、ローテーション値 12 のハッシュを作成します。これにより、データベースに保存する暗号化テキストが生成され、最後にユーザーが返されます。
次に、アプリケーションをより堅牢なものにするために、ユーザーが特定のルートを訪問するたびに userSession をチェックするミドルウェアを追加しましょう。ユーザーが認証されていない場合、そのルートへの訪問は許可されません。
認証されていないユーザーの /kanban ルートへのアクセスを制限するミドルウェアを追加します。
cd kanban-ai-realtime-localization
ここでは、ユーザーが認証されていない場合、「/kanban」ルートにアクセスできないようにする必要があると言っています。
認証を処理するためのバックエンド ロジックが完了しました。クライアント側のロジックに取り組んでみましょう。
Navbar コンポーネントは、いくつかの小さなコンポーネントでも構成されます。ログイン、登録、ログアウトするためのボタンと、ユーザーが言語を切り替えられるようにするための選択タグがあります。
これらのコンポーネントの作業を始めましょう!
src/app/components ディレクトリ内に、次のコード行を含む新しいファイル lang-selector.tsx を作成します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
コンポーネントは一目瞭然です。 を使用しています。 shadcn/ui によって提供されるコンポーネントを使用して、利用可能な言語の選択肢をすべてマップします。ユーザーの選択に基づいて、先ほど language.ts ファイルで作業した setLanguage 関数を使用して言語を設定します。
?注: コード内のテキストをハードコーディングしていないことに注目してください。代わりに、Tolgee のコンポーネントを使用してテキストをレンダリングします。このように、ユーザーが言語を切り替えると、それに応じてテキストも変更されます。テキストをハードコーディングした場合、翻訳の実装は効果的ではありません。今後もこのアプローチを使用し続けます。
同様に、このコンポーネント ディレクトリ内に、次のコード行を含む logout-btn.tsx という新しいファイルを作成します。
npx shadcn@latest init -d
前と同様に、ユーザーがボタンをクリックすると、handleLogout 関数がトリガーされ、ユーザーのログアウトが試行され、エラーが発生した場合は、翻訳されたエラー メッセージを含むトースト通知が表示されます。
ユーザーのログアウト時にローダー アイコンを表示するために読み込み状態を使用します。
最後に、必要な小さなコンポーネントが両方とも利用可能になったので、
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
この Navbar コンポーネントは、アプリケーションのナビゲーション バーを作成します。 getServerSession を使用してユーザーがログインしているかどうかを確認します。ユーザーが認証されると、ログアウト ボタンが表示されます。そうでない場合は、ユーザーにログインして登録するためのリンクが表示されます。
これで、認証のためのバックエンド ロジックの処理が完了し、アプリケーションへの Tolgee の実装も完了しました。クライアント側のロジックに取り組み、UI を構築しましょう。
app/components ディレクトリ内に、次のコード行を含む新しいファイル login.tsx を作成します。
cd kanban-ai-realtime-localization
このログイン コンポーネントは、電子メールとパスワードのログイン フォームを表示し、両方の入力フィールドが制御されたコンポーネントとして機能します。フォームの送信時に、next-auth から SignIn を呼び出して認証を処理します。ログインが失敗すると、翻訳されたエラー メッセージがトースト通知を通じて表示されます。ログインに成功すると、ユーザーはホームページにリダイレクトされます。
ユーザーがアプリケーションにログインしているときに読み込みアニメーション アイコンを表示するために使用する、別の読み込み状態変数もあります。
現時点では、これは私たちが作成した単なるコンポーネントです。アプリケーションにはまだ表示されていません。そのためには、このコンポーネントをアプリケーションの app ディレクトリにレンダリングする必要があります。
src/app/login ディレクトリ内に、次のコード行を含む page.tsx という新しいファイルを作成します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
ログイン ページでは、まずユーザーがアクティブなセッションを持っているかどうかを確認します。ユーザーがアクティブなセッションを持っている場合は、単に「/kanban」ルートにリダイレクトします (これはすぐに実装します)。ユーザーがアクティブなセッションを持っていない場合は、以前の
これでログインページの実装が完了しました。同様に、登録ページを構築しましょう。
app/components ディレクトリ内に、次のコード行を含む新しいファイル register.tsx を作成します。
npx shadcn@latest init -d
このコンポーネントの電子メールとパスワードの入力は、ログイン ページのものと同様に、制御されたコンポーネントとして機能します。ここでは、React Query を使用して、POST リクエストを行うプロセスを簡素化します。このアプローチにより、ロードまたはエラー処理のために個別の状態を管理する必要がなくなります。
ユーザーがフォームの送信ボタンをクリックすると、先ほど作業したデータベースにユーザーを登録するための API ルートに対して POST リクエストが行われます。登録が成功すると、ユーザーはログイン ページにリダイレクトされます。そうでない場合は、翻訳されたエラー メッセージとともにトースト メッセージが表示されます。
ユーザーが送信ボタンをクリックすると、POST リクエストが API ルートに送信され、以前に設定したデータベースにユーザーを登録します。登録が成功すると、ユーザーはログイン ページにリダイレクトされます。登録が失敗した場合は、関連するキーを使用して翻訳されたエラー メッセージを含むトースト メッセージが表示されます。
src/app/register ディレクトリ内に、次のコード行を含む page.tsx という新しいファイルを作成します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
このページを設定すると、アプリケーションの認証フローが完了しました。これで、ローカリゼーション サポートを備えた認証対応アプリケーションが動作するようになりました。
このセクションでは、アプリケーション用に WebSocket サーバーをセットアップします。まず、ソケットへのアクセスを支援する関数を作成しましょう。
src/config ディレクトリ内に、次のコード行を含む新しいファイルソケット.ts を作成します。
cd kanban-ai-realtime-localization
このコードは、環境変数 NEXT_PUBLIC_APP_URL で指定された URL への Socket.IO クライアント接続を初期化する関数 getSocket を定義し、ソケットが 1 回だけ作成されるようにします。ソケットがすでに初期化されている場合は、単に既存のソケット インスタンスを返します。
ここで、socket.io 接続を管理し、コンポーネントがソケット インスタンスにアクセスする方法を提供する必要があります。 src/providers ディレクトリ内に、次のコード行を含む新しいファイルsocket-provider.tsxを作成します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
このコードは、Socket.IO 接続を管理するための React コンテキストを作成し、ソケット インスタンスにアクセスするための useSocket フックを提供します。 SocketProviderClient は、getSocket 関数を使用してソケットを初期化して接続し、その子をコンテキスト プロバイダーでラップして、アプリケーション全体でソケット インスタンスを共有します。
次に、データの送受信に WebSocket を使用してアクセスできるように、アプリケーションをこのソケット プロバイダーでラップする必要があります。
同じディレクトリ内に、新しいファイル Provides.tsx を作成します。これを使用して、子コンポーネントを @tanstack/react-query の QueryClientProvider と新しく作成した SocketProviderClient でラップします。
次のコード行をファイルに追加します。
npx shadcn@latest init -d
あとは、アプリケーションをこの
次のコード行を使用して、プロジェクトのルートにあるlayout.tsxを変更します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
これで、独自の Socket.io サーバーを作成する準備が整いました。新しいファイルserver.tsを作成し、次のコード行を追加します:
cd kanban-ai-realtime-localization
これで、このserver.ts ファイルがアプリケーションへのエントリ ポイントになります。 Express.js のようなバックエンド フレームワークを使用すると、socket.io サーバーで行うことのほとんどすべてを行うことができます。
ここで「接続」と「切断」をリッスンするのと同様のイベントをリッスンできるようになりました。今後、このファイルを変更してカスタム イベントをリッスンする予定です。
次に、サーバー固有の設定を保持する新しいファイル tsconfig.server.json を作成します。次のコード行を追加します:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
この tsconfig.server.json ファイルは、tsconfig.json にある基本の TypeScript 構成を拡張し、プロジェクトのいくつかのカスタム設定を指定します。モジュール出力には CommonJS を使用し、コンパイルされたファイルを dist ディレクトリに送ります。孤立モジュールオプションは false に設定され、自己完結型ではないファイルを許可します。一方、noEmit は false に設定され、出力ファイルの生成が許可されます。最後に、コンパイル プロセスには、server.ts ファイルのみが含まれます。
開発サーバーには、nodemon を使用します。また、現在は、server.ts ファイルをサーバーとして使用しています。したがって、package.json ファイル内のスクリプトを次のように変更します。
npx shadcn@latest init -d
また、server.ts ファイル内の変更を監視し、その実行コマンドを変更するには、nodemon 構成を微調整する必要があります。
次の構成でプロジェクトのルートに新しいファイル nodemon.json を作成します。
npx shadcn@latest add button card input label select textarea toast
ついに、ボードの事前作業がすべて完了しました。ボードのタスクの表示と作成に取り組んでみましょう。
src/components ディレクトリ内に、次のコード行を含む新しいファイル task.tsx を作成します。
npx prisma init
これをアプリケーションでタスクを表示するために使用します。ここでは、基本的にタスク オブジェクトをプロップとして受け入れ、Card コンポーネントを使用してタスクの内容をカードのような方法で表示します。 date-fns パッケージを使用して、日付をより読みやすい形式にフォーマットしています。
次に、ボードにタスクを追加するために使用できるコンポーネントを作成しましょう。 src/components ディレクトリ内に、次のコード行を含む新しいファイル add-task.tsx を作成します。
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
このコンポーネントでは多くのことが行われています。 2 つの入力フィールドがあり、どちらも制御されたコンポーネントです。ただし、テキストエリアはユーザーではなく AI によって設定されることを意図しているため、readOnly に設定されます。タイトルと説明の 2 つの状態変数を使用して、タイトルと説明のフィールドを管理します。
ユーザーが送信ボタンをクリックすると、タスク作成エンドポイントに対して API リクエストが行われ、ユーザーの新しいタスクがデータベースに追加されて返されます。エラーが発生した場合は、翻訳されたエラー メッセージがトーストに表示されます。成功すると、入力フィールドをリセットし、サーバーが取得するイベントを発行し、ボード コンポーネントの更新をトリガーしてすべてのタスクを表示します。
ここでは、Vercel の AI SDK からアクセスされる useChat フックが特に興味深いです。これにより、AI の応答がまだ読み込まれているかどうかを追跡する isPending 変数とともに、メッセージ履歴や現在の入力メッセージなどのフィールドへのアクセスが提供されます。
ユーザーが [生成] ボタンをクリックすると、タイトルが AI に送信されます。応答を受信したら、useEffect フックを使用してメッセージ フィールドを確認します。アシスタントのメッセージが更新されると、説明をこの新しいメッセージに設定します。
ここで、server.ts ファイルを更新して、タスクによって作成されたイベントもリッスンします。次のコード行を使用して、プロジェクトのルートにあるserver.tsファイルを変更します:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
ここでは、そのイベントをリッスンし、受信したら、接続されているすべてのソケットにイベントを送信します。その後、それは
次に、
ユーザーと AI からの入力を検証するためのスキーマ ファイルを作成しましょう。 src/lib/validators ディレクトリ内に、次のコード行を含む新しいファイル message.ts を作成します。
cd kanban-ai-realtime-localization
これらのスキーマを使用して AI からの応答の型を推測し、API ルートで型検証を取得できるようになります。
最後に、src/api/chat ディレクトリ内に、次のコード行を含む新しいファイル Route.ts を作成します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
この API ルートでは、まず入力を検証して、各オブジェクトにロールとコンテンツ フィールドがあるメッセージ配列が含まれていることを確認します。次に、この配列から最新のユーザー メッセージ (つまり、AI への最新の質問またはリクエスト) を抽出します。このメッセージを取得したら、それを streamText 関数に渡し、AI にメッセージの内容に基づいてタスクの説明を生成させます。
最後に、応答をデータ ストリームとして返し、クライアントがメッセージ配列をリアルタイムで更新できるようにします。このストリーミング応答は useEffect フックをトリガーし、説明フィールドを更新し、AI が生成した説明をテキスト領域に直接表示します。
src/lib/validators ディレクトリ内に、次のコード行を含む新しいファイル create-task.ts を作成します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
CreateTaskSchema スキーマは、タスクを作成するための構造を定義します。 1 ~ 50 文字のタイトルが必要で、オプションの説明が含まれます。
推論された型 TCreateTaskSchema は、この構造に型安全性を提供し、クライアント側とサーバー側のコードの両方で一貫した型付けに使用できるようにします。
次に、タスク作成エンドポイント、つまり /api/tasks/[userId]/create に取り組んでみましょう。
このパスで新しいディレクトリを作成し、次のコード行を含むファイル内に Route.ts を作成します。
cd kanban-ai-realtime-localization
この API ルートは新しいタスクを作成します。まず、getServerSession を使用して有効なユーザー セッションを確認します。アクティブなセッションがない場合 (ユーザーがログインしていない場合)、401 Unauthorized エラーが返されます。次に、CreateTaskSchema を使用してリクエスト本文を検証し、検証が失敗した場合は、422 ステータスとエラーの詳細を返します。
入力が有効な場合、順序付けのためにデフォルトの列 (0 - 進行中) のタスクをカウントし、指定されたタイトル、オプションの説明、ユーザー ID、列、順序値を使用してデータベースに新しいタスクを作成します。配列の長さです。成功すると新しいタスクが返されます。それ以外の場合は、内部サーバー エラーが返されます。
?ここでは、ボード上のタスクを更新するための主要な UI コンポーネントといくつかの API を構築します
それでは、
src/components ディレクトリ内に、次のコード行を含む新しいファイル board.tsx を作成します。
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
これは、カンバン ボードの主な機能、つまり項目のドラッグ アンド ドロップを利用するコンポーネントです。このために、以前にインストールしたパッケージ、react-Beautiful-dnd を使用します。このコンポーネントは、まず getSession を使用してユーザー セッションを取得し、それを状態に設定します。セッションが利用可能になると、API 呼び出しを行ってログイン ユーザーのタスクを取得し、タスクに保存します。
タスク リストを更新する task-updated と、現在のタスク リストに新しいタスクを追加する task-created という 2 つのソケット イベントをリッスンします。
タスクは、tasksByStatus 関数を使用して、列のステータス (0 は「進行中」、1 は「保留中」、2 は「完了」) ごとにグループ化されます。コンポーネントはこれらのステータスをマップして、対応するタスクを含む各列をレンダリングします。
DragDropContext ラッパーにより、ドラッグ アンド ドロップ機能が有効になります。タスクが移動されると、handleDragEnd は同期のためにソケット イベントを介して新しいタスクの順序をサーバーに送信します。
各列は、ドラッグ可能なタスク コンポーネントを含むドロップ可能な領域であり、ユーザーは列内および列間でタスクを並べ替えることができます。
次に、データベースからユーザー タスクのリストを返す役割を担う /api/tasks ルートに取り組みましょう。
app/api/tasks 内に、次のコード行を含む Route.ts ファイルを作成します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
この API ルートの GET 関数は、タスクを含むユーザーの情報を取得します。まず、getServerSession を使用して認証を検証します。セッションが存在しない場合、401 Unauthorized ステータスが返されます。
ルートは、リクエスト URL のクエリ パラメーターから電子メールとユーザー ID を抽出します。 userId が欠落している場合、またはセッションのユーザーの電子メールが指定された電子メールと一致しない場合は、403 Forbidden ステータスが返されます。
次に、指定された電子メールと ID を持つユーザーをデータベースにクエリし、ユーザーの ID とタスクのみを選択します。ユーザーが見つからない場合は、404 Not Found ステータスが返されます。ユーザーが存在する場合、そのデータが応答で送信されます。
さあ、これでほぼ完了です。
次のコード行を使用して、プロジェクトのルートにあるserver.ts ファイルを変更します。
cd kanban-ai-realtime-localization
タスク ドラッグ イベントは、カンバン ボード内のタスクのドラッグ アンド ドロップ機能を処理します。タスクがある位置から別の位置にドラッグされると、このイベントがトリガーされ、サーバーがデータベース内のタスクのステータスと位置を更新できるようになります。
クライアントが「task-drag」イベントを発行すると、ドラッグされているタスクのソースと宛先の場所、およびユーザーの電子メール アドレスを含むペイロードが送信されます。サーバーはこのイベントをリッスンします。
その後、サーバーは handleTaskDrag 関数を呼び出し、ユーザーの電子メール、送信元、送信先を引数として渡します。この関数は、電子メール アドレスを使用してデータベースからユーザーを取得し、タスクの更新が正しいユーザーに関連付けられていることを確認します。
handleTaskDrag 内で、関数はデータベースからユーザーのタスクを取得し、タスク更新ロジックを処理する updateTasksInDB を呼び出します。この関数は、ドラッグ アンド ドロップ操作に基づいてタスクの列と順序を更新し、データベース内でタスクが正しく再配置されるようにします。
タスクが正常に更新されると、更新されたタスクは io.sockets.emit を使用して接続されているすべてのクライアントに送信され、ユーザー インターフェイスをリアルタイムで更新できるように変更がブロードキャストされます。
これで、
src/app/kanban ディレクトリ内に、次のコード行を含む新しいファイル page.tsx を作成します。
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
getServerSession を使用してユーザーのセッションをチェックすることから始まり、セッションが存在しない場合はログイン ページにリダイレクトされます。このステートメントは、おそらく、実行されることはありません。これは、以前に src ディレクトリに middleware.ts ファイルを構築したためです。このファイルには、/kanban で始まるルートには認証されていないユーザーはアクセスできないことが示されています。
ただし、Next.js は同様の重複リクエストを重複排除するため、検証レイヤーを追加しても問題はありません。セッションを確認した後、データベースからユーザーの ID を取得します。ユーザーが見つからない場合は、登録ページにリダイレクトされます。
最後に、ユーザーの ID をプロップとして渡して、AddTask コンポーネントと Board コンポーネントをレンダリングします。
最後に残っていることが 1 つあります。お気づきの場合は、
src/app/kanban/[taskId] ディレクトリ内に、次のコード行を含む新しいファイル page.tsx を作成します。
cd kanban-ai-realtime-localization
ここでも同じことが当てはまります。最初にセッションを検証します。前述したように、ミドルウェアがすでに導入されているため、これは決して実行されるべきではありません。
次に、小道具として受け取った taskId を使用してデータベースからタスクをフェッチします。タスクが存在しない場合は、ユーザーを /kanban ページにリダイレクトします。存在する場合は、タスクのタイトルと説明が表示されます。
最後に、アプリケーションのルートホームページ (/route) で作業しましょう。次のコード行で src/app/page.tsx を変更します:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
ここでは、ユーザーが認証されているかどうかを単純に確認します。存在する場合、/kanban ルートに送信されます。そうでない場合は、ログイン ページにリダイレクトされます。
カンバン ボードを完璧に実行するために必要なのは文字通りこれだけです。これで、認証、ローカリゼーション、リアルタイム サポートを備えた完全に機能するかんばんボードが完成しました。 ?
うわー! ??今日私たちは一緒に多くのことを達成しました。
ここまで進めば、ブログ投稿の助けを借りて、AI とローカリゼーションを活用したカンバン ボードをゼロから構築することに成功したことになります。自分自身の背中を押して当然です!
Tolgee リポジトリにスターを付ける ⭐
このようなコンテンツをもっと見るには、Tolgee をフォローしてください。
以下のコメントセクションでご意見を共有してください! ?
読んでいただきありがとうございます! ? ?
以上がNext.js、Vercel AI、Tolgee を使用してカンバン ボードを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。