首頁 >web前端 >js教程 >使用 Next.js、Vercel AI 和 Tolgee 建立看板

使用 Next.js、Vercel AI 和 Tolgee 建立看板

Patricia Arquette
Patricia Arquette原創
2024-11-17 22:17:02625瀏覽

長話短說

在本文中,我們將使用 WebSockets 在 Next.js 中建立即時看板,並提供資料庫支援、透過 Vercel AI SDK 提供的 AI 支援以及透過 Tolgee 進行在地化。

您將學到什麼:✨

  • 在沒有 Express 的 Next.js 中設定 WebSocket 伺服器。
  • 使用 NextAuth 在 Next.js 中實作基於憑證的驗證。
  • 使用 Docker 或雲端供應商配置 PostgreSQL 資料庫。
  • 將任務描述的 AI 支援與 Vercel AI SDK 整合。
  • 使用 Tolgee 新增即時翻譯和在地化。

為 Tolgee 儲存庫加註星標 ⭐

您準備好建立具有人工智慧和在地化支援的獨特看板了嗎? ?

Building a Kanban Board with Next.js,Vercel AI and Tolgee


設定項目? ️

初始化 Next.js 應用程式

使用以下指令初始化一個新的 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 元件

對於 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

使用以下指令初始化 Prisma:

npx prisma init

執行此指令後,應在專案根目錄的 prisma 目錄中建立新的 schema.prisma 檔案。

定義 Prisma 架構

修改新建立的 schema.prisma 檔案以使用 PostgreSQL 作為資料庫並包含 User 和 Task 模型。

// ? 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 或其他服務存取資料庫,那就太好了。使用連線 URL 填入 .env 檔案。您不需要使用 docker 在本機設定資料庫。


使用 Docker 在本機設定資料庫?

如果您正在跟進並且只想使用 Docker 嘗試使用本地 PostgreSQL 資料庫的項目,請將具有此連接字串值的名為 DATABASE_URL 的新變數新增至 .env 檔案中。

npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm

要在本機上運行資料庫,請確保安裝了 Docker。在專案根目錄中建立一個名為scripts的新目錄,並新增一個名為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 的單例實例,以確保在您的應用程式中僅建立和重複使用一個實例,這在開發模式下特別有用。

我們現在可以使用匯出的常數資料庫與應用程式中的資料庫進行互動。

執行以下命令將架構中的變更推送到資料庫。

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 進行本地化? ️

要使用 Tolgee 在 Next.js 應用程式中啟用本地化,請按照以下步驟操作:

  1. 建立語言.ts

此文件處理語言偵測和 cookie 管理。

// ? .env

# If you are using local DB with docker
DATABASE_URL=postgresql://postgres:password@localhost:5432/kanban-board

setLanguage 函數將所選語言(區域設定)保存為有效期為一年的 cookie,允許應用程式在會話中記住使用者的語言首選項。

getLanguage 函數檢查 cookie 中儲存的語言。如果找到有效的語言,則傳回該語言;否則,如果在瀏覽器中執行,它會嘗試從瀏覽器標頭中偵測語言。如果偵測失敗或環境不是瀏覽器,則預設為DEFAULT_LANGUAGE。

  1. 建立shared.ts

此檔案包含用於處理局部化的共享常數和函數,包括取得用於翻譯的靜態資料

npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm

getStaticData 函數負責載入特定語言和命名空間的翻譯以預取在地化內容。它按語言和命名空間從訊息目錄中獲取 JSON 文件,然後將所有內容捆綁到一個物件中並返回它。

對於我們應用程式中的語言選擇,我們將為使用者提供四種不同的語言選擇(英語、捷克語、法語和德語)。如果您願意,您可以新增對其他語言的支援。

在專案根目錄的 messages 目錄中,我們將為不同的單字和句子儲存不同的靜態資料。

ℹ️您可以在我的儲存庫中找到這些靜態翻譯檔案的連結。該文件中沒有什麼需要解釋的,因為它們是一堆不同其他語言的翻譯句子。

TolgeeBase 函數為 Tolgee 設定了處理翻譯的工具。它添加了對 ICU 訊息格式化 (FormatIcu) 的支持,並包含用於偵錯的 DevTools。此函數使用環境變數中的 API 金鑰和 URL,並將英文 (en) 設定為後備語言。

  1. 更新環境變數

我們使用兩個不同的環境變量,使用這些 API 金鑰填充 .env 檔案。在 Tolgee 中註冊一個帳戶並存取 TOLGEE_API_KEYS,但對於此應用程序,不需要擁有該 API 金鑰。

cd kanban-ai-realtime-localization

  1. 建立 server.ts

