Heim  >  Artikel  >  Web-Frontend  >  Erstellen eines Kanban-Boards mit Next.js, Vercel AI und Tolgee

Erstellen eines Kanban-Boards mit Next.js, Vercel AI und Tolgee

Patricia Arquette
Patricia ArquetteOriginal
2024-11-17 22:17:02536Durchsuche

TL;DR

In diesem Artikel erstellen wir ein Echtzeit-Kanban-Board in Next.js mithilfe von WebSockets, mit Datenbankunterstützung, KI-Unterstützung durch das Vercel AI SDK und Lokalisierung über Tolgee.

Was Sie lernen werden: ✨

  • Richten Sie einen WebSocket-Server in Next.js ohne Express ein.
  • Implementieren Sie die auf Anmeldeinformationen basierende Authentifizierung in Next.js mit NextAuth.
  • Konfigurieren Sie eine PostgreSQL-Datenbank mit Docker oder einem Cloud-Anbieter.
  • Integrieren Sie die KI-Unterstützung für Aufgabenbeschreibungen mit dem Vercel AI SDK.
  • Fügen Sie Echtzeitübersetzung und -lokalisierung mit Tolgee hinzu.

Stern Sie das Tolgee-Repository ⭐

Sind Sie bereit, ein einzigartiges Kanban-Board mit KI- und Lokalisierungsunterstützung zu erstellen? ?

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


Das Projekt einrichten ?️

Initialisieren einer Next.js-Anwendung

Initialisieren Sie eine neue Next.js-Anwendung mit dem folgenden Befehl:

ℹ️ Sie können einen beliebigen Paketmanager Ihrer Wahl verwenden. Für dieses Projekt verwende ich npm.

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

Navigieren Sie als Nächstes in das neu erstellte Next.js-Projekt:

cd kanban-ai-realtime-localization

Abhängigkeiten installieren

Wir benötigen mehrere Abhängigkeiten. Führen Sie diesen Befehl aus, um alle für unser Projekt erforderlichen Abhängigkeiten zu installieren:

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

Einrichten von UI-Komponenten

Für UI-Komponenten verwenden wir shadcn/ui. Initialisieren Sie es mit den Standardeinstellungen mit diesem Befehl:

npx shadcn@latest init -d

Jetzt fügen wir einige UI-Komponenten hinzu, die wir später in unserer Anwendung verwenden werden. Um wiederverwendbare Komponenten aus shadcn/ui hinzuzufügen, führen Sie diesen Befehl aus:

npx shadcn@latest add button card input label select textarea toast

Im Verzeichnis app/components/ui werden einige zusätzliche Dateien für diese Komponenten hinzugefügt, die wir beim Erstellen der Benutzeroberfläche für unsere Anwendung verwenden werden.


Einrichten des Datenbankmodells?

Prisma wird initialisiert

Initialisieren Sie Prisma mit dem folgenden Befehl:

npx prisma init

Nachdem Sie diesen Befehl ausgeführt haben, sollte eine neue schema.prisma-Datei im Prisma-Verzeichnis im Stammverzeichnis Ihres Projekts erstellt werden.

Definieren des Prisma-Schemas

Ändern Sie die neu erstellte Datei schema.prisma, um PostgreSQL als Datenbank zu verwenden und die Benutzer- und Aufgabenmodelle einzuschließen.

// ? 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
}

Das Modell ist unkompliziert: Jeder Benutzer kann mehrere Aufgaben haben, wobei jede Aufgabe mit einem bestimmten Benutzer verknüpft ist. Eine Aufgabe hat einen ganzzahligen Spaltenwert, der ihren Status angibt (0 für läuft, 1 für ausstehend und 2 für abgeschlossen). Der Bestellwert bestimmt die Position jeder Aufgabe innerhalb der zugewiesenen Spalte.

Da wir nun unser Modell fertig haben, müssen wir es in unsere Datenbank übertragen. Dazu benötigen wir die Verbindungs-URL.

Wenn Sie bereits Zugriff auf eine Datenbank mit Neon oder einem anderen Dienst haben, ist das großartig. Füllen Sie die .env-Datei mit der Verbindungs-URL. Sie müssen die Datenbank nicht lokal mit Docker einrichten.


Eine Datenbank lokal mit Docker einrichten?

Wenn Sie mitmachen und das Projekt einfach mit einer lokalen PostgreSQL-Datenbank mithilfe von Docker ausprobieren möchten, fügen Sie der .env-Datei eine neue Variable namens DATABASE_URL mit diesem Verbindungszeichenfolgenwert hinzu.

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

Um eine Datenbank lokal auszuführen, stellen Sie sicher, dass Docker installiert ist. Erstellen Sie im Stammverzeichnis des Projekts ein neues Verzeichnis mit dem Namen „scripts“ und fügen Sie eine Datei namens „start-local-db-docker.sh“ mit den folgenden Codezeilen hinzu:

cd kanban-ai-realtime-localization

Dieses Skript liest grundsätzlich die .env-Datei für die Variable DATABASE_URL und extrahiert alle relevanten Daten wie den Benutzernamen, das Passwort und den Datenbanknamen und erstellt einen Container, falls dieser nicht vorhanden ist. Wenn dies bereits der Fall ist, wird einfach der vorhandene Container hochgefahren.

Führen Sie dieses Skript aus, um einen PostgreSQL-Container zu erstellen und auszuführen, der alle Benutzerdaten für unsere Anwendung hostet.

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

Jetzt sollten wir einen laufenden Container mit PostgreSQL haben. Sie können überprüfen, ob dies der Fall ist, indem Sie diesen Befehl ausführen:

npx shadcn@latest init -d


Jetzt benötigen wir eine Möglichkeit, einen Prisma-Client für die Interaktion mit der Datenbank zu instanziieren.

Erstellen Sie eine neue Datei index.ts im Verzeichnis src/db und fügen Sie die folgenden Codezeilen hinzu:

npx shadcn@latest add button card input label select textarea toast

Wir richten eine Singleton-Instanz des PrismaClient ein, um sicherzustellen, dass in Ihrer Anwendung nur eine Instanz erstellt und wiederverwendet wird, was besonders im Entwicklungsmodus hilfreich ist.

Wir können jetzt unsere exportierte konstante Datenbank verwenden, um mit unserer Datenbank in unserer Anwendung zu interagieren.

Führen Sie den folgenden Befehl aus, um Ihre Änderungen in Ihrem Schema in die Datenbank zu übertragen.

npx prisma init

Damit die aktualisierten Typen nun in der IDE funktionieren, führen Sie den folgenden Befehl aus, um neue Typen basierend auf unserem aktualisierten Schema zu generieren.

// ? 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
}

Das ist alles, was wir zum Einrichten unserer Bewerbungsdatenbank benötigen. ?


Tolgee für die Lokalisierung einrichten ?️

Um die Lokalisierung in Ihrer Next.js-Anwendung mit Tolgee zu aktivieren, befolgen Sie diese Schritte:

  1. Sprache.ts erstellen

Diese Datei übernimmt die Spracherkennung und Cookie-Verwaltung.

// ? .env

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

Die setLanguage-Funktion speichert die ausgewählte Sprache (Gebietsschema) als Cookie mit einem Ablauf von einem Jahr, sodass die App sich sitzungsübergreifend an die Sprachpräferenz des Benutzers erinnern kann.

Die getLanguage-Funktion prüft, ob die in Cookies gespeicherte Sprache vorhanden ist. Wenn eine gültige Sprache gefunden wird, wird diese zurückgegeben. Andernfalls versucht es, die Sprache anhand der Header des Browsers zu erkennen, wenn es in einem Browser ausgeführt wird. Wenn die Erkennung fehlschlägt oder die Umgebung kein Browser ist, wird standardmäßig DEFAULT_LANGUAGE verwendet.

  1. Shared.ts erstellen

Diese Datei enthält gemeinsame Konstanten und Funktionen zur Handhabung der Lokalisierung, einschließlich des Abrufens statischer Daten für Übersetzungen

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

Die getStaticData-Funktion ist für das Laden von Übersetzungen für bestimmte Sprachen und Namespaces verantwortlich, um lokalisierte Inhalte vorab abzurufen. Es ruft JSON-Dateien aus dem Nachrichtenverzeichnis nach Sprache und Namespace ab, bündelt dann alles in einem einzigen Objekt und gibt es zurück.

Für die Sprachauswahl in unserer Anwendung stellen wir dem Benutzer vier verschiedene Sprachoptionen zur Verfügung (Englisch, Tschechisch, Französisch und Deutsch). Sie können bei Bedarf Unterstützung für andere Sprachen hinzufügen.

Im Nachrichtenverzeichnis im Stammverzeichnis des Projekts speichern wir verschiedene statische Daten für verschiedene Wörter und Sätze.

ℹ️ Den Link zu dieser statischen Übersetzungsdatei finden Sie in meinem Repository. In dieser Datei gibt es nichts zu erklären, da es sich um eine Reihe von Übersetzungssätzen in verschiedenen anderen Sprachen handelt.

Die TolgeeBase-Funktion richtet Tolgee mit Tools für die Verarbeitung von Übersetzungen ein. Es bietet Unterstützung für die ICU-Nachrichtenformatierung (FormatIcu) und enthält DevTools zum Debuggen. Die Funktion verwendet den API-Schlüssel und die URL aus Umgebungsvariablen und legt Englisch (en) als Fallback-Sprache fest.

  1. Umgebungsvariablen aktualisieren

Wir verwenden zwei verschiedene env-Variablen. Füllen Sie die .env-Datei mit diesen API-Schlüsseln. Eröffnen Sie ein Konto in Tolgee und erhalten Sie Zugriff auf TOLGEE_API_KEYS. Für diese Anwendung ist es jedoch nicht erforderlich, über diesen API-Schlüssel zu verfügen.

cd kanban-ai-realtime-localization

  1. server.ts erstellen

Diese Datei konfiguriert die Tolgee-Instanz für das serverseitige Rendering und richtet die Übersetzungsverarbeitung ein.

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

Dieser Code erstellt eine Tolgee-Instanz für die serverseitige Übersetzungsverarbeitung. Zunächst wird getLocale so eingestellt, dass die getLanguage-Funktion verwendet wird, die die bevorzugte Sprache des Benutzers abruft. Anschließend wird Tolgee in createTolgee über getStaticData.

mit Übersetzungsdaten für alle unterstützten Sprachen initialisiert

Es stellt Tolgee außerdem so ein, dass es die bereitgestellte Sprache (von getLanguage) verwendet, und konfiguriert eine benutzerdefinierte Abruffunktion, um immer aktuelle Daten zu laden, indem revalidate: 0 festgelegt wird, wodurch das Zwischenspeichern von Übersetzungsanfragen verhindert wird.

  1. client.ts erstellen

Dadurch wird der Tolgee-Anbieter für das clientseitige Rendering eingerichtet.

npx shadcn@latest init -d

Dieser Code richtet einen clientseitigen Tolgee-Anbieter für Übersetzungen ein. TolgeeProviderClient verwendet Sprache, statische Daten und untergeordnete Elemente als Requisiten und initialisiert Tolgee mit der angegebenen Sprache und den angegebenen Daten. Innerhalb von useEffect lauscht es mit permanentChange auf Sprachänderungen und aktualisiert die Seite über router.refresh(), wann immer die Sprache aktualisiert wird.

Schließlich rendert TolgeeProvider die untergeordneten Elemente, indem es SSR-Optionen verwendet, um Übersetzungen vorab zu laden, und zeigt „Laden …“ an, wenn Übersetzungen nicht sofort fertig sind.

  1. Umschließen Sie die Anwendung mit TolgeeProviderClient in layout.tsx

Schließen Sie Ihre Anwendung abschließend mit dem Komponente, um sicherzustellen, dass alle Übersetzungen zugänglich sind.

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

Hier erhalten wir zunächst Zugriff auf das Gebietsschema des Benutzers basierend auf dem Header oder über das Cookie, das wir über die Funktion gesetzt haben. Dann stellen wir dieses Gebietsschema dem zur Verfügung. Tag.

Das ist alles, was wir brauchen, um Tolgee in unserer Next.js-Anwendung einzurichten. ✨Dies wird ein Standardprozess sein, den Sie durchführen müssen, um den Standort mit Tolgee in allen Next.js-Anwendungen zu implementieren.


Authentifizierung einrichten ?️

Wir werden NextAuth zur Authentifizierung in unserer Anwendung verwenden. Beginnen wir zunächst mit der Definition eines neuen Zod-Schemas, das wir zur Validierung der vom Benutzer übergebenen Daten verwenden werden.

Zod-Schema zur Validierung

