can you patch my frontend code ? :
// src/components/Login.js
import React, { useState } from 'react';
import axios from 'axios';

function Login({ setUser }) {
  const [username, setUsername] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    axios.post('http://127.0.0.1:8000/login', { name: username })
      .then(response => {
        setUser(username);
      })
      .catch(error => {
        if (error.response) {
          setError(error.response.data.detail);
        } else {
          setError('Erreur de connexion au serveur.');
        }
      });
  };

  return (
    <div>
      <h2>Se connecter</h2>
      <form onSubmit={handleSubmit}>
        <label>Nom d'utilisateur :</label>
        <input type="text" value={username} onChange={e => setUsername(e.target.value)} required />
        <button type="submit">Se connecter</button>
      </form>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}

export default Login;

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);


// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';


import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { AuthProvider } from './contexts/AuthContext';
import Login from './components/Auth/Login';
import Signup from './components/Auth/Signup';
import Home from './components/Home';
import Chat from './components/Chat/Chat';
import Conversations from './components/Conversations/Conversations';
import Navbar from './components/Navbar';

function App() {
  return (
    <AuthProvider>
      <Router>
        <Navbar />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/login" element={<Login />} />
          <Route path="/signup" element={<Signup />} />
          <Route path="/conversations" element={<Conversations />} />
          <Route path="/chat/:conversationId" element={<Chat />} />
        </Routes>
      </Router>
    </AuthProvider>
  );
}

export default App;

import axios from 'axios';

const instance = axios.create({
  baseURL: process.env.REACT_APP_API_URL,
});

export default instance;

import React, { createContext, useState, useEffect } from 'react';
import axios from '../utils/api';