此檔案配置 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 實例。首先將 getLocale 設定為使用 getLanguage 函數,該函數會擷取使用者的首選語言。然後,在 createTolgee 中,它透過 getStaticData 使用所有支援的語言的翻譯資料初始化 Tolgee。

它還設定 Tolgee 使用提供的語言(來自 getLanguage),並配置自訂取得函數以透過設定 revalidate: 0 始終載入新數據,從而防止快取翻譯請求。

  1. 建立 client.ts

這將為客戶端渲染設定 Tolgee 提供者。

npx shadcn@latest init -d

此程式碼設定了一個用於翻譯的客戶端 Tolgee 提供者。 TolgeeProviderClient 將 language、staticData 和 Children 作為 props,並使用指定的語言和資料初始化 Tolgee。在 useEffect 內部,它透過 permanentChange 監聽語言變化,每當語言更新時透過 router.refresh() 刷新頁面。

最後,TolgeeProvider 渲染子項,使用 ssr 選項預先載入翻譯並在翻譯尚未立即準備好時顯示「正在載入...」。

  1. 在layout.tsx中使用TolgeeProviderClient包裝應用程式

最後,用 包裝您的應用程式元件以確保所有翻譯均可存取。

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 模式

定義 Zod 架構 (AuthSchema) 以驗證使用者在登入和註冊期間輸入的電子郵件和密碼。這可以確保電子郵件格式正確且密碼符合指定的長度要求。

cd kanban-ai-realtime-localization

我們要求電子郵件字段是準確的電子郵件地址,而不是任何其他字串,並且我們希望密碼字段的最小長度為 8 個字符,最大長度為 20 個字符。我們將在多個地方使用此驗證模式來驗證登入/註冊表單中使用者傳遞的數據,以檢查其是否符合資格。

NextAuth 配置

您在src/app/api/auth/[...nextauth]下的route.ts中設定NextAuth,使用CredentialsProvider進行身份驗證。授權函數驗證憑證、檢查使用者的存在並驗證密碼。

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 檔:

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

在這裡,我們說的是,如果用戶未經身份驗證,則不應訪問“/看板”路線。

我們已經完成了處理身分驗證的後端邏輯。讓我們研究一些客戶端邏輯。


建立導覽列組件

我們的導覽列元件也將由一些較小的元件組成。我們將有一個用於登入、註冊、登出的按鈕和一個選擇標籤以允許用戶切換語言。

讓我們開始研究這些組件吧!

語言選擇器元件

在 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 的元件來渲染文字。這樣,當使用者切換語言時,文字也會隨之改變。如果我們對文字進行硬編碼,那麼實作翻譯將是無效的。我們將繼續使用這種方法前進。

我們正在使用 >元件和我們從 Tolgee 的 useTranslate 鉤子獲得的 t 函數來應用翻譯。要了解它們的差異,請訪問此處。

LogoutBtn 元件

同樣,在此元件目錄中建立一個名為 logout-btn.tsx 的新文件,其中包含以下程式碼行:

npx shadcn@latest init -d

與之前類似,當用戶單擊按鈕時,我們會觸發handleLogout函數,然後該函數會嘗試註銷用戶,如果發生任何錯誤,它會顯示一條toast通知以及翻譯後的錯誤訊息。

我們使用載入狀態在使用者登出時顯示載入程式圖示。

導覽列組件

最後,現在我們需要的兩個較小的組件都可用了,讓我們來處理 > 。組件。

npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm

這個導覽列元件為我們的應用程式建立一個導覽列。它使用 getServerSession 檢查使用者是否登入。如果使用者通過身份驗證,則會顯示註銷按鈕。如果沒有,它會顯示用戶登入和註冊的連結。


建立身份驗證頁面

現在,我們已經完成了身份驗證的後端邏輯的處理,也完成了在我們的應用程式中實作 Tolgee 的工作。讓我們研究一些客戶端邏輯並建立一些 UI。

登入組件

在 app/components 目錄中,使用以下程式碼行建立一個新檔案 login.tsx:

cd kanban-ai-realtime-localization

此登入元件顯示電子郵件和密碼的登入表單,兩個輸入欄位都充當受控元件。提交表單後,它會從 next-auth 呼叫 SignIn 來處理身份驗證。如果登入失敗,則會透過 Toast 通知顯示翻譯後的錯誤訊息。成功登入會將使用者重新導向至主頁。

我們還有一個單獨的載入狀態變量,用於在使用者登入我們的應用程式時顯示載入動畫圖示。

目前,這只是我們創建的一個元件;它尚未顯示在我們的應用程式中。為此,我們需要在應用程式的 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

在登入頁面,我們先檢查使用者是否有活動會話。如果用戶有活動會話,我們只需將他們重新導向到「/看板」路線(我們將很快實現)。如果使用者沒有活動會話,我們會顯示先前的 我們建立的元件。

