Dans cet article, nous allons créer un tableau Kanban en temps réel dans Next.js à l'aide de WebSockets, avec prise en charge de la base de données, prise en charge de l'IA via le SDK Vercel AI et localisation via Tolgee.
Ce que vous apprendrez : ✨
Start le référentiel Tolgee ⭐
Êtes-vous prêt à créer un tableau Kanban unique avec prise en charge de l'IA et de la localisation ? ?
Initialisez une nouvelle application Next.js avec la commande suivante :
ℹ️ Vous pouvez utiliser n'importe quel gestionnaire de paquets de votre choix. Pour ce projet, j'utiliserai npm.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Ensuite, accédez au projet Next.js nouvellement créé :
cd kanban-ai-realtime-localization
Nous aurons besoin de plusieurs dépendances. Exécutez cette commande pour installer toutes les dépendances requises pour notre projet :
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
Pour les composants de l'interface utilisateur, nous utiliserons shadcn/ui. Initialisez-le avec les paramètres par défaut avec cette commande :
npx shadcn@latest init -d
Maintenant, ajoutons quelques composants d'interface utilisateur que nous utiliserons plus tard dans notre application. Pour ajouter des composants réutilisables depuis shadcn/ui, exécutez cette commande :
npx shadcn@latest add button card input label select textarea toast
Dans le répertoire app/components/ui, des fichiers supplémentaires seront ajoutés pour ces composants, que nous utiliserons lors de la création de l'interface utilisateur de notre application.
Initialisez Prisma avec la commande suivante :
npx prisma init
Après avoir exécuté cette commande, un nouveau fichier schema.prisma doit être créé dans le répertoire prisma à la racine de votre projet.
Modifiez le fichier schema.prisma nouvellement créé pour utiliser PostgreSQL comme base de données et incluez les modèles Utilisateur et Tâche.
// ? 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 }
Le modèle est simple : chaque utilisateur peut avoir plusieurs tâches, chaque tâche étant liée à un utilisateur spécifique. Une tâche a une valeur de colonne entière représentant son statut (0 pour en cours, 1 pour en attente et 2 pour terminé). La valeur de la commande détermine la position de chaque tâche dans la colonne qui lui est attribuée.
Maintenant que notre modèle est prêt, nous devons le transférer dans notre base de données. Pour cela, nous avons besoin de l'URL de connexion.
Si vous avez déjà accès à une base de données avec Neon ou un autre service, c'est super. Remplissez le fichier .env avec l'URL de connexion. Vous n'avez pas besoin de configurer la base de données localement avec Docker.
Si vous suivez et souhaitez simplement essayer le projet avec une base de données PostgreSQL locale à l'aide de Docker, ajoutez une nouvelle variable nommée DATABASE_URL avec cette valeur de chaîne de connexion au fichier .env.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Pour exécuter une base de données localement, assurez-vous que Docker est installé. Créez un nouveau répertoire nommé scripts à la racine du projet et ajoutez un fichier appelé start-local-db-docker.sh avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
Ce script lit essentiellement le fichier .env pour la variable DATABASE_URL et extrait toutes les données pertinentes comme le nom d'utilisateur, le mot de passe, le nom de la base de données et crée un conteneur s'il n'existe pas. Si c'est déjà le cas, il fait simplement tourner le conteneur existant.
Exécutez ce script pour créer et exécuter un conteneur PostgreSQL qui hébergera toutes les données utilisateur de notre application.
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
Maintenant, nous devrions avoir un conteneur en cours d'exécution avec PostgreSQL. Vous pouvez vérifier si tel est le cas en exécutant cette commande :
npx shadcn@latest init -d
Maintenant, nous aurons besoin d'un moyen d'instancier un client Prisma pour interagir avec la base de données.
Créez un nouveau fichier index.ts dans le répertoire src/db et ajoutez les lignes de code suivantes :
npx shadcn@latest add button card input label select textarea toast
Nous avons configuré une instance singleton de PrismaClient pour garantir qu'une seule instance est créée et réutilisée dans votre application, ce qui est particulièrement utile en mode développement.
Nous pouvons désormais utiliser notre base de données constante exportée pour interagir avec notre base de données dans notre application.
Exécutez la commande suivante pour transférer vos modifications dans votre schéma vers la base de données.
npx prisma init
Maintenant, pour que les types mis à jour fonctionnent dans l'EDI, exécutez la commande suivante pour générer de nouveaux types basés sur notre schéma mis à jour.
// ? 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 }
C'est tout ce dont nous avons besoin pour configurer notre base de données d'applications. ?
Pour activer la localisation dans votre application Next.js avec Tolgee, suivez ces étapes :
Ce fichier gère la détection de la langue et la gestion des cookies.
// ? .env # If you are using local DB with docker DATABASE_URL=postgresql://postgres:password@localhost:5432/kanban-board
La fonction setLanguage enregistre la langue sélectionnée (locale) sous forme de cookie avec une expiration d'un an, permettant à l'application de mémoriser la préférence linguistique de l'utilisateur au fil des sessions.
La fonction getLanguage vérifie la langue enregistrée dans les cookies. Si une langue valide est trouvée, elle la renvoie ; sinon, il tente de détecter la langue à partir des en-têtes du navigateur s'il est exécuté dans un navigateur. Si la détection échoue ou si l'environnement n'est pas un navigateur, la valeur par défaut est DEFAULT_LANGUAGE.
Ce fichier contient des constantes et des fonctions partagées pour gérer la localisation, y compris la récupération de données statiques pour les traductions
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
La fonction getStaticData est responsable du chargement des traductions pour des langues et des espaces de noms spécifiques afin de pré-extraire le contenu localisé. Il récupère les fichiers JSON du répertoire des messages, par langue et espace de noms, puis regroupe le tout dans un seul objet et le renvoie.
Pour la sélection de la langue dans notre application, nous proposerons à l'utilisateur quatre choix de langues différents (anglais, tchèque, français et allemand). Vous pouvez ajouter la prise en charge d'autres langues si vous le souhaitez.
Dans le répertoire des messages à la racine du projet, nous stockerons différentes données statiques pour différents mots et phrases.
ℹ️ Vous pouvez trouver un lien vers ces fichiers de traduction statique dans mon référentiel. Il n'y a rien à expliquer dans ce fichier car il s'agit d'un tas de phrases traduites dans différentes autres langues.
La fonction TolgeeBase configure Tolgee avec des outils de gestion des traductions. Il ajoute la prise en charge du formatage des messages ICU (FormatIcu) et inclut DevTools pour le débogage. La fonction utilise la clé API et l'URL des variables d'environnement et définit l'anglais (en) comme langue de secours.
Nous utilisons deux variables env différentes, remplissez le fichier .env avec ces clés API. Créez un compte dans Tolgee et accédez aux TOLGEE_API_KEYS, mais pour cette application, il n'est pas nécessaire d'avoir cette clé API.
cd kanban-ai-realtime-localization
Ce fichier configure l'instance Tolgee pour le rendu côté serveur, en configurant la gestion de la traduction.
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
Ce code crée une instance Tolgee pour la gestion de la traduction côté serveur. Cela commence par configurer getLocale pour qu'il utilise la fonction getLanguage, qui récupère la langue préférée de l'utilisateur. Ensuite, dans createTolgee, il initialise Tolgee avec les données de traduction pour toutes les langues prises en charge via getStaticData.
Il configure également Tolgee pour qu'il utilise la langue fournie (à partir de getLanguage) et configure une fonction de récupération personnalisée pour toujours charger de nouvelles données en définissant revalidate : 0, empêchant la mise en cache des demandes de traduction.
Cela configure le fournisseur Tolgee pour le rendu côté client.
npx shadcn@latest init -d
Ce code configure un fournisseur Tolgee côté client pour les traductions. TolgeeProviderClient prend la langue, staticData et les enfants comme accessoires, et initialise Tolgee avec la langue et les données spécifiées. Dans useEffect, il écoute les changements de langue avec permanentChange, actualisant la page via router.refresh() chaque fois que la langue est mise à jour.
Enfin, TolgeeProvider restitue les enfants, en utilisant les options ssr pour précharger les traductions et en affichant "Chargement..." si les traductions ne sont pas prêtes instantanément.
Enfin, enveloppez votre application avec le
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Ici, nous obtenons d'abord accès aux paramètres régionaux de l'utilisateur en fonction de l'en-tête ou du cookie que nous avons défini à partir de la fonction. Ensuite, nous fournissons ces paramètres régionaux au
étiquette.C'est tout ce dont nous avons besoin pour configurer Tolgee dans notre application Next.js. ✨Ce sera un processus standard que vous devrez suivre pour implémenter la localisation avec Tolgee dans toutes les applications Next.js.
Nous utiliserons NextAuth pour l'authentification dans notre application. Tout d’abord, commençons par définir un nouveau schéma Zod que nous utiliserons pour valider les données transmises par l’utilisateur.
Définissez un schéma Zod (AuthSchema) pour valider la saisie de l'utilisateur pour l'e-mail et le mot de passe lors de la connexion et de l'inscription. Cela garantit que le format de l'e-mail est correct et que le mot de passe répond aux exigences de longueur spécifiées.
cd kanban-ai-realtime-localization
Nous exigeons que le champ e-mail soit l'adresse e-mail exacte et non toute autre chaîne et nous voulons que le champ du mot de passe ait une longueur minimale de 8 caractères et une longueur maximale de 20 caractères. Nous utiliserons ce schéma de validation à plusieurs endroits pour valider les données transmises par l'utilisateur dans notre formulaire de connexion/inscription afin de vérifier si elles répondent aux critères.
Vous configurez NextAuth dans route.ts sous src/app/api/auth/[...nextauth], en utilisant CredentialsProvider pour l'authentification. La fonction d'autorisation valide les informations d'identification, vérifie l'existence de l'utilisateur et vérifie le mot de passe.
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
La logique de la fonction d'autorisation est responsable de la connexion ou non de l'utilisateur. La fonction de cette configuration vérifie si l'e-mail et le mot de passe fournis correspondent à un utilisateur existant dans la base de données.
Nous utilisons uniquement l'authentification basée sur les informations d'identification. Tout d’abord, il valide les informations d’identification à l’aide d’AuthSchema pour la validation des champs. Si la validation réussit, elle recherche l'utilisateur par email dans la base de données. Si l'utilisateur est trouvé, il compare ensuite le mot de passe haché dans la base de données avec le mot de passe saisi. Si les deux vérifications réussissent, il renvoie les données de l'utilisateur (à l'exclusion du mot de passe).
Comme vous l'avez peut-être deviné, nous exigeons ici que la variable NEXTAUTH_SECRET soit définie dans le fichier .env. Remplissez le fichier .env avec ces deux variables :
npx shadcn@latest init -d
Dans le src/app/api/auth/register/route.ts, nous créons un point de terminaison pour l'enregistrement des utilisateurs qui hache le mot de passe et stocke les données utilisateur dans la base de données. Nous renvoyons ensuite les réponses appropriées en fonction du succès de la validation.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Ici, nous analysons les données reçues du client et les validons avec l'AuthSchema que nous avons écrit plus tôt. Ensuite, nous créons un hachage avec une valeur de rotation de 12. Cela génère un texte crypté que nous stockerons dans notre base de données, et enfin, nous renvoyons l'utilisateur.
Maintenant, pour rendre notre application plus solide, ajoutons un middleware qui vérifie la session utilisateur à chaque fois qu'un utilisateur visite un certain itinéraire, et s'il n'est pas authentifié, il n'est pas autorisé à visiter cet itinéraire.
Nous ajoutons un middleware pour restreindre l'accès à la route /kanban pour les utilisateurs non authentifiés.
cd kanban-ai-realtime-localization
Ici, nous disons qu'un utilisateur ne devrait pas pouvoir visiter la route « /kanban » s'il n'est pas authentifié.
Nous en avons fini avec la logique backend pour gérer l’authentification. Travaillons sur une logique côté client.
Notre composant Navbar sera également composé de composants plus petits. Nous aurons un bouton pour se connecter, s'inscrire, se déconnecter et une balise de sélection pour permettre à l'utilisateur de changer de langue.
Commençons à travailler sur ces composants !
Dans le répertoire src/app/components, créez un nouveau fichier lang-selector.tsx avec les lignes de code suivantes :
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
Le composant devrait être assez explicite. Nous utilisons l'option composant fourni par shadcn/ui pour cartographier tous les choix de langues disponibles dont nous disposons. En fonction de la sélection de l'utilisateur, nous définissons la langue sur celle-ci avec la fonction setLanguage sur laquelle nous avons travaillé plus tôt dans le fichier language.ts.
? REMARQUE : remarquez que nous ne codons en dur aucun texte dans le code ; à la place, nous utilisons des composants de Tolgee pour restituer le texte. De cette façon, lorsque l'utilisateur change de langue, le texte change en conséquence. Si nous codions le texte en dur, la mise en œuvre des traductions serait inefficace. Nous continuerons à utiliser cette approche à l’avenir.
Nous utilisons le
De même, dans ce répertoire de composants, créez un nouveau fichier appelé logout-btn.tsx avec les lignes de code suivantes :
npx shadcn@latest init -d
Semblable à précédemment, lorsque l'utilisateur clique sur le bouton, nous déclenchons la fonction handleLogout qui tente ensuite de déconnecter l'utilisateur et si une erreur se produit, elle affiche ensuite une notification toast avec le message d'erreur traduit.
Nous utilisons notre état de chargement pour afficher une icône de chargeur lors de la déconnexion de l'utilisateur.
Enfin, maintenant que les deux composants plus petits dont nous avions besoin sont disponibles, travaillons sur la
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Ce composant Navbar crée une barre de navigation pour notre application. Il vérifie si un utilisateur est connecté à l'aide de getServerSession. Si l'utilisateur est authentifié, un bouton de déconnexion s'affiche. Sinon, il affiche le lien permettant à l'utilisateur de se connecter et de s'inscrire.
Maintenant, nous en avons fini avec la gestion de la logique backend pour l'authentification et nous avons également fini d'implémenter Tolgee dans notre application. Travaillons sur une logique côté client et construisons une interface utilisateur.
Dans le répertoire app/components, créez un nouveau fichier login.tsx avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
Ce composant de connexion affiche un formulaire de connexion pour l'e-mail et le mot de passe, les deux champs de saisie fonctionnant comme des composants contrôlés. Lors de la soumission du formulaire, il appelle signIn depuis next-auth pour gérer l'authentification. Si la connexion échoue, un message d'erreur traduit s'affiche via une notification toast. Les connexions réussies redirigent l'utilisateur vers la page d'accueil.
Nous avons également une variable d'état de chargement distincte, que nous utilisons pour afficher une icône d'animation de chargement lors de la connexion de l'utilisateur à notre application.
Actuellement, il ne s'agit que d'un composant que nous avons créé ; il n'est pas encore affiché dans notre application. Pour ce faire, nous devons restituer ce composant dans le répertoire app de notre application.
Dans le répertoire src/app/login, créez un nouveau fichier appelé page.tsx avec les lignes de code suivantes :
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
Dans la page de connexion, nous vérifions d'abord si l'utilisateur a une session active. Si l'utilisateur a une session active, nous le redirigeons simplement vers la route « /kanban » (que nous implémenterons prochainement). Si l'utilisateur n'a pas de session active, nous affichons l'ancien
Nous avons maintenant terminé la mise en œuvre de la page de connexion ; de même, construisons la page d'inscription.
Dans le répertoire app/components, créez un nouveau fichier register.tsx avec les lignes de code suivantes :
npx shadcn@latest init -d
Les entrées d'e-mail et de mot de passe dans ce composant fonctionnent comme des composants contrôlés, similaires à ceux de la page de connexion. Ici, nous utilisons React Query pour simplifier le processus de création de requête POST. Cette approche élimine le besoin de gérer des états distincts pour le chargement ou la gestion des erreurs.
Lorsque l'utilisateur clique sur le bouton Soumettre dans le formulaire, une requête POST est adressée à notre route API pour enregistrer un utilisateur dans la base de données sur laquelle nous avons travaillé précédemment. Si l'inscription réussit, l'utilisateur est redirigé vers la page de connexion. Sinon, un message toast s'affiche avec le message d'erreur traduit.
Lorsque l'utilisateur clique sur le bouton Soumettre, une requête POST est envoyée à notre route API pour enregistrer l'utilisateur dans la base de données que nous avons précédemment configurée. Une fois l'inscription réussie, l'utilisateur est redirigé vers la page de connexion. Si l'enregistrement échoue, nous affichons un message toast avec le message d'erreur traduit à l'aide des touches appropriées.
Dans le répertoire src/app/register, créez un nouveau fichier appelé page.tsx avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Avec cette page mise en place, nous avons terminé le flux d'authentification de notre application. Vous devriez maintenant disposer d'une application opérationnelle activée pour l'authentification avec prise en charge de la localisation.
Dans cette section, nous allons mettre en place un serveur WebSocket pour notre application. Créons d'abord une fonction qui nous aide à accéder au socket.
Dans le répertoire src/config, créez un nouveau fichier socket.ts avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
Ce code définit une fonction getSocket qui initialise une connexion client Socket.IO à l'URL spécifiée dans la variable d'environnement NEXT_PUBLIC_APP_URL, garantissant que le socket n'est créé qu'une seule fois. Si le socket est déjà initialisé, il renvoie simplement l'instance de socket existante.
Maintenant, nous devons gérer notre connexion socket.io et fournir un moyen à nos composants d'accéder à l'instance de socket. Dans le répertoire src/providers, créez un nouveau fichier socket-provider.tsx avec les lignes de code suivantes :
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
Ce code crée un contexte React pour gérer une connexion Socket.IO, fournissant un hook useSocket pour accéder à l'instance de socket. Le SocketProviderClient initialise le socket à l'aide de la fonction getSocket et le connecte, puis encapsule ses enfants dans un fournisseur de contexte pour partager l'instance de socket dans toute l'application.
Maintenant, nous devons envelopper notre application avec ce fournisseur de socket pour pouvoir accéder à l'utilisation de WebSocket pour envoyer et recevoir des données.
Dans le même répertoire, créez un nouveau fichier fournisseurs.tsx que nous utiliserons pour envelopper nos composants enfants avec le QueryClientProvider de @tanstack/react-query et notre SocketProviderClient nouvellement créé.
Ajoutez les lignes de code suivantes au fichier :
npx shadcn@latest init -d
Maintenant, tout ce que nous devons faire est d'envelopper notre application avec ce
Modifiez le layout.tsx à la racine du projet avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Maintenant, nous sommes prêts à créer notre propre serveur Socket.io. Créez un nouveau fichier server.ts et ajoutez les lignes de code suivantes :
cd kanban-ai-realtime-localization
Désormais, ce fichier server.ts devient le point d'entrée de notre application. Nous pouvons faire presque tout ce que nous ferions avec un serveur socket.io avec un framework backend comme express.js.
Nous pouvons désormais écouter tous les événements similaires à l'écoute de « connexion » et de « déconnexion » ici. Nous modifierons ce fichier à l'avenir pour écouter nos événements personnalisés.
Maintenant, créez un nouveau fichier tsconfig.server.json qui contiendra les paramètres spécifiques à notre serveur. Ajoutez les lignes de code suivantes :
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
Ce fichier tsconfig.server.json étend la configuration TypeScript de base trouvée dans tsconfig.json et spécifie certains paramètres personnalisés pour notre projet. Il utilise CommonJS pour la sortie du module et dirige les fichiers compilés vers le répertoire dist. L'option isoléeModules est définie sur false, autorisant la génération de fichiers qui peuvent ne pas être autonomes, tandis que noEmit est définie sur false, permettant la génération de fichiers de sortie. Enfin, il inclut uniquement le fichier server.ts dans le processus de compilation.
Pour notre serveur de développement, nous utiliserons nodemon et maintenant nous utilisons également le fichier server.ts comme serveur. Alors, modifiez les scripts dans le fichier package.json comme suit :
npx shadcn@latest init -d
De plus, nous devons modifier la configuration de nodemon pour surveiller les modifications dans le fichier server.ts et modifier sa commande d'exécution.
Créez un nouveau fichier nodemon.json à la racine du projet avec la configuration suivante :
npx shadcn@latest add button card input label select textarea toast
Enfin, nous avons maintenant terminé tous les pré-travaux pour notre planche. Travaillons sur l'affichage et la création de tâches pour notre tableau.
Dans le répertoire src/components, créez un nouveau fichier task.tsx avec les lignes de code suivantes :
npx prisma init
Nous l'utiliserons pour afficher les tâches dans notre application. Ici, nous acceptons essentiellement un objet de tâche comme accessoire et utilisons le composant Card pour présenter le contenu de la tâche à la manière d'une carte. Nous utilisons le package date-fns pour formater la date de manière plus lisible.
Maintenant, créons un composant que nous pouvons utiliser pour ajouter des tâches à notre tableau. Dans le répertoire src/components, créez un nouveau fichier add-task.tsx avec les lignes de code suivantes :
// ? 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 }
Il se passe beaucoup de choses dans ce composant. Il existe deux champs de saisie, qui sont tous deux des composants contrôlés. Cependant, la zone de texte est définie sur readOnly car elle est destinée à être remplie par l'IA plutôt que par l'utilisateur. Nous utilisons deux variables d'état, titre et description, pour gérer les champs de titre et de description.
Lorsque l'utilisateur clique sur le bouton Soumettre, une requête API est adressée à notre point de terminaison de création de tâche, qui ajoute une nouvelle tâche pour l'utilisateur dans la base de données et la renvoie. Si des erreurs se produisent, un toast affiche le message d'erreur traduit. En cas de succès, nous réinitialisons les champs de saisie et émettons un événement que le serveur récupérera, déclenchant une mise à jour sur le composant du tableau pour afficher toutes les tâches.
Le hook useChat, accessible depuis le SDK AI de Vercel, est ici particulièrement intéressant. Il donne accès à des champs tels que l'historique des messages et le message d'entrée actuel, ainsi qu'à la variable isPending, qui permet de savoir si la réponse de l'IA est toujours en cours de chargement.
Lorsque l'utilisateur clique sur le bouton Générer, nous soumettons le titre à l'IA. Une fois que nous recevons une réponse, nous vérifions le champ des messages à l’aide du hook useEffect. Si le message de l'assistant est mis à jour, nous définissons la description sur ce nouveau message.
Maintenant, nous allons mettre à jour le fichier server.ts pour écouter également l'événement créé par la tâche. Modifiez le fichier server.ts à la racine du projet avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Ici, nous écoutons cet événement, et une fois qu'il est reçu, nous l'émettons sur toutes les prises connectées. Il est ensuite reçu par le
Maintenant, dans notre
Créons un fichier de schéma pour valider les entrées de l'utilisateur et de l'IA. Dans le répertoire src/lib/validators, créez un nouveau fichier message.ts avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
Maintenant, nous pouvons utiliser ces schémas pour déduire le type de réponse de l'IA afin d'obtenir la validation de type dans notre route API.
Enfin, dans le répertoire src/api/chat, créez un nouveau fichier route.ts avec les lignes de code suivantes :
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
Dans cette route API, nous commençons par valider l'entrée pour nous assurer qu'elle inclut un tableau de messages où chaque objet a un rôle et un champ de contenu. Ensuite, nous extrayons le dernier message utilisateur (c'est-à-dire la question ou la demande la plus récente adressée à l'IA) de ce tableau. Avec ce message en main, nous le transmettons à la fonction streamText, invitant l'IA à générer une description de tâche basée sur le contenu du message.
Enfin, nous renvoyons la réponse sous forme de flux de données, permettant au client de mettre à jour le tableau des messages en temps réel. Cette réponse en streaming déclenche le hook useEffect, qui met à jour le champ de description, affichant la description générée par l'IA directement dans la zone de texte.
Dans le répertoire src/lib/validators, créez un nouveau fichier create-task.ts avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Le schéma CreateTaskSchema définit la structure de création d'une tâche. Il nécessite un titre entre 1 et 50 caractères et comprend une description facultative.
Le type déduit, TCreateTaskSchema, assure la sécurité des types pour cette structure, nous permettant de l'utiliser pour une saisie cohérente dans le code côté client et côté serveur.
Maintenant, travaillons sur le point de terminaison de création de tâche, c'est-à-dire /api/tasks/[userId]/create.
Créez un nouveau répertoire avec ce chemin et créez un route.ts à l'intérieur du fichier avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
Cette route API crée une nouvelle tâche. Il vérifie d'abord une session utilisateur valide avec getServerSession. S'il n'y a pas de session active (l'utilisateur n'est pas connecté), il renvoie une erreur 401 non autorisée. Ensuite, il valide le corps de la demande avec CreateTaskSchema, et si la validation échoue, il répond avec un statut 422 et les détails de l'erreur.
Si l'entrée est valide, elle compte les tâches dans la colonne par défaut (0 - en cours) pour la commande, puis crée une nouvelle tâche dans la base de données avec le titre fourni, la description facultative, l'ID utilisateur, la colonne et la valeur de la commande, qui est la longueur du tableau. La nouvelle tâche est renvoyée en cas de succès ; sinon, il renvoie une erreur interne du serveur.
? Ici, nous allons construire les principaux composants de l'interface utilisateur et certaines API pour la mise à jour des tâches sur notre tableau
Maintenant, créons un
Dans le répertoire src/components, créez un nouveau fichier board.tsx avec les lignes de code suivantes :
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
C'est le composant dans lequel nous utiliserons la fonctionnalité principale d'un tableau Kanban, c'est-à-dire le glisser-déposer d'éléments. Pour cela, nous utiliserons notre package précédemment installé, react-beautiful-dnd. Le composant récupère d'abord la session utilisateur à l'aide de getSession et la définit dans l'état. Une fois la session disponible, elle effectue un appel API pour récupérer les tâches de l'utilisateur connecté et les stocke dans les tâches.
Il écoute les événements à deux sockets : tâches mises à jour, qui met à jour la liste des tâches, et tâches créées, qui ajoute une nouvelle tâche à la liste des tâches actuelle.
Les tâches sont regroupées par statut de colonne (0 pour « En cours », 1 pour « En attente » et 2 pour « Terminé ») à l'aide de la fonction tâchesByStatus. Le composant mappe ces statuts pour afficher chaque colonne avec les tâches correspondantes.
Le wrapper DragDropContext active la fonctionnalité glisser-déposer. Lorsqu'une tâche est déplacée, handleDragEnd envoie le nouvel ordre de tâche au serveur via un événement socket pour la synchronisation.
Chaque colonne est une zone déposable qui contient des composants de tâches déplaçables, permettant aux utilisateurs de réorganiser les tâches dans et entre les colonnes.
Maintenant, travaillons sur la route /api/tasks qui est chargée de renvoyer une liste de tâches utilisateur depuis la base de données.
Dans app/api/tasks, créez un fichier route.ts avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
La fonction GET de cette route API récupère les informations d'un utilisateur, y compris ses tâches. Cela commence par valider l'authentification à l'aide de getServerSession. Si la session est absente, un statut 401 non autorisé est renvoyé.
La route extrait l'e-mail et l'ID utilisateur des paramètres de requête de l'URL de la requête. Si l'ID utilisateur est manquant ou si l'e-mail de l'utilisateur de la session ne correspond pas à l'e-mail fourni, un statut 403 Forbidden est renvoyé.
Ensuite, il interroge la base de données pour un utilisateur avec l'e-mail et l'identifiant spécifiés, en sélectionnant uniquement l'identifiant et les tâches de l'utilisateur. Si aucun utilisateur n'est trouvé, un statut 404 Not Found est renvoyé. Si l'utilisateur existe, ses données sont envoyées dans la réponse.
Maintenant, nous avons presque terminé ; nous avons juste besoin d'écouter l'événement task-drag du
Modifiez le fichier server.ts à la racine du projet avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
L'événement task-drag est responsable de la gestion de la fonctionnalité glisser-déposer des tâches au sein de votre tableau Kanban. Lorsqu'une tâche est déplacée d'une position à une autre, cet événement est déclenché, permettant au serveur de mettre à jour le statut et la position de la tâche dans la base de données.
Lorsqu'un client émet l'événement « task-drag », il envoie une charge utile contenant les emplacements source et de destination de la tâche en cours de déplacement, ainsi que l'adresse e-mail de l'utilisateur. Le serveur écoute cet événement.
Le serveur appelle ensuite la fonction handleTaskDrag, en passant l'e-mail de l'utilisateur, la source et la destination comme arguments. Cette fonction est chargée de récupérer l'utilisateur de la base de données à l'aide de son adresse e-mail, garantissant que les mises à jour des tâches sont associées au bon utilisateur.
Dans handleTaskDrag, la fonction récupère les tâches de l'utilisateur dans la base de données puis appelle updateTasksInDB, qui traite la logique de mise à jour des tâches. Cette fonction met à jour la colonne et l'ordre des tâches en fonction de l'opération glisser-déposer, garantissant ainsi que les tâches sont correctement réorganisées dans la base de données.
Si les tâches sont mises à jour avec succès, les tâches mises à jour sont renvoyées à tous les clients connectés à l'aide de io.sockets.emit, diffusant les modifications afin que l'interface utilisateur puisse être mise à jour en temps réel.
Maintenant que nous avons à la fois l'option
Dans le répertoire src/app/kanban, créez un nouveau fichier page.tsx avec les lignes de code suivantes :
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Cela commence par vérifier la session de l'utilisateur avec getServerSession, en redirigeant vers la page de connexion si la session est absente. Cette instruction ne sera probablement jamais exécutée car nous avons créé un fichier middleware.ts plus tôt dans le répertoire src, qui indique que toute route commençant par /kanban n'est pas accessible aux utilisateurs non authentifiés.
Cependant, cela ne fait jamais de mal d'ajouter une couche supplémentaire de validation, car Next.js déduplique toutes les demandes en double similaires. Après avoir confirmé la session, il récupère l'identifiant de l'utilisateur dans la base de données ; si l'utilisateur n'est pas trouvé, il redirige vers la page d'inscription.
Enfin, il restitue les composants AddTask et Board, en transmettant l'ID de l'utilisateur comme accessoire.
Il reste une dernière chose : si vous l'avez remarqué, dans la zone
Dans le répertoire src/app/kanban/[taskId], créez un nouveau fichier page.tsx avec les lignes de code suivantes :
cd kanban-ai-realtime-localization
C'est pareil ici : on valide d'abord la séance. Comme mentionné précédemment, cela ne devrait jamais être exécuté en raison du middleware que nous avons déjà en place.
Ensuite, nous récupérons simplement la tâche de la base de données en utilisant le taskId que nous avons reçu en guise d'accessoire. Si la tâche n'existe pas, nous redirigeons l'utilisateur vers la page /kanban. Si elle existe, nous affichons le titre et la description de la tâche.
Enfin, travaillons sur la page d'accueil racine de notre application (/route). Modifiez le src/app/page.tsx avec les lignes de code suivantes :
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
Ici, on vérifie simplement si l'utilisateur est authentifié. Si tel est le cas, ils sont envoyés vers la route /kanban ; sinon, ils sont redirigés vers la page de connexion.
C'est littéralement tout ce que nous devons faire pour que notre tableau Kanban fonctionne parfaitement. Vous devriez désormais disposer d'un tableau Kanban entièrement fonctionnel avec authentification, localisation et assistance en temps réel. ?
Wow ! ?? Nous avons accompli beaucoup de choses ensemble aujourd’hui.
Si vous êtes arrivé jusqu'ici, vous avez réussi à créer un tableau Kanban basé sur l'IA et la localisation à partir de zéro, à l'aide d'un article de blog. Donnez-vous une tape dans le dos bien méritée !
Start le référentiel Tolgee ⭐
Suivez Tolgee pour plus de contenu comme celui-ci.
Partagez vos réflexions dans la section commentaires ci-dessous ! ?
Merci beaucoup d'avoir lu ! ? ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!