From 3b250b3217f1dbf302654e6405392ece5b5e8686 Mon Sep 17 00:00:00 2001 From: Ladebeze66 Date: Wed, 12 Feb 2025 18:26:22 +0100 Subject: [PATCH] effects --- app/components/ChatBot.js | 48 ++++++++----------- app/components/ContentSectionCompetences.tsx | 2 +- app/globals.css | 18 +++++++ app/layout.tsx | 29 +++++++++-- llm-api/__pycache__/api.cpython-313.pyc | Bin 1496 -> 714 bytes 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/app/components/ChatBot.js b/app/components/ChatBot.js index 1525d04..12913e3 100644 --- a/app/components/ChatBot.js +++ b/app/components/ChatBot.js @@ -1,65 +1,59 @@ -import { useState, useEffect } from "react"; +import { useState } from "react"; import { askAI } from "../utils/askAI"; -export default function ChatBot() { +export default function ChatBot({ onClose }) { const [question, setQuestion] = useState(""); const [messages, setMessages] = useState([]); - - // Afficher le message d'introduction une seule fois au chargement du chatbot - useEffect(() => { - const introMessage = { - sender: "bot", - text: "Bonjour ! Je suis GrasBot, une intelligence artificielle locale basée sur Mistral 7B et hébergée sur un serveur Windows. Je suis là pour répondre à vos questions. Posez-moi votre question ! 😊" - }; - setMessages([introMessage]); - }, []); + const [isWaiting, setIsWaiting] = useState(false); const handleAsk = async () => { - if (!question.trim()) return; // Évite d'envoyer un message vide + if (!question.trim()) return; const userMessage = { sender: "user", text: question }; - setMessages((prevMessages) => [...prevMessages, userMessage]); // Ajoute le message utilisateur + setMessages([...messages, userMessage]); - setQuestion(""); // Réinitialise le champ après l'envoi + setQuestion(""); + setIsWaiting(true); try { const botResponse = await askAI(question); const botMessage = { sender: "bot", text: botResponse }; - setMessages((prevMessages) => [...prevMessages, botMessage]); // Ajoute la réponse du bot + setMessages((prevMessages) => [...prevMessages, botMessage]); } catch (error) { - setMessages((prevMessages) => [ - ...prevMessages, - { sender: "bot", text: "❌ Erreur de réponse. Réessayez plus tard." } - ]); + setMessages([...messages, { sender: "bot", text: "❌ Erreur de réponse. Réessayez plus tard." }]); + } finally { + setIsWaiting(false); } }; return (
- {/* En-tête du chatbot */}
- 💬 GrasBot - + 💬 GrasBot +
- {/* Zone d'affichage des messages */}
{messages.map((msg, index) => (
{msg.text}
))} + {isWaiting && ( +
+ wait... +
+ )}
- {/* Zone d'entrée utilisateur */}
setQuestion(e.target.value)} @@ -73,4 +67,4 @@ export default function ChatBot() {
); -} +} \ No newline at end of file diff --git a/app/components/ContentSectionCompetences.tsx b/app/components/ContentSectionCompetences.tsx index a5106e4..3dfbebe 100644 --- a/app/components/ContentSectionCompetences.tsx +++ b/app/components/ContentSectionCompetences.tsx @@ -148,7 +148,7 @@ export default function ContentSectionCompetences({ {/* 🔥 Chatbot affiché uniquement si isChatbotOpen est vrai */} {isChatbotOpen && (
- + setIsChatbotOpen(false)} />
)} diff --git a/app/globals.css b/app/globals.css index 0f75502..ae2bd46 100644 --- a/app/globals.css +++ b/app/globals.css @@ -40,3 +40,21 @@ body { .animate-fade-in { animation: fade-in 0.5s ease-out; /* Animation de 0.5s avec une courbe de transition */ } + +@keyframes blink { + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } +} + +.wait-animation .dot-1 { + animation: blink 1s infinite 0s; +} + +.wait-animation .dot-2 { + animation: blink 1s infinite 0.2s; +} + +.wait-animation .dot-3 { + animation: blink 1s infinite 0.4s; +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 35dc329..f07eccf 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,15 +1,31 @@ "use client"; -import React from "react"; +import React, { useEffect, useState } from "react"; import Footer from "./components/Footer"; import "./assets/main.css"; import NavLink from "./components/NavLink"; export default function RootLayout({ children }) { + const [visitCount, setVisitCount] = useState(0); + + useEffect(() => { + // Récupère le compteur de visites depuis localStorage + const visits = localStorage.getItem("visitCount"); + const newVisitCount = visits ? parseInt(visits) + 1 : 1; + localStorage.setItem("visitCount", newVisitCount.toString()); + setVisitCount(newVisitCount); + }, []); + return ( -
+
+ {/* Cercles animés */} +
+
+
+
+

Portfolio Gras-Calvet Fernand

@@ -25,13 +41,18 @@ export default function RootLayout({ children }) {
{/* Ne pas forcer de largeur ici, chaque page gère son `main` */} -
+
{children}
+ + {/* Affichage du compteur de visites */} +
+ NV : {visitCount} +
); -} +} \ No newline at end of file diff --git a/llm-api/__pycache__/api.cpython-313.pyc b/llm-api/__pycache__/api.cpython-313.pyc index ffddb41bfaf422ecc23bb07b786cea79f0c68fdc..05807eeee16d8ae91a056689a3c71ef2088d6537 100644 GIT binary patch delta 537 zcmcb?eTudIGcPX}0}yQ4vpPMEk%8echyw%6P{!v3AY&>+Fhek-H-i^r5u*Z#&E(Bg z#1zA*#9#_lR>U04T*MN?9K;P3K%#WL`jG>4-C{{eEJ?h@QIuL-ke^qaS_}%3$v!Mb^@2bK2M`y7jC#q?!0>^MK}hHQ+YUjjlP`Su&-r#YATe#o0)3)3G0*lnoVvq$*21bmU z9JkohfIdzv$SeYxUjz!jTg-_C1x37IR(fj5E#~5qq9Tx`D;Yim$!LZm0gxPrO>TZl zX-=wLkpz$n3gTi5An}2jk&*E(gY<0%{)cS5&6y3%4+PB`_#QB_w2L>2cZfC1e_&!~ Yl%ApdnE^o|Vop*)mIWt@aYMzPbX2@z?ilr&07ng@7effS2qYfqdF>s@zd z9ok40h6vFjq=E#ZNIm3OiwhSHoc#~P3R0sf5&=%VxiS|nh;KI8CXBT6&G*gsn)&@^ zThVA3!T9x;AB#T+5c*3f{s7$@t-Bz;Lpsu>TWC?D(xOadEOhynLKRP{RLx0)XyP=4 z26Tl6b(LzD5e?-6neNk#b3zYHNGGZu%!PF=Cy%RoXaH@iud=ik5U4iplUzYOq}ZUK7z2VlX3g zhrsfE(=Iq4Gpq}preEd1ZLoUHbA~J>r%-V{$M5ce#A6-tt(pFYw zU9lBi%_2RZ2h)nJu7`Y|j7Mf)JCTEEJ>pxks;<2yXX3toCVk4;fe$7!oo9A`rHAyk ziPLkWqM{EylvOTE!)Q|3l#=0RpRc@Q>;QA$c& z-DZx>LzFOpj*-e$C^HARI99zjinj^2M}Qar5H4469)c0}!Z<}H)hE>{Kn zd9(tw++c(WxEYTutgK~L=dw4}7FJh8IS*aNRY2Y4vDKxendO-ccv2hL%o2rDA+8jO zn+#HcEfrVKH7})E;8DNZ4VT=7f(64hXbfDK@WbBV7Z;~;rF$tGJW_&XIm;@g;5Fvp zOPBBQ2oP$+=NP>JfgK{l=Pc4$}F64s6cqc-h-*BNRsqB8h(!A&r$my!RVe@RgOE~tj3zE-0_K2jWolkv%4BSmeeo$ iKJ9zZyZ2gC?vX|w4>b{pr&>#hmV)HYm%>gHko7;ol8d