我們現在已經完成了登入頁面的實作;同樣,讓我們可以建立註冊頁面。

註冊組件

在 app/components 目錄中,使用以下程式碼行建立一個新檔案 register.tsx:

npx shadcn@latest init -d

此元件中輸入的電子郵件和密碼可作為受控元件,與登入頁面上的類似。在這裡,我們使用 React Query 來簡化發出 POST 請求的流程。這種方法消除了管理載入或錯誤處理的單獨狀態的需要。

當使用者點擊表單中的提交按鈕時,系統會向我們的 API 路由發出 POST 請求,以便在我們之前使用的資料庫中註冊使用者。如果註冊成功,使用者將被重新導向到登入頁面。如果沒有,則會顯示一則 Toast 訊息以及翻譯後的錯誤訊息。

當使用者點擊提交按鈕時,POST 請求將發送到我們的 API 路由,以在我們先前設定的資料庫中註冊使用者。註冊成功後,使用者將被重新導向到登入頁面。如果註冊失敗,我們會使用相關按鍵顯示一則 toast 訊息以及翻譯後的錯誤訊息。

註冊頁面路由

在 src/app/register 目錄中,建立一個名為 page.tsx 的新文件,其中包含以下程式碼行:

npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm

設定此頁面後,我們已經完成了應用程式的身份驗證流程。現在您應該擁有一個可運行且支援身份驗證且支援本地化的應用程式。


設定 WebSocket 和 QueryClient 提供者

在本節中,我們將為我們的應用程式設定一個 WebSocket 伺服器。我們首先創建一個函數來幫助我們存取套接字。

getSocket 函數

在 src/config 目錄中,使用以下程式碼行建立一個新檔案 socket.ts:

cd kanban-ai-realtime-localization

這段程式碼定義了一個函數 getSocket,它初始化一個 Socket.IO 用戶端連接到環境變數 NEXT_PUBLIC_APP_URL 中指定的 URL,確保套接字只建立一次。如果套接字已經初始化,它只會傳回現有的套接字實例。

套接字提供者

現在,我們需要管理我們的 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

此程式碼建立一個 React 上下文來管理 Socket.IO 連接,提供 useSocket 鉤子來存取套接字實例。 SocketProviderClient 使用 getSocket 函數初始化套接字並連接它,然後將其子級包裝在上下文提供者中以在整個應用程式中共用套接字實例。

現在,我們需要使用此套接字提供者包裝我們的應用程序,以便能夠使用 WebSocket 發送和接收資料。

QueryClient 和 SocketProvider

在同一目錄中,建立一個新檔案providers.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 自訂 Web 伺服器

現在,我們準備建立自己的 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 目錄。 isolatedModules 選項設定為 false,允許可能不是獨立的文件,而 noEmit 為 false,允許產生輸出檔。最後,編譯過程中只包含server.ts檔。

更新package.json

對於我們的開發伺服器,我們將使用 nodemon,現在我們使用 server.ts 檔案作為我們的伺服器。因此,將 package.json 檔案中的腳本修改為:

npx shadcn@latest init -d

此外,我們需要調整 nodemon 配置以觀察 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
}

這個組件有很多事情要做。有兩個輸入字段,它們都是受控組件。然而,文字區域設定為唯讀,因為它是由人工智慧而不是使用者填充的。我們使用兩個狀態變量,標題和描述,來管理標題和描述欄位。

當使用者點擊提交按鈕時,會向我們的任務建立端點發出 API 請求,該端點會在資料庫中為使用者新增一個任務並將其傳回。如果發生任何錯誤,Toast 會顯示翻譯後的錯誤訊息。成功後,我們重置輸入欄位並發出伺服器將接收的事件,觸發面板組件上的更新以顯示所有任務。

從 Vercel 的 AI SDK 訪問的 useChat 鉤子在這裡特別有趣。它提供對訊息歷史記錄和當前輸入訊息等欄位的訪問,以及 isPending 變量,該變量追蹤 AI 的回應是否仍在加載。

當使用者點擊「產生」按鈕時,我們將標題提交給 AI。收到回應後,我們使用 useEffect 掛鉤檢查 messages 欄位。如果助理的訊息更新,我們會為此新訊息設定描述。

更新 server.ts 文件

現在,我們將更新 server.ts 檔案以偵聽任務建立的事件。使用以下程式碼行修改專案根目錄中的 server.ts 檔案:

npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm

在這裡,我們監聽該事件,一旦接收到該事件,我們將其發送到所有連接的套接字。然後它被接收。組件,我們稍後將創建它。此元件將負責以看板格式顯示所有任務並使用接收到的資料更新任務。


設定用於 AI 和任務創建的 API 路由