export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  // Charger l'utilisateur depuis le localStorage au démarrage
  useEffect(() => {
    const storedUser = localStorage.getItem('user');
    const storedToken = localStorage.getItem('token');
    if (storedUser && storedToken) {
      setUser(JSON.parse(storedUser));
      axios.defaults.headers.common['Authorization'] = `Bearer ${storedToken}`;
    }
  }, []);

  const login = async (username, password) => {
    const response = await axios.post('/login', {
      name: username,
      password: password,
    });
    const { access_token } = response.data;
    localStorage.setItem('token', access_token);
    axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;

    // Obtenir les informations de l'utilisateur courant
    const userResponse = await axios.get('/users/me');
    localStorage.setItem('user', JSON.stringify(userResponse.data));
    setUser(userResponse.data);
  };

  const signup = async (username, password) => {
    await axios.post('/signup', {
      name: username,
      password: password,
    });
    // Après l'inscription, effectuer la connexion
    await login(username, password);
  };

  const logout = () => {
    localStorage.removeItem('user');
    localStorage.removeItem('token');
    delete axios.defaults.headers.common['Authorization'];
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, login, signup, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

// Home.jsx
import React, { useContext } from 'react';
import { AuthContext } from '../contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
import styles from './Home.module.css';

function Home() {
  const { user } = useContext(AuthContext);
  const navigate = useNavigate();

  const handleLogin = () => navigate('/login');
  const handleSignUp = () => navigate('/signup');
  const handleStartChat = () => navigate('/conversations');

  return (
    <div className={styles.container}>
      

      <main className={styles.content}>
        {user ? (
          <div className={styles.authenticatedContent}>
            <div className={styles.avatarWrapper}>
              <div className={styles.avatar}>
                {user.name.charAt(0).toUpperCase()}
              </div>
            </div>

            <h2 className={styles.welcomeText}>
              Ravi de vous revoir, <span className={styles.userName}>{user.name}</span>
            </h2>

            <button 
              className={styles.mainButton}
              onClick={handleStartChat}
            >
              Accéder aux conversations
            </button>
          </div>
        ) : (
          <div className={styles.unauthenticatedContent}>
            <h2 className={styles.heroTitle}>
              Connectez-vous pour commencer
            </h2>
            <p className={styles.heroText}>
              Rejoignez une communauté dynamique et échangez en temps réel
            </p>

            <div className={styles.actionButtons}>
              <button
                className={`${styles.mainButton} ${styles.loginButton}`}
                onClick={handleLogin}
              >
                Se connecter
              </button>

              <button
                className={`${styles.mainButton} ${styles.signupButton}`}
                onClick={handleSignUp}
              >
                Créer un compte
              </button>
            </div>

            <div className={styles.features}>
              <div className={styles.featureItem}>
                <span className={styles.featureIcon}>🔒</span>
                <p>Messagerie sécurisée</p>
              </div>
              <div className={styles.featureItem}>
                <span className={styles.featureIcon}>⚡</span>
                <p>Temps réel</p>
              </div>
              <div className={styles.featureItem}>
                <span className={styles.featureIcon}>🌐</span>
                <p>Accessible partout</p>
              </div>
            </div>
          </div>
        )}
      </main>
    </div>
  );
}

export default Home;

// Navbar.jsx
import React, { useContext } from 'react';
import { Link } from 'react-router-dom';
import { AuthContext } from '../contexts/AuthContext';
import styles from './Navbar.module.css';

function Navbar() {
  const { user, logout } = useContext(AuthContext);

  return (
    <nav className={styles.navbar}>
      <div className={styles.navbarContainer}>
        <Link to="/" className={styles.navbarLogo}>
          ChatApp
        </Link>

        <div className={styles.navbarContent}>
          {user ? (
            <div className={styles.authenticatedNav}>
              <div className={styles.navLinks}>
                <Link to="/conversations" className={styles.navLink}>
                  Conversations
                </Link>
                <Link to="/profile" className={styles.navLink}>
                  Profil
                </Link>
              </div>
              
              <div className={styles.userSection}>
                <div className={styles.userInfo}>
                  <div className={styles.userAvatar}>
                    {user.name ? user.name.charAt(0).toUpperCase() : '?'}
                  </div>
                  <span className={styles.userName}>
                    {user.name || user.email}
                  </span>
                </div>
                <button 
                  onClick={logout} 
                  className={styles.logoutButton}
                >
                  Déconnexion
                </button>
              </div>
            </div>
          ) : (
            <div className={styles.authButtons}>
              <Link to="/login" className={styles.loginButton}>
                Se connecter
              </Link>
              <Link to="/signup" className={styles.signupButton}>
                S'inscrire
              </Link>
            </div>
          )}
        </div>
      </div>
    </nav>
  );
}

export default Navbar;

import React, { useEffect, useState, useContext } from 'react';
import { AuthContext } from '../../contexts/AuthContext';
import axios from '../../utils/api';
import { Link } from 'react-router-dom';
import styles from './Conversations.module.css';

function Conversations() {
  const { user } = useContext(AuthContext);
  const [conversations, setConversations] = useState([]);
  const [users, setUsers] = useState([]);
  const [isNewConvoOpen, setIsNewConvoOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchData();
  }, [user.name]);

  const fetchData = async () => {
    try {
      setLoading(true);
      const [convoResponse, usersResponse] = await Promise.all([
        axios.get('/conversations'),
        axios.get('/users')
      ]);
      
      setConversations(convoResponse.data);
      setUsers(usersResponse.data.filter(u => u.name !== user.name));
    } catch (error) {
      console.error('Erreur lors du chargement des données:', error);
    } finally {
      setLoading(false);
    }
  };

  const handleNewConversation = async (selectedUser) => {
    try {
      await axios.post('/conversations', [selectedUser]);
      await fetchData();
      setIsNewConvoOpen(false);
    } catch (error) {
      console.error('Erreur lors de la création de la conversation:', error);
    }
  };

  const filteredUsers = users.filter(u => 
    u.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  const LoadingSpinner = () => (
    <div className={styles.loadingSpinner}>
      <div className={styles.spinner}></div>
    </div>
  );

  return (
    <div className={styles.pageContainer}>
      <div className={styles.conversationsWrapper}>
        <header className={styles.header}>
          <div className={styles.headerTop}>
            <h1 className={styles.title}>Messages</h1>
            <button 
              className={styles.newChatBtn}
              onClick={() => setIsNewConvoOpen(true)}
              aria-label="Nouvelle conversation"
            >
              <span>+</span>
            </button>
          </div>
        </header>

        {loading ? (
          <LoadingSpinner />
        ) : (
          <div className={styles.conversationsList}>
            {conversations.length === 0 ? (
              <div className={styles.emptyState}>
                <p>Aucune conversation pour le moment</p>
                <button 
                  onClick={() => setIsNewConvoOpen(true)}
                  className={styles.startChatBtn}
                >
                  Démarrer une conversation
                </button>
              </div>
            ) : (
              conversations.map((convo) => {
                const otherParticipant = convo.participants.find(
                  name => name !== user.name
                );
                return (
                  <Link 
                    to={`/chat/${convo.id}`} 
                    key={convo.id}
                    className={styles.conversationCard}
                  >
                    <div className={styles.avatarContainer}>
                      <div className={styles.avatar}>
                        {otherParticipant.charAt(0).toUpperCase()}
                      </div>
                    </div>
                    <div className={styles.conversationDetails}>
                      <h3>{otherParticipant}</h3>
                    </div>
                  </Link>
                );
              })
            )}
          </div>
        )}
      </div>

      {isNewConvoOpen && (
        <div className={styles.modalOverlay} onClick={() => setIsNewConvoOpen(false)}>
          <div className={styles.modal} onClick={e => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2>Nouvelle conversation</h2>
              <button 
                className={styles.closeBtn}
                onClick={() => setIsNewConvoOpen(false)}
              >
                ×
              </button>
            </div>
            
            <div className={styles.searchContainer}>
              <input
                type="text"
                placeholder="Rechercher un utilisateur..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className={styles.searchInput}
              />
            </div>

            <div className={styles.usersList}>
              {filteredUsers.map((u) => (
                <div 
                  key={u.name} 
                  className={styles.userCard}
                  onClick={() => handleNewConversation(u.name)}
                >
                  <div className={styles.avatar}>
                    {u.name.charAt(0).toUpperCase()}
                  </div>
                  <span>{u.name}</span>
                </div>
              ))}
              {filteredUsers.length === 0 && (
                <div className={styles.noResults}>
                  Aucun utilisateur trouvé
                </div>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

export default Conversations;

import React, { useEffect, useState, useContext, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import axios from '../../utils/api';
import { AuthContext } from '../../contexts/AuthContext';
import styles from './Chat.module.css';

function Chat() {
  const { conversationId } = useParams();
  const { user } = useContext(AuthContext);
  const navigate = useNavigate();
  const [conversation, setConversation] = useState(null);
  const [messageText, setMessageText] = useState('');
  const [loading, setLoading] = useState(true);
  const messagesEndRef = useRef(null);
  const chatBoxRef = useRef(null);

  useEffect(() => {
    fetchConversation();
    const interval = setInterval(fetchConversation, 3000);
    return () => clearInterval(interval);
  }, [conversationId]);

  useEffect(() => {
    scrollToBottom();
  }, [conversation?.messages]);

  const fetchConversation = async () => {
    try {
      const response = await axios.get(`/conversations/${conversationId}`);
      setConversation(response.data);
      setLoading(false);
    } catch (err) {
      console.error(err);
      setLoading(false);
    }
  };

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  const handleSendMessage = async (e) => {
    e.preventDefault();
    if (messageText.trim() === '') return;

    try {
      const message = {
        sender: user.name,
        message: messageText,
        timestamp: new Date().toISOString(),
      };
      await axios.post(`/conversations/${conversationId}/messages`, message);
      setConversation((prev) => ({
        ...prev,
        messages: [...prev.messages, message],
      }));
      setMessageText('');
    } catch (err) {
      console.error(err);
    }
  };

  const formatTime = (timestamp) => {
    return new Date(timestamp).toLocaleTimeString([], {
      hour: '2-digit',
      minute: '2-digit'
    });
  };

  if (loading) {
    return <div className={styles.loading}>Chargement...</div>;
  }

  if (!conversation) {
    return (
      <div className={styles.notFound}>
        <h2>Conversation non trouvée</h2>
        <button onClick={() => navigate('/conversations')} className={styles.backButton}>
          Retour aux conversations
        </button>
      </div>
    );
  }

  const otherParticipant = conversation.participants.find(
    (name) => name !== user.name
  );

  return (
    <div className={styles.chatContainer}>
      <div className={styles.header}>
        <button
          className={styles.backButton}
          onClick={() => navigate('/conversations')}
        >
          ←
        </button>
        <div className={styles.participantInfo}>
          <div className={styles.avatar}>{otherParticipant.charAt(0).toUpperCase()}</div>
          <span>{otherParticipant}</span>
        </div>
      </div>

      <div className={styles.messagesContainer} ref={chatBoxRef}>
        {conversation.messages.map((msg, index) => (
          <div
            key={index}
            className={`${styles.messageWrapper} ${
              msg.sender === user.name ? styles.sent : styles.received
            }`}
          >
            <div className={styles.message}>
              <p>{msg.message}</p>
              <span className={styles.timestamp}>
                {formatTime(msg.timestamp)}
              </span>
            </div>
          </div>
        ))}
        <div ref={messagesEndRef} />
      </div>

      <form onSubmit={handleSendMessage} className={styles.inputContainer}>
        <input
          type="text"
          value={messageText}
          onChange={(e) => setMessageText(e.target.value)}
          placeholder="Écrivez votre message..."
          className={styles.messageInput}
        />
        <button 
          type="submit" 
          className={styles.sendButton}
          disabled={!messageText.trim()}
        >
          Envoyer
        </button>
      </form>
    </div>
  );
}

export default Chat;

import React, { useState, useContext } from 'react';
import { AuthContext } from '../../contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
import styles from './Login.module.css';

function Login() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const { login } = useContext(AuthContext);
  const [error, setError] = useState('');
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      await login(username, password);
      navigate('/');
    } catch (err) {
      setError('Nom d\'utilisateur ou mot de passe incorrect');
    }
  };

  return (
    <div className={styles.loginContainer}>
      <div className={styles.loginBox}>
        <h2 className={styles.title}>Se connecter</h2>
        <form onSubmit={handleSubmit} className={styles.form}>
          <div className={styles.inputGroup}>
            <label htmlFor="username">Nom d'utilisateur</label>
            <input
              id="username"
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              required
              className={styles.input}
            />
          </div>
          <div className={styles.inputGroup}>
            <label htmlFor="password">Mot de passe</label>
            <input
              id="password"
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
              className={styles.input}
            />
          </div>
          <button type="submit" className={styles.submitButton}>
            Se connecter
          </button>
        </form>
        {error && <p className={styles.error}>{error}</p>}
      </div>
    </div>
  );
}

export default Login;

import React, { useState, useContext } from 'react';
import { AuthContext } from '../../contexts/AuthContext';
import { useNavigate, Link } from 'react-router-dom';
import styles from './Signup.module.css';

function Signup() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const { signup } = useContext(AuthContext);
  const [error, setError] = useState('');
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      await signup(username, password);
      navigate('/');
    } catch (err) {
      setError('Erreur lors de l\'inscription');
    }
  };

  return (
    <div className={styles.container}>
      <div className={styles.overlay}></div>
      <div className={styles.formContainer}>
        <h1 className={styles.logo}>ChatApp</h1>
        <h2 className={styles.title}>Créer un compte</h2>
        
        <form onSubmit={handleSubmit} className={styles.form}>
          <div className={styles.inputField}>
            <input
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              required
              placeholder="Nom d'utilisateur"
            />
          </div>

          <div className={styles.inputField}>
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
              placeholder="Mot de passe"
            />
          </div>

          {error && <div className={styles.error}>{error}</div>}

          <button type="submit" className={styles.button}>
            S'inscrire
          </button>
        </form>

        <Link to="/login" className={styles.link}>
          Déjà un compte ? Se connecter
        </Link>
      </div>
    </div>
  );
}

export default Signup;

# models.py
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime

# Modèles pour l'utilisateur
class UserBase(BaseModel):
    name: str

class UserCreate(UserBase):
    password: str

class UserInDB(UserBase):
    hashed_password: str

class User(UserBase):
    id: str

# Modèles pour les messages
class Message(BaseModel):
    sender: str
    message: str
    timestamp: datetime = Field(default_factory=datetime.utcnow)

# Modèles pour les conversations
class Conversation(BaseModel):
    id: str
    participants: List[str]
    messages: List[Message] = []

from fastapi import FastAPI, Depends, HTTPException, status
from typing import List
from fastapi.middleware.cors import CORSMiddleware
from models import *
from authentication import *
from config import *
from database import *
from bson.objectid import ObjectId
import bcrypt
import os
from fastapi import FastAPI


app = FastAPI()

# CORS Configuration
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
def read_root():
    return {"message": "Hello, world!"}

@app.post("/signup", response_model=User)
def signup(user: UserCreate):
    # Vérifier si l'utilisateur existe déjà
    if users_collection.find_one({"name": user.name}):
        raise HTTPException(status_code=400, detail="Un utilisateur avec ce nom existe déjà.")
    
    # asher le mot de passe
    hashed_password = bcrypt.hashpw(user.password.encode('utf-8'), bcrypt.gensalt())
    
    # Créer l'utilisateur
    user_doc = {
        "name": user.name,
        "password": hashed_password.decode('utf-8')
    }
    result = users_collection.insert_one(user_doc)
    return User(id=str(result.inserted_id), name=user.name)

@app.post("/login")
def login(form_data: UserCreate):
    user = authenticate_user(users_collection, form_data.name, form_data.password)
    if not user:
        raise HTTPException(status_code=400, detail="Nom d'utilisateur ou mot de passe incorrect")
    
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.name}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

# ---- Gestion des conversations ----

@app.post("/conversations", response_model=Conversation)
def create_conversation(participants: List[str], current_user: UserInDB = Depends(get_current_user)):
    # Ajouter l'utilisateur courant aux participants s'il n'est pas déjà présent
    if current_user.name not in participants:
        participants.append(current_user.name)
    
    # Vérifier que les utilisateurs existent
    for name in participants:
        if not users_collection.find_one({"name": name}):
            raise HTTPException(status_code=404, detail=f"Utilisateur {name} introuvable")
    
    # Vérifier si la conversation existe déjà
    conversation = conversations_collection.find_one({"participants": {"$all": participants}})
    if conversation:
        raise HTTPException(status_code=400, detail="La conversation existe déjà")
    
    # Créer la conversation
    conversation_doc = {
        "participants": participants,
        "messages": []
    }
    result = conversations_collection.insert_one(conversation_doc)
    return Conversation(id=str(result.inserted_id), participants=participants)

@app.get("/conversations", response_model=List[Conversation])
def get_user_conversations(current_user: UserInDB = Depends(get_current_user)):
    conversations = conversations_collection.find({"participants": current_user.name})
    convo_list = []
    for convo in conversations:
        convo_list.append(Conversation(
            id=str(convo['_id']),
            participants=convo["participants"]
        ))
    return convo_list

@app.get("/conversations/{conversation_id}", response_model=Conversation)
def get_conversation(conversation_id: str, current_user: UserInDB = Depends(get_current_user)):
    conversation = conversations_collection.find_one({"_id": ObjectId(conversation_id)})
    if not conversation:
        raise HTTPException(status_code=404, detail="Conversation non trouvée")
    if current_user.name not in conversation["participants"]:
        raise HTTPException(status_code=403, detail="Accès refusé")
    messages = [Message(**msg) for msg in conversation.get("messages", [])]
    return Conversation(
        id=str(conversation['_id']),
        participants=conversation["participants"],
        messages=messages
    )

@app.post("/conversations/{conversation_id}/messages", response_model=Message)
def send_message(conversation_id: str, message: Message, current_user: UserInDB = Depends(get_current_user)):
    conversation = conversations_collection.find_one({"_id": ObjectId(conversation_id)})
    if not conversation:
        raise HTTPException(status_code=404, detail="Conversation non trouvée")
    if current_user.name not in conversation["participants"]:
        raise HTTPException(status_code=403, detail="Accès refusé")
    
    message_doc = message.dict()
    message_doc["timestamp"] = message.timestamp

    conversations_collection.update_one(
        {"_id": ObjectId(conversation_id)},
        {"$push": {"messages": message_doc}}
    )
    return message

@app.delete("/conversations/{conversation_id}")
def delete_conversation(conversation_id: str, current_user: UserInDB = Depends(get_current_user)):
    conversation = conversations_collection.find_one({"_id": ObjectId(conversation_id)})
    if not conversation:
        raise HTTPException(status_code=404, detail="Conversation non trouvée")
    if current_user.name not in conversation["participants"]:
        raise HTTPException(status_code=403, detail="Accès refusé")
    
    conversations_collection.delete_one({"_id": ObjectId(conversation_id)})
    return {"detail": "Conversation supprimée"}

# ---- Gestion des utilisateurs connectés ----

@app.get("/users/me", response_model=UserBase)
def read_current_user(current_user: UserInDB = Depends(get_current_user)):
    return UserBase(name=current_user.name)

@app.get("/users", response_model=List[UserBase])
def get_all_users(current_user: UserInDB = Depends(get_current_user)):
    users = users_collection.find({})
    return [UserBase(name=user["name"]) for user in users]

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

# authentication.py
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from database import users_collection
from models import UserInDB
from config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES
import bcrypt

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# Fonction pour vérifier l'utilisateur
def verify_password(plain_password, hashed_password):
    return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))

# Fonction pour récupérer l'utilisateur
def get_user(db, username: str):
    user = db.find_one({"name": username})
    if user:
        return UserInDB(name=user["name"], hashed_password=user["password"])
    return None

# Fonction pour authentifier l'utilisateur
def authenticate_user(db, username: str, password: str):
    user = get_user(db, username)
    if not user:
        return False
    if not verify_password(password, user.hashed_password):
        return False
    return user

# Fonction pour créer un token d'accès
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta if expires_delta else timedelta(minutes=15))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

# Fonction pour obtenir l'utilisateur actuel
async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=401,
        detail="Impossible de valider les informations d'identification",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        user = get_user(users_collection, username)
        if user is None:
            raise credentials_exception
        return user
    except JWTError:
        raise credentials_exception

import os

MONGODB_URI = os.environ.get("MONGODB_URI")
SECRET_KEY = os.environ.get("SECRET_KEY")
ALGORITHM = os.environ.get("ALGORITHM", "HS256")
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.environ.get("ACCESS_TOKEN_EXPIRE_MINUTES", 30))

# database.py
from pymongo import MongoClient
from config import MONGODB_URI

client = MongoClient(MONGODB_URI)
db = client["FIRSTSERv"]
users_collection = db["users"]
conversations_collection = db["conversations"]

# models.py
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime

# Modèles pour l'utilisateur
class UserBase(BaseModel):
    name: str

class UserCreate(UserBase):
    password: str

class UserInDB(UserBase):
    hashed_password: str

class User(UserBase):
    id: str

# Modèles pour les messages
class Message(BaseModel):
    sender: str
    message: str
    timestamp: datetime = Field(default_factory=datetime.utcnow)

# Modèles pour les conversations
class Conversation(BaseModel):
    id: str
    participants: List[str]
    messages: List[Message] = []
const reportWebVitals = onPerfEntry => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};

export default reportWebVitals;
adapt my code for localhost  and work with npm install