Definieren Sie ein Zod-Schema (AuthSchema), um Benutzereingaben für E-Mail und Passwort während der Anmeldung und Registrierung zu validieren. Dadurch wird sichergestellt, dass das E-Mail-Format korrekt ist und das Passwort den angegebenen Längenanforderungen entspricht.

cd kanban-ai-realtime-localization

Wir verlangen, dass das E-Mail-Feld die exakte E-Mail-Adresse und keine andere Zeichenfolge enthält, und wir möchten, dass das Passwortfeld eine Mindestlänge von 8 Zeichen und eine Höchstlänge von 20 Zeichen hat. Wir werden dieses Validierungsschema an mehreren Stellen verwenden, um die vom Benutzer übergebenen Daten in unserem Anmelde-/Registrierungsformular zu validieren und zu überprüfen, ob sie die Kriterien erfüllen.

NextAuth-Konfiguration

Sie richten NextAuth in route.ts unter src/app/api/auth/[...nextauth] ein und verwenden CredentialsProvider für die Authentifizierung. Die Autorisierungsfunktion validiert die Anmeldeinformationen, prüft die Existenz des Benutzers und verifiziert das Passwort.

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

Die Logik der Autorisierungsfunktion ist dafür verantwortlich, ob sich der Benutzer anmeldet oder nicht. Die Funktion in diesem Setup prüft, ob die angegebene E-Mail-Adresse und das Passwort mit einem vorhandenen Benutzer in der Datenbank übereinstimmen.

Wir verwenden ausschließlich die auf Anmeldeinformationen basierende Authentifizierung. Zunächst werden die Anmeldeinformationen mithilfe des AuthSchema zur Feldvalidierung validiert. Wenn die Validierung erfolgreich ist, wird der Benutzer per E-Mail in der Datenbank gesucht. Wenn der Benutzer gefunden wird, vergleicht es das gehashte Passwort in der Datenbank mit dem eingegebenen Passwort. Wenn beide Prüfungen erfolgreich sind, werden die Daten des Benutzers zurückgegeben (mit Ausnahme des Passworts).

Wie Sie vielleicht schon erraten haben, müssen wir hier die Variable NEXTAUTH_SECRET in der .env-Datei definieren. Füllen Sie die .env-Datei mit diesen beiden Variablen:

npx shadcn@latest init -d

Benutzerregistrierungs-API

In src/app/api/auth/register/route.ts erstellen wir einen Endpunkt für die Benutzerregistrierung, der das Passwort hasht und Benutzerdaten in der Datenbank speichert. Wir geben dann basierend auf dem Validierungserfolg entsprechende Antworten zurück.

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

Hier analysieren wir die vom Client empfangenen Daten und validieren sie mit dem zuvor geschriebenen AuthSchema. Dann erstellen wir einen Hash mit einem Rotationswert von 12. Dadurch wird ein verschlüsselter Text generiert, den wir in unserer Datenbank speichern, und schließlich geben wir den Benutzer zurück.

Um unsere Anwendung noch stabiler zu machen, fügen wir nun eine Middleware hinzu, die jedes Mal, wenn ein Benutzer eine bestimmte Route besucht, nach der userSession sucht. Wenn er nicht authentifiziert ist, darf er diese Route nicht besuchen.

Middleware für den Routenschutz

Wir fügen eine Middleware hinzu, um den Zugriff auf die /kanban-Route für nicht authentifizierte Benutzer einzuschränken.

cd kanban-ai-realtime-localization

Hier sagen wir, dass ein Benutzer nicht in der Lage sein sollte, die „/kanban“-Route zu besuchen, wenn er nicht authentifiziert ist.

Wir sind mit der Backend-Logik zur Handhabung der Authentifizierung fertig. Lassen Sie uns an einer clientseitigen Logik arbeiten.


Erstellen Sie eine Navbar-Komponente

Unsere Navbar-Komponente wird auch aus einigen kleineren Komponenten bestehen. Wir werden eine Schaltfläche zum Anmelden, Registrieren und Abmelden sowie ein Auswahl-Tag haben, damit der Benutzer die Sprache wechseln kann.

Lasst uns mit der Arbeit an diesen Komponenten beginnen!

LangSelector-Komponente

Erstellen Sie im Verzeichnis src/app/components eine neue Datei lang-selector.tsx mit den folgenden Codezeilen:

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

Die Komponente sollte ziemlich selbsterklärend sein. Wir verwenden die Funktion