現在,在我們的 中元件中,當使用者點擊「產生」按鈕時,handleAISubmit 函數會透過 POST 請求呼叫 /api/chat 端點。因此,我們需要建立 API 路由來處理流向描述欄位的回應流。

用於訊息驗證的 Zod 架構

讓我們建立一個模式檔案來驗證使用者和人工智慧的輸入。在 src/lib/validators 目錄中,使用下列程式碼行建立一個新檔案 message.ts:

cd kanban-ai-realtime-localization

現在,我們可以使用這些模式來推斷 AI 的回應類型,以在我們的 API 路由中進行類型驗證。

OpenAI 的聊天路線

最後,在 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 生成的描述。

用於新增任務驗證的 Zod 架構

在 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 端點

現在,讓我們處理任務建立端點,即 /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 來為登入使用者取得任務並將其儲存在任務中。

它監聽雙套接字事件 —tasks-updated(更新任務清單)和 task-created(將新任務附加到目前任務清單)。

使用tasksByStatus 函數按列狀態對任務進行分組(0 表示“正在進行”,1 表示“待處理”,2 表示“已完成”)。此元件會對應這些狀態以呈現具有對應任務的每一列。

DragDropContext 包裝器支援拖放功能。當任務移動時,handleDragEnd 透過套接字事件將新的任務順序傳送到伺服器進行同步。

每一列都是一個可放置區域,其中包含可拖曳的任務元件,允許使用者在列內和列之間重新排序任務。

用於取得使用者任務的 API 路由

現在,讓我們研究 /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 未授權狀態。

路由從請求 URL 的查詢參數中提取電子郵件和使用者 ID。如果 userId 遺失或會話的使用者電子郵件與提供的電子郵件不匹配,則會傳回 403 Forbidden 狀態。

接下來,它會在資料庫中查詢具有指定電子郵件和 ID 的用戶,僅選擇該用戶的 ID 和任務。如果未找到用戶,則傳回 404 Not Found 狀態。如果用戶存在,他們的資料將在回應中發送。

現在,我們快完成了;我們只需要監聽 中的任務拖曳事件即可。 server.ts 檔案中的元件並相應地處理它。

更新 server.ts 文件

修改專案根目錄下的server.ts文件,程式碼如下:

cd kanban-ai-realtime-localization

任務拖曳事件負責處理看板中任務的拖曳功能。當任務從一個位置拖曳到另一個位置時,會觸發此事件,從而允許伺服器更新任務在資料庫中的狀態和位置。

當客戶端發出「任務拖曳」事件時,它會發送有效負載,其中包含被拖曳任務的來源位置和目標位置,以及使用者的電子郵件地址。伺服器監聽此事件。

然後,伺服器呼叫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;如果未找到用戶,則重新導向至註冊頁面。

最後,它渲染 AddTask 和 Board 元件,並將使用者的 ID 作為 prop 傳遞。

還剩下最後一件事:如果您注意到的話,在 在先前的元件中,我們有一種方法讓使用者可以透過 /kanban/[taskId] 的連結查看描述。

看板描述頁面路由

在 src/app/kanban/[taskId] 目錄中,使用下列程式碼行建立一個新檔案 page.tsx:

cd kanban-ai-realtime-localization

這裡也是如此:我們先驗證會話。如前所述,由於我們已經有了中間件,因此永遠不應該執行此操作。

然後,我們只需使用我們收到的作為 prop 的 taskId 從資料庫中取得任務。如果任務不存在,我們將使用者重新導向到 /kanban 頁面。如果確實存在,我們會顯示任務的標題和描述。

首頁路線

最後,讓我們處理應用程式的根主頁(/路線)。使用以下程式碼行修改 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 路線;如果沒有,他們將被重新導向到登入頁面。

這實際上就是讓我們的看板完美運行所需要做的全部事情。現在,您應該擁有一個功能齊全的看板,具有身份驗證、本地化和即時支援。 ?

Building a Kanban Board with Next.js,Vercel AI and Tolgee


結論⚡

哇! ?‍?今天我們一起取得了很多成就。

如果您做到了這一步,那麼您已經在部落格文章的幫助下從頭開始成功建立了一個由人工智慧和本地化驅動的看板。給自己一個當之無愧的鼓勵!

為 Tolgee 儲存庫加註星標 ⭐

關注Tolgee以獲取更多此類內容。

Building a Kanban Board with Next.js,Vercel AI and Tolgee

托爾吉

Tolgee 是一個用於網頁應用程式在地化的開源開發工具?

在下面的評論部分分享你的想法! ?

非常感謝您的閱讀! ? ?

Building a Kanban Board with Next.js,Vercel AI and Tolgee


以上是使用 Next.js、Vercel AI 和 Tolgee 建立看板的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn