Heim >Web-Frontend >js-Tutorial >Erstellen eines Kanban-Boards mit Next.js, Vercel AI und Tolgee
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: ✨
Stern Sie das Tolgee-Repository ⭐
Sind Sie bereit, ein einzigartiges Kanban-Board mit KI- und Lokalisierungsunterstützung zu erstellen? ?
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
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
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.
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.
Ä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.
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. ?
Um die Lokalisierung in Ihrer Next.js-Anwendung mit Tolgee zu aktivieren, befolgen Sie diese Schritte:
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.
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.
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
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 initialisiertEs 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.
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.
Schließen Sie Ihre Anwendung abschließend mit dem
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.
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.
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.
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
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.
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.
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!
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 Komponente, die von shadcn/ui bereitgestellt wird, um alle verfügbaren Sprachoptionen abzubilden. Basierend auf der Benutzerauswahl stellen wir die Sprache mit der setLanguage-Funktion ein, an der wir zuvor in der Datei language.ts gearbeitet haben.
? HINWEIS: Beachten Sie, dass wir keinen Text im Code fest codieren. Stattdessen verwenden wir Komponenten von Tolgee, um den Text darzustellen. Auf diese Weise ändert sich der Text entsprechend, wenn der Benutzer die Sprache wechselt. Wenn wir den Text fest codieren würden, wäre die Implementierung von Übersetzungen wirkungslos. Diesen Ansatz werden wir auch in Zukunft weiter verfolgen.
Wir verwenden das
In ähnlicher Weise erstellen Sie in diesem Komponentenverzeichnis eine neue Datei namens logout-btn.tsx mit den folgenden Codezeilen:
npx shadcn@latest init -d
Ähnlich wie zuvor lösen wir, wenn der Benutzer auf die Schaltfläche klickt, die handleLogout-Funktion aus, die dann versucht, den Benutzer abzumelden, und wenn ein Fehler auftritt, wird eine Toastbenachrichtigung mit der übersetzten Fehlermeldung angezeigt.
Wir verwenden unseren Ladestatus, um beim Abmelden des Benutzers ein Ladesymbol anzuzeigen.
Da nun endlich die beiden benötigten kleineren Komponenten verfügbar sind, arbeiten wir an der
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Diese Navbar-Komponente erstellt eine Navigationsleiste für unsere Anwendung. Es prüft, ob ein Benutzer mit getServerSession angemeldet ist. Wenn der Benutzer authentifiziert ist, wird eine Schaltfläche zum Abmelden angezeigt. Wenn nicht, wird dem Benutzer der Link zum Anmelden und Registrieren angezeigt.
Jetzt sind wir mit der Handhabung der Backend-Logik für die Authentifizierung und der Implementierung von Tolgee in unserer Anwendung fertig. Lassen Sie uns an einer clientseitigen Logik arbeiten und eine Benutzeroberfläche erstellen.
Erstellen Sie im Verzeichnis app/components eine neue Datei login.tsx mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Diese Anmeldekomponente zeigt ein Anmeldeformular für E-Mail und Passwort an, wobei beide Eingabefelder als kontrollierte Komponenten fungieren. Beim Absenden des Formulars wird signIn von next-auth aufgerufen, um die Authentifizierung durchzuführen. Wenn die Anmeldung fehlschlägt, wird eine übersetzte Fehlermeldung über eine Toast-Benachrichtigung angezeigt. Erfolgreiche Anmeldungen leiten den Benutzer zur Startseite weiter.
Wir haben auch eine separate Ladezustandsvariable, die wir verwenden, um ein Ladeanimationssymbol anzuzeigen, während wir den Benutzer bei unserer Anwendung anmelden.
Derzeit ist dies nur eine Komponente, die wir erstellt haben; es wird noch nicht in unserer Anwendung angezeigt. Dazu müssen wir diese Komponente im App-Verzeichnis unserer Anwendung rendern.
Erstellen Sie im Verzeichnis src/app/login eine neue Datei namens page.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
Auf der Anmeldeseite prüfen wir zunächst, ob der Benutzer eine aktive Sitzung hat. Wenn der Benutzer eine aktive Sitzung hat, leiten wir ihn einfach auf die Route „/kanban“ um (die wir in Kürze implementieren werden). Wenn der Benutzer keine aktive Sitzung hat, zeigen wir die frühere
Wir haben jetzt die Implementierung der Login-Seite abgeschlossen; Lassen Sie uns auf ähnliche Weise die Registrierungsseite erstellen.
Erstellen Sie im Verzeichnis app/components eine neue Datei register.tsx mit den folgenden Codezeilen:
npx shadcn@latest init -d
Die E-Mail- und Passworteingaben in dieser Komponente fungieren als kontrollierte Komponenten, ähnlich denen auf der Anmeldeseite. Hier verwenden wir React Query, um den Prozess der POST-Anfrage zu vereinfachen. Durch diesen Ansatz entfällt die Notwendigkeit, separate Zustände für das Laden oder die Fehlerbehandlung zu verwalten.
Wenn der Benutzer im Formular auf die Schaltfläche „Senden“ klickt, wird eine POST-Anfrage an unsere API-Route gestellt, um einen Benutzer in der Datenbank zu registrieren, an der wir zuvor gearbeitet haben. Wenn die Registrierung erfolgreich ist, wird der Benutzer zur Anmeldeseite weitergeleitet. Wenn nicht, wird eine Toastmeldung mit der übersetzten Fehlermeldung angezeigt.
Wenn der Benutzer auf die Schaltfläche „Senden“ klickt, wird eine POST-Anfrage an unsere API-Route gesendet, um den Benutzer in der zuvor eingerichteten Datenbank zu registrieren. Nach erfolgreicher Registrierung wird der Benutzer zur Anmeldeseite weitergeleitet. Wenn die Registrierung fehlschlägt, zeigen wir mithilfe der entsprechenden Tasten eine Toastmeldung mit der übersetzten Fehlermeldung an.
Erstellen Sie im Verzeichnis src/app/register eine neue Datei namens page.tsx mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Mit der Einrichtung dieser Seite haben wir den Authentifizierungsablauf unserer Anwendung abgeschlossen. Sie sollten jetzt über eine funktionierende, authentifizierungsfähige Anwendung mit Lokalisierungsunterstützung verfügen.
In diesem Abschnitt richten wir einen WebSocket-Server für unsere Anwendung ein. Erstellen wir zunächst eine Funktion, die uns hilft, Zugriff auf den Socket zu erhalten.
Erstellen Sie im Verzeichnis src/config eine neue Datei socket.ts mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Dieser Code definiert eine Funktion getSocket, die eine Socket.IO-Clientverbindung mit der in der Umgebungsvariablen NEXT_PUBLIC_APP_URL angegebenen URL initialisiert und so sicherstellt, dass der Socket nur einmal erstellt wird. Wenn der Socket bereits initialisiert ist, wird einfach die vorhandene Socket-Instanz zurückgegeben.
Jetzt müssen wir unsere socket.io-Verbindung verwalten und unseren Komponenten eine Möglichkeit bieten, auf die Socket-Instanz zuzugreifen. Erstellen Sie im Verzeichnis src/providers eine neue Datei socket-provider.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
Dieser Code erstellt einen React-Kontext zum Verwalten einer Socket.IO-Verbindung und stellt einen useSocket-Hook für den Zugriff auf die Socket-Instanz bereit. Der SocketProviderClient initialisiert den Socket mithilfe der getSocket-Funktion und verbindet ihn. Anschließend werden seine untergeordneten Elemente in einen Kontextanbieter eingeschlossen, um die Socket-Instanz in der gesamten Anwendung gemeinsam zu nutzen.
Jetzt müssen wir unsere Anwendung mit diesem Socket-Anbieter umschließen, um Zugriff auf die Verwendung von WebSocket zum Senden und Empfangen von Daten zu erhalten.
Erstellen Sie im selben Verzeichnis eine neue Datei „Providers.tsx“, die wir verwenden werden, um unsere untergeordneten Komponenten mit dem QueryClientProvider von @tanstack/react-query und unserem neu erstellten SocketProviderClient zu umschließen.
Fügen Sie der Datei die folgenden Codezeilen hinzu:
npx shadcn@latest init -d
Jetzt müssen wir unsere Anwendung nur noch mit diesem
Ändern Sie die Datei „layout.tsx“ im Stammverzeichnis des Projekts mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Jetzt sind wir bereit, unseren eigenen Socket.io-Server zu erstellen. Erstellen Sie eine neue Datei server.ts und fügen Sie die folgenden Codezeilen hinzu:
cd kanban-ai-realtime-localization
Jetzt wird diese server.ts-Datei zum Einstiegspunkt für unsere Anwendung. Wir können fast alles tun, was wir mit einem socket.io-Server mit einem Backend-Framework wie express.js machen würden.
Wir können jetzt auf alle Ereignisse warten, die dem Warten auf „Verbindung“ und „Verbindung trennen“ ähneln. Wir werden diese Datei in Zukunft ändern, um unsere benutzerdefinierten Ereignisse abzuhören.
Erstellen Sie nun eine neue Datei tsconfig.server.json, die die für unseren Server spezifischen Einstellungen enthält. Fügen Sie die folgenden Codezeilen hinzu:
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
Diese tsconfig.server.json-Datei erweitert die in tsconfig.json enthaltene Basis-TypeScript-Konfiguration und legt einige benutzerdefinierte Einstellungen für unser Projekt fest. Es verwendet CommonJS für die Modulausgabe und leitet kompilierte Dateien an das dist-Verzeichnis weiter. Die Option „isolatedModules“ ist auf „false“ gesetzt, wodurch Dateien zugelassen werden, die möglicherweise nicht in sich geschlossen sind, während „noEmit“ auf „false“ gesetzt ist und die Generierung von Ausgabedateien ermöglicht. Schließlich wird nur die Datei server.ts in den Kompilierungsprozess einbezogen.
Für unseren Entwicklungsserver verwenden wir nodemon und jetzt auch die Datei server.ts als Server. Ändern Sie also die Skripte in der Datei package.json wie folgt:
npx shadcn@latest init -d
Außerdem müssen wir die Nodemon-Konfiguration anpassen, um Änderungen in der server.ts-Datei zu überwachen und ihren Ausführungsbefehl zu ändern.
Erstellen Sie eine neue Datei nodemon.json im Stammverzeichnis des Projekts mit der folgenden Konfiguration:
npx shadcn@latest add button card input label select textarea toast
Endlich sind wir mit allen Vorarbeiten für unser Board fertig. Lasst uns daran arbeiten, Aufgaben für unser Board anzuzeigen und zu erstellen.
Erstellen Sie im Verzeichnis src/components eine neue Datei task.tsx mit den folgenden Codezeilen:
npx prisma init
Wir werden dies verwenden, um Aufgaben in unserer Anwendung anzuzeigen. Hier akzeptieren wir im Wesentlichen ein Aufgabenobjekt als Requisite und verwenden die Kartenkomponente, um den Aufgabeninhalt auf kartenähnliche Weise darzustellen. Wir verwenden das date-fns-Paket, um das Datum besser lesbar zu formatieren.
Jetzt erstellen wir eine Komponente, mit der wir Aufgaben zu unserem Board hinzufügen können. Erstellen Sie im Verzeichnis src/components eine neue Datei add-task.tsx mit den folgenden Codezeilen:
// ? 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 }
In dieser Komponente ist viel los. Es gibt zwei Eingabefelder, die beide gesteuerte Komponenten sind. Der Textbereich ist jedoch auf readOnly gesetzt, da er von der KI und nicht vom Benutzer gefüllt werden soll. Wir verwenden zwei Statusvariablen, Titel und Beschreibung, um die Titel- und Beschreibungsfelder zu verwalten.
Wenn der Benutzer auf die Schaltfläche „Senden“ klickt, wird eine API-Anfrage an unseren Endpunkt zur Aufgabenerstellung gestellt, der eine neue Aufgabe für den Benutzer in der Datenbank hinzufügt und diese zurückgibt. Wenn Fehler auftreten, wird in einem Toast die übersetzte Fehlermeldung angezeigt. Bei Erfolg setzen wir die Eingabefelder zurück und geben ein Ereignis aus, das der Server aufnimmt und ein Update der Board-Komponente auslöst, um alle Aufgaben anzuzeigen.
Besonders interessant ist hier der useChat-Hook, auf den über das AI SDK von Vercel zugegriffen wird. Es bietet Zugriff auf Felder wie den Nachrichtenverlauf und die aktuelle Eingabenachricht sowie auf die Variable isPending, die verfolgt, ob die Antwort der KI noch geladen wird.
Wenn der Benutzer auf die Schaltfläche „Generieren“ klickt, übermitteln wir den Titel an die KI. Sobald wir eine Antwort erhalten, überprüfen wir das Nachrichtenfeld mithilfe des useEffect-Hooks. Wenn die Nachricht des Assistenten aktualisiert wird, legen wir die Beschreibung auf diese neue Nachricht fest.
Jetzt aktualisieren wir die Datei server.ts, um auch auf das von der Aufgabe erstellte Ereignis zu warten. Ändern Sie die Datei server.ts im Stammverzeichnis des Projekts mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Hier warten wir auf dieses Ereignis, und sobald es empfangen wurde, senden wir es an alle angeschlossenen Sockets. Es wird dann vom
Jetzt können Sie in unserem
Lassen Sie uns eine Schemadatei zur Validierung der Eingaben des Benutzers und der KI erstellen. Erstellen Sie im Verzeichnis src/lib/validators eine neue Datei message.ts mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Jetzt können wir diese Schemata verwenden, um die Art der Antwort von der KI abzuleiten, um eine Typvalidierung in unserer API-Route zu erhalten.
Schließlich erstellen Sie im Verzeichnis src/api/chat eine neue Datei route.ts 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
Bei dieser API-Route validieren wir zunächst die Eingabe, um sicherzustellen, dass sie ein Nachrichtenarray enthält, in dem jedes Objekt ein Rollen- und Inhaltsfeld hat. Als nächstes extrahieren wir die neueste Benutzernachricht (d. h. die aktuellste Frage oder Anfrage an die KI) aus diesem Array. Mit dieser Nachricht übergeben wir sie an die streamText-Funktion und veranlassen die KI, eine Aufgabenbeschreibung basierend auf dem Nachrichteninhalt zu generieren.
Schließlich geben wir die Antwort als Datenstrom zurück, sodass der Client das Nachrichtenarray in Echtzeit aktualisieren kann. Diese Streaming-Antwort löst den useEffect-Hook aus, der das Beschreibungsfeld aktualisiert und die von der KI generierte Beschreibung direkt im Textbereich anzeigt.
Erstellen Sie im Verzeichnis src/lib/validators eine neue Datei create-task.ts mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Das CreateTaskSchema-Schema definiert die Struktur zum Erstellen einer Aufgabe. Es erfordert einen Titel zwischen 1 und 50 Zeichen und enthält optional eine Beschreibung.
Der abgeleitete Typ TCreateTaskSchema bietet Typsicherheit für diese Struktur und ermöglicht uns die Verwendung für konsistente Eingaben sowohl im clientseitigen als auch im serverseitigen Code.
Jetzt arbeiten wir am Endpunkt für die Aufgabenerstellung, d. h. /api/tasks/[userId]/create.
Erstellen Sie ein neues Verzeichnis mit diesem Pfad und erstellen Sie eine route.ts in der Datei mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Diese API-Route erstellt eine neue Aufgabe. Zunächst wird mit getServerSession geprüft, ob eine gültige Benutzersitzung vorliegt. Wenn keine aktive Sitzung vorhanden ist (der Benutzer ist nicht angemeldet), wird der Fehler 401 Unauthorized zurückgegeben. Als nächstes validiert es den Anforderungstext mit CreateTaskSchema. Wenn die Validierung fehlschlägt, antwortet es mit einem 422-Status und Fehlerdetails.
Wenn die Eingabe gültig ist, werden die Aufgaben in der Standardspalte (0 – laufend) für die Bestellung gezählt und dann eine neue Aufgabe in der Datenbank mit dem angegebenen Titel, der optionalen Beschreibung, der Benutzer-ID, der Spalte und dem Bestellwert erstellt ist die Länge des Arrays. Bei Erfolg wird die neue Aufgabe zurückgegeben; andernfalls wird ein interner Serverfehler zurückgegeben.
? Hier werden wir die wichtigsten UI-Komponenten und einige APIs für Aktualisierungsaufgaben auf unserem Board erstellen
Jetzt erstellen wir ein
Erstellen Sie im Verzeichnis src/components eine neue Datei „board.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
In dieser Komponente werden wir die Hauptfunktion eines Kanban-Boards nutzen, nämlich das Drag-and-Drop von Elementen. Hierzu verwenden wir unser zuvor installiertes Paket „react-beautiful-dnd“. Die Komponente ruft zunächst mit getSession die Benutzersitzung ab und setzt sie in den Status. Sobald die Sitzung verfügbar ist, führt sie einen API-Aufruf durch, um Aufgaben für den angemeldeten Benutzer abzurufen und sie in Aufgaben zu speichern.
Es wartet auf Zwei-Socket-Ereignisse – „tasks-updated“, wodurch die Aufgabenliste aktualisiert wird, und „task-created“, wodurch eine neue Aufgabe an die aktuelle Aufgabenliste angehängt wird.
Aufgaben werden mithilfe der Funktion „tasksByStatus“ nach Spaltenstatus gruppiert (0 für „Laufend“, 1 für „Ausstehend“ und 2 für „Abgeschlossen“). Die Komponente ordnet diese Status zu, um jede Spalte mit den entsprechenden Aufgaben darzustellen.
Der DragDropContext-Wrapper ermöglicht Drag-and-Drop-Funktionalität. Wenn eine Aufgabe verschoben wird, sendet handleDragEnd die neue Aufgabenreihenfolge über ein Socket-Ereignis zur Synchronisierung an den Server.
Jede Spalte ist ein ablegbarer Bereich, der ziehbare Aufgabenkomponenten enthält, sodass Benutzer Aufgaben innerhalb und über Spalten hinweg neu anordnen können.
Jetzt arbeiten wir an der Route /api/tasks, die für die Rückgabe einer Liste von Benutzeraufgaben aus der Datenbank verantwortlich ist.
Erstellen Sie in app/api/tasks eine route.ts-Datei mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Die GET-Funktion in dieser API-Route ruft die Informationen eines Benutzers ab, einschließlich seiner Aufgaben. Es beginnt mit der Validierung der Authentifizierung mithilfe von getServerSession. Wenn die Sitzung abwesend ist, wird der Status „401 Nicht autorisiert“ zurückgegeben.
Die Route extrahiert die E-Mail-Adresse und die Benutzer-ID aus den Abfrageparametern der Anforderungs-URL. Wenn die Benutzer-ID fehlt oder die Benutzer-E-Mail-Adresse der Sitzung nicht mit der angegebenen E-Mail-Adresse übereinstimmt, wird der Status „403 Verboten“ zurückgegeben.
Als nächstes wird die Datenbank nach einem Benutzer mit der angegebenen E-Mail-Adresse und ID abgefragt, wobei nur die ID und die Aufgaben des Benutzers ausgewählt werden. Wenn kein Benutzer gefunden wird, wird der Status „404 Nicht gefunden“ zurückgegeben. Wenn der Benutzer existiert, werden seine Daten in der Antwort gesendet.
Jetzt sind wir fast fertig; Wir müssen nur auf das Task-Drag-Ereignis vom
Ändern Sie die Datei server.ts im Stammverzeichnis des Projekts mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Das Task-Drag-Ereignis ist für die Handhabung der Drag-and-Drop-Funktionalität von Aufgaben in Ihrem Kanban-Board verantwortlich. Wenn eine Aufgabe von einer Position an eine andere gezogen wird, wird dieses Ereignis ausgelöst, wodurch der Server den Status und die Position der Aufgabe in der Datenbank aktualisieren kann.
Wenn ein Client das „Task-Drag“-Ereignis ausgibt, sendet er eine Nutzlast mit den Quell- und Zielorten der zu ziehenden Aufgabe sowie der E-Mail-Adresse des Benutzers. Der Server wartet auf dieses Ereignis.
Der Server ruft dann die Funktion handleTaskDrag auf und übergibt die E-Mail-Adresse des Benutzers, die Quelle und das Ziel als Argumente. Diese Funktion ist dafür verantwortlich, den Benutzer mithilfe seiner E-Mail-Adresse aus der Datenbank abzurufen und sicherzustellen, dass die Aufgabenaktualisierungen dem richtigen Benutzer zugeordnet werden.
Innerhalb von handleTaskDrag ruft die Funktion die Aufgaben des Benutzers aus der Datenbank ab und ruft dann updateTasksInDB auf, das die Aufgabenaktualisierungslogik verarbeitet. Diese Funktion aktualisiert die Spalte und Reihenfolge der Aufgabe basierend auf dem Drag-and-Drop-Vorgang und stellt so sicher, dass die Aufgaben in der Datenbank korrekt neu angeordnet werden.
Wenn die Aufgaben erfolgreich aktualisiert wurden, werden die aktualisierten Aufgaben über io.sockets.emit an alle verbundenen Clients zurückgesendet und die Änderungen übertragen, sodass die Benutzeroberfläche in Echtzeit aktualisiert werden kann.
Da wir nun beide
Erstellen Sie im Verzeichnis src/app/kanban eine neue Datei page.tsx mit den folgenden Codezeilen:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Zu Beginn wird die Sitzung des Benutzers mit getServerSession überprüft und bei Abwesenheit der Sitzung zur Anmeldeseite weitergeleitet. Diese Anweisung wird wahrscheinlich nie ausgeführt, da wir zuvor im src-Verzeichnis eine Datei middleware.ts erstellt haben, die besagt, dass nicht authentifizierte Benutzer auf keine Route zugreifen können, die mit /kanban beginnt.
Es schadet jedoch nie, eine zusätzliche Validierungsebene hinzuzufügen, da Next.js alle ähnlichen doppelten Anfragen dedupliziert. Nach Bestätigung der Sitzung wird die Benutzer-ID aus der Datenbank abgerufen. Wenn der Benutzer nicht gefunden wird, wird er zur Registrierungsseite weitergeleitet.
Schließlich werden die AddTask- und Board-Komponenten gerendert und die Benutzer-ID als Requisite übergeben.
Eine letzte Sache bleibt noch: Wenn Sie es bemerkt haben, finden Sie in der
Erstellen Sie im Verzeichnis src/app/kanban/[taskId] eine neue Datei page.tsx mit den folgenden Codezeilen:
cd kanban-ai-realtime-localization
Das Gleiche gilt auch hier: Wir validieren zunächst die Sitzung. Wie bereits erwähnt, sollte dies aufgrund der bereits vorhandenen Middleware niemals ausgeführt werden.
Dann rufen wir einfach die Aufgabe aus der Datenbank ab, indem wir die Task-ID verwenden, die wir als Requisite erhalten haben. Wenn die Aufgabe nicht existiert, leiten wir den Benutzer auf die Seite /kanban um. Wenn es existiert, zeigen wir den Titel und die Beschreibung der Aufgabe an.
Abschließend arbeiten wir an der Stamm-Homepage unserer Anwendung (/route). Ändern Sie src/app/page.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
Hier prüfen wir lediglich, ob der Benutzer authentifiziert ist. Wenn dies der Fall ist, werden sie an die /kanban-Route gesendet. Wenn nicht, werden sie zur Anmeldeseite weitergeleitet.
Das ist buchstäblich alles, was wir tun müssen, um unser Kanban-Board perfekt zum Laufen zu bringen. Jetzt sollten Sie über ein voll funktionsfähiges Kanban-Board mit Authentifizierung, Lokalisierung und Echtzeitunterstützung verfügen. ?
Wow! ?? Wir haben heute gemeinsam viel erreicht.
Wenn Sie es bis hierher geschafft haben, haben Sie mithilfe eines Blogbeitrags erfolgreich ein KI- und Lokalisierungs-gestütztes Kanban-Board von Grund auf erstellt. Gönnen Sie sich einen wohlverdienten Klaps auf die Schulter!
Stern Sie das Tolgee-Repository ⭐
Folgen Sie Tolgee für weitere Inhalte wie diesen.
Teilen Sie Ihre Gedanken im Kommentarbereich unten! ?
Vielen Dank fürs Lesen! ? ?
Das obige ist der detaillierte Inhalt vonErstellen eines Kanban-Boards mit Next.js, Vercel AI und Tolgee. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!