this is my app in pythoon and frontend suggest me 10 feature i can add for improve it and deploy on render :
from fastapi import FastAPI, Depends, HTTPException, status
from typing import List, Optional
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
from pydantic import BaseModel
from datetime import timedelta

app = FastAPI()

# Configuration CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # Adjust based on your frontend's URL
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Modèle pour la mise à jour de la bio
class BioUpdate(BaseModel):
    bio: str

# Inscription d'un nouvel utilisateur
@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à.")

    # Hasher 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'),
        "bio": user.bio or ""  # Initialiser la bio
    }
    result = users_collection.insert_one(user_doc)
    return User(
        id=str(result.inserted_id),
        name=user.name,
        bio=user.bio or ""
    )

# Connexion d'un utilisateur (Endpoint token mis à jour)
@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 bios ----

# Récupérer le profil de l'utilisateur courant
@app.get("/users/me", response_model=User)
def read_current_user(current_user: UserInDB = Depends(get_current_user)):
    user = users_collection.find_one({"name": current_user.name})
    return User(
        id=str(user["_id"]),
        name=user["name"],
        bio=user.get("bio", "")
    )

# Mettre à jour la bio de l'utilisateur courant
@app.put("/users/me/bio", response_model=UserBase)
def update_bio(bio_update: BioUpdate, current_user: UserInDB = Depends(get_current_user)):
    users_collection.update_one(
        {"name": current_user.name},
        {"$set": {"bio": bio_update.bio}}
    )
    updated_user = users_collection.find_one({"name": current_user.name})
    return UserBase(
        name=updated_user["name"],
        bio=updated_user.get("bio", "")
    )

# Récupérer le profil d'un utilisateur par nom
@app.get("/users/{username}", response_model=UserBase)
def get_user_profile(username: str, current_user: UserInDB = Depends(get_current_user)):
    user = users_collection.find_one({"name": username})
    if not user:
        raise HTTPException(status_code=404, detail="Utilisateur non trouvé")
    return UserBase(
        name=user["name"],
        bio=user.get("bio", "")
    )

# Récupérer tous les utilisateurs
@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"], bio=user.get("bio", "")) for user in users]

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

# Modèle pour la création d'une conversation
class ConversationCreate(BaseModel):
    participants: List[str]
    name: Optional[str] = None

@app.post("/conversations", response_model=Conversation)
def create_conversation(convo: ConversationCreate, current_user: UserInDB = Depends(get_current_user)):
    participants = convo.participants
    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")

    # Si c'est une conversation individuelle sans nom, vérifier si elle existe déjà
    if len(participants) == 2 and not convo.name:
        existing_convo = conversations_collection.find_one({
            "participants": {"$all": participants},
            "name": {"$exists": False}
        })
        if existing_convo:
            raise HTTPException(status_code=400, detail="La conversation existe déjà")

    # Créer la conversation
    conversation_doc = {
        "participants": participants,
        "messages": [],
    }
    if convo.name:
        conversation_doc["name"] = convo.name

    result = conversations_collection.insert_one(conversation_doc)
    return Conversation(
        id=str(result.inserted_id),
        name=convo.name,
        participants=participants
    )

# Récupérer les conversations de l'utilisateur courant
@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']),
            name=convo.get("name"),
            participants=convo["participants"]
        ))
    return convo_list

# Récupérer une conversation par son ID
@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']),
        name=conversation.get("name"),
        participants=conversation["participants"],
        messages=messages
    )

# Envoyer un message dans une conversation
@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

# Supprimer une conversation
@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"}

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 le mot de passe
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 un utilisateur depuis la base de données
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 un 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 JWT
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)

# Dépendance pour obtenir l'utilisateur courant
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
from dotenv import load_dotenv

# Charger les variables d'environnement depuis un fichier .env
load_dotenv()

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
    bio: Optional[str] = None  # Ajout du champ bio

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
    content: str
    timestamp: datetime = Field(default_factory=datetime.utcnow)

# Modèles pour les conversations
class Conversation(BaseModel):
    id: str
    name: Optional[str] = None  # Nom du groupe (optionnel)
    participants: List[str]
    messages: List[Message] = []

// src/components/Auth/Login.js
import React, { useState, useContext } from 'react';
import { AuthContext } from '../../contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
import { motion } from 'framer-motion';
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 (
    <motion.div
      className={styles.loginContainer}
      initial={{ opacity: 0, scale: 0.9 }}
      animate={{ opacity: 1, scale: 1 }}
      transition={{ duration: 0.5 }}
    >
      <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>
    </motion.div>
  );
}

export default Login;

.loginContainer {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #000000;
}

.loginBox {
  background-color: #1C1C1E;
  padding: 2rem;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 400px;
}

.title {
  color: #FFFFFF;
  text-align: center;
  margin-bottom: 2rem;
  font-size: 1.5rem;
}

.form {
  display: flex;
  flex-direction: column;
}

.inputGroup {
  margin-bottom: 1rem;
}

.inputGroup label {
  display: block;
  color: #FFFFFF;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

.input {
  width: 100%;
  padding: 0.75rem;
  border: none;
  border-radius: 5px;
  background-color: #2C2C2E;
  color: #FFFFFF;
  font-size: 1rem;
}

.submitButton {
  background: linear-gradient(45deg, #FF416C, #FF4B2B);
  border: none;
  color: white;
  padding: 0.75rem;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 1rem;
  font-weight: bold;
  margin-top: 1rem;
}

.submitButton:hover {
  background: linear-gradient(45deg, #FF4B2B, #FF416C);
  box-shadow: 0 2px 10px rgba(255, 75, 43, 0.3);
}

.error {
  color: #FF416C;
  text-align: center;
  margin-top: 1rem;
  font-size: 0.9rem;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.loginBox {
  animation: fadeIn 0.5s ease-in-out;
}

// src/components/Auth/Signup.js
import React, { useState, useContext } from 'react';
import { AuthContext } from '../../contexts/AuthContext';
import { useNavigate, Link } from 'react-router-dom';
import { motion } from 'framer-motion';
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 (
    <motion.div
      className={styles.container}
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
    >
      <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>
    </motion.div>
  );
}

export default Signup;

/* Base container */
.container {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(45deg, #000000, #1a1a1a);
  position: relative;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

/* Overlay effect */
.overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(5px);
  z-index: 1;
}

/* Form container */
.formContainer {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 400px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  padding: 40px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  animation: fadeIn 0.5s ease-out;
}

/* Logo styling */
.logo {
  font-size: 2rem;
  font-weight: 700;
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-align: center;
  margin-bottom: 20px;
}

/* Title styling */
.title {
  color: #ffffff;
  font-size: 1.5rem;
  text-align: center;
  margin-bottom: 30px;
  font-weight: 500;
  letter-spacing: 0.5px;
}

/* Form styling */
.form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Input field container */
.inputField {
  position: relative;
}

/* Input styling */
.inputField input {
  width: 100%;
  padding: 15px 20px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  color: white;
  font-size: 16px;
  transition: all 0.3s ease;
}

/* Input focus state */
.inputField input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.15);
  box-shadow: 0 0 0 4px rgba(220, 39, 67, 0.1);
}

/* Input placeholder */
.inputField input::placeholder {
  color: rgba(255, 255, 255, 0.6);
}

/* Button styling */
.button {
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743);
  color: white;
  padding: 15px;
  border: none;
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  text-transform: uppercase;
  letter-spacing: 1px;
}

/* Button hover state */
.button:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(220, 39, 67, 0.2);
}

/* Button active state */
.button:active {
  transform: translateY(0);
}

/* Error message styling */
.error {
  color: #ff4444;
  font-size: 14px;
  text-align: center;
  background: rgba(255, 68, 68, 0.1);
  padding: 12px;
  border-radius: 8px;
  border: 1px solid rgba(255, 68, 68, 0.2);
  margin-top: -10px;
}

/* Link styling */
.link {
  display: block;
  text-align: center;
  color: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  margin-top: 30px;
  font-size: 14px;
  transition: all 0.3s ease;
  padding: 10px;
}

/* Link hover state */
.link:hover {
  color: white;
  text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}

/* Animation keyframes */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Loading state for button */
.button.loading {
  opacity: 0.8;
  cursor: wait;
}

/* Success state for input */
.inputField.success input {
  border-color: #4CAF50;
}

/* Error state for input */
.inputField.error input {
  border-color: #ff4444;
}

/* Responsive design */
@media (max-width: 480px) {
  .formContainer {
    padding: 30px 20px;
  }

  .title {
    font-size: 1.3rem;
  }

  .inputField input {
    padding: 12px 15px;
  }

  .button {
    padding: 12px;
  }
}

/* Medium screens */
@media (max-width: 768px) {
  .formContainer {
    max-width: 90%;
  }
}

/* Custom scrollbar */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
}

::-webkit-scrollbar-thumb {
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(45deg, #dc2743, #cc2366, #bc1888);
}

/* Focus visible outline */
:focus-visible {
  outline: 2px solid #dc2743;
  outline-offset: 2px;
}

/* Disable autofill background */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: white;
  -webkit-box-shadow: 0 0 0px 1000px rgba(255, 255, 255, 0.1) inset;
  transition: background-color 5000s ease-in-out 0s;
}

/* Selection style */
::selection {
  background: rgba(220, 39, 67, 0.3);
  color: white;
}

/* Smooth transitions */
* {
  transition: all 0.3s ease;
}

/* Remove focus outline for mouse users */
*:focus:not(:focus-visible) {
  outline: none;
}

// src/components/Chat/Chat.jsx
import React, { useEffect, useState, useContext, useRef } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import axios from '../../utils/api';
import { AuthContext } from '../../contexts/AuthContext';
import { IoSend, IoMenu, IoSearch, IoEllipsisVertical, IoAdd } from 'react-icons/io5';
import styles from './Chat.module.css';

// Importer le composant Modal
import CreateConversationModal from './CreateConversationModal';

function Chat() {
  const { conversationId } = useParams();
  const { user } = useContext(AuthContext);
  const navigate = useNavigate();
  const [conversations, setConversations] = useState([]);
  const [currentConversation, setCurrentConversation] = useState(null);
  const [message, setMessage] = useState('');
  const [searchQuery, setSearchQuery] = useState('');
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
  const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
  const messagesEndRef = useRef(null);

  // Animation variants
  const sidebarVariants = {
    hidden: { x: -300, opacity: 0 },
    visible: { x: 0, opacity: 1, transition: { type: "spring", damping: 25 } }
  };

  const messageVariants = {
    hidden: { opacity: 0, y: 20 },
    visible: { opacity: 1, y: 0 },
    exit: { opacity: 0, x: -100 }
  };

  useEffect(() => {
    fetchConversations();
    const interval = setInterval(fetchConversations, 5000);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    if (conversationId) {
      fetchCurrentConversation();
      const interval = setInterval(fetchCurrentConversation, 3000);
      return () => clearInterval(interval);
    } else {
      setCurrentConversation(null); // Réinitialiser si pas de conversation sélectionnée
    }
  }, [conversationId]);

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

  const fetchConversations = async () => {
    try {
      const response = await axios.get('/conversations');
      setConversations(response.data);
    } catch (error) {
      console.error('Error fetching conversations:', error);
    }
  };

  const fetchCurrentConversation = async () => {
    try {
      const response = await axios.get(`/conversations/${conversationId}`);
      setCurrentConversation({
        ...response.data,
        messages: response.data.messages || []
      });
    } catch (error) {
      console.error('Error fetching conversation:', error);
    }
  };

  const handleSendMessage = async (e) => {
    e.preventDefault();
    if (!message.trim()) return;

    try {
      const newMessage = {
        content: message,
        sender: user.name, // Use user.name instead of user.id
        timestamp: new Date().toISOString()
      };

      await axios.post(`/conversations/${conversationId}/messages`, newMessage);
      setMessage('');
      fetchCurrentConversation();
    } catch (error) {
      console.error('Error sending message:', error);
    }
  };

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

  const filteredConversations = conversations.filter(conv => {
    const conversationName = conv.name || '';
    return conversationName.toLowerCase().includes(searchQuery.toLowerCase());
  });

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

  // Fonction pour ouvrir le modal de création
  const openCreateModal = () => {
    setIsCreateModalOpen(true);
  };

  // Fonction pour fermer le modal de création
  const closeCreateModal = () => {
    setIsCreateModalOpen(false);
  };

  // Fonction pour créer une nouvelle conversation
  const handleCreateConversation = async (conversationData) => {
    try {
      const response = await axios.post('/conversations', conversationData);
      // Actualiser la liste des conversations
      fetchConversations();
      closeCreateModal();
      // Naviguer vers la nouvelle conversation
      navigate(`/chat/${response.data.id}`);
    } catch (error) {
      console.error('Error creating conversation:', error);
      // Optionally set error state here
    }
  };

  return (
    <motion.div
      className={styles.container}
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      transition={{ duration: 0.5 }}
    >
      {/* Sidebar */}
      <motion.aside
        className={`${styles.sidebar} ${isMobileMenuOpen ? styles.sidebarOpen : ''}`}
        variants={sidebarVariants}
        initial="hidden"
        animate="visible"
      >
        <div className={styles.sidebarHeader}>
          <motion.div
            className={styles.userProfile}
            whileHover={{ scale: 1.05 }}
            whileTap={{ scale: 0.95 }}
            onClick={() => navigate('/profile')}
          >
            <div className={styles.userAvatar}>{user.name[0].toUpperCase()}</div>
            <h3>{user.name}</h3>
          </motion.div>
        </div>

        <div className={styles.searchContainer}>
          <IoSearch className={styles.searchIcon} />
          <input
            type="text"
            placeholder="Rechercher une conversation..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className={styles.searchInput}
          />
        </div>

        <div className={styles.newConversationButton}>
          <button onClick={openCreateModal}>
            <IoAdd /> Nouvelle Conversation
          </button>
        </div>

        <div className={styles.conversationsList}>
          <AnimatePresence>
            {filteredConversations.map((conv) => (
              <motion.div
                key={conv.id}
                className={`${styles.conversationItem} ${
                  conv.id === conversationId ? styles.active : ''
                }`}
                variants={messageVariants}
                initial="hidden"
                animate="visible"
                exit="exit"
                whileHover={{ x: 5 }}
                onClick={() => {
                  navigate(`/chat/${conv.id}`);
                  setIsMobileMenuOpen(false);
                }}
              >
                <div className={styles.conversationAvatar}>
                  {(conv.name || '?')[0].toUpperCase()}
                </div>
                <div className={styles.conversationInfo}>
                  <h4>{conv.name || 'Conversation sans nom'}</h4>
                  <p>{conv.lastMessage?.content || 'Nouvelle conversation'}</p>
                </div>
                {conv.unreadCount > 0 && (
                  <div className={styles.unreadBadge}>
                    {conv.unreadCount}
                  </div>
                )}
              </motion.div>
            ))}
          </AnimatePresence>
        </div>
      </motion.aside>

      {/* Main Chat Area */}
      <main className={styles.chatArea}>
        {currentConversation ? (
          <>
            <header className={styles.chatHeader}>
              <button
                className={styles.menuButton}
                onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
              >
                <IoMenu />
              </button>
              <div className={styles.chatInfo}>
                <h2>{currentConversation.name}</h2>
                <span>{currentConversation.participants.length} participants</span>
              </div>
              <button className={styles.optionsButton}>
                <IoEllipsisVertical />
              </button>
            </header>

            <div className={styles.messagesContainer}>
              <AnimatePresence>
                {(currentConversation.messages || []).map((msg, index) => (
                  <motion.div
                    key={index}
                    className={`${styles.message} ${
                      msg.sender === user.name ? styles.sent : styles.received
                    }`}
                    variants={messageVariants}
                    initial="hidden"
                    animate="visible"
                    exit="exit"
                  >
                    <p>{msg.content}</p>
                    <span className={styles.timestamp}>
                      {formatTime(msg.timestamp)}
                    </span>
                  </motion.div>
                ))}
              </AnimatePresence>
              <div ref={messagesEndRef} />
            </div>

            <form onSubmit={handleSendMessage} className={styles.messageForm}>
              <motion.input
                type="text"
                value={message}
                onChange={(e) => setMessage(e.target.value)}
                placeholder="Écrivez votre message..."
                whileFocus={{ scale: 1.01 }}
                className={styles.messageInput}
              />
              <motion.button
                type="submit"
                disabled={!message.trim()}
                whileHover={{ scale: 1.05 }}
                whileTap={{ scale: 0.95 }}
                className={styles.sendButton}
              >
                <IoSend />
              </motion.button>
            </form>
          </>
        ) : (
          <motion.div
            className={styles.welcomeScreen}
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5 }}
          >
            <div className={styles.welcomeContent}>
              <h2>Bienvenue sur votre messagerie</h2>
              <p>Sélectionnez une conversation pour commencer à discuter</p>
            </div>
          </motion.div>
        )}
      </main>

      {/* Mobile Overlay */}
      {isMobileMenuOpen && (
        <motion.div
          className={styles.overlay}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          onClick={() => setIsMobileMenuOpen(false)}
        />
      )}

      {/* Modal pour la création de conversation */}
      {isCreateModalOpen && (
        <CreateConversationModal
          onClose={closeCreateModal}
          onCreate={handleCreateConversation}
        />
      )}
    </motion.div>
  );
}

export default Chat;

/* Chat.module.css */

.container {
  min-height: 100vh;
  width: 100%;
  background: #1e1e1e; /* Darker background for a sleek look */
  display: flex;
  position: relative;
  overflow: hidden;
  font-family: 'Inter', sans-serif; /* Modern sans-serif font */
}

/* Animated Background with Smooth Gradients */
.background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  overflow: hidden;
}

.gradient1, .gradient2, .gradient3 {
  position: absolute;
  border-radius: 50%;
  filter: blur(100px);
  opacity: 0.6; /* Reduced opacity for subtlety */
}

.gradient1 {
  width: 60%;
  height: 60%;
  background: linear-gradient(45deg, #4facfe, #00f2fe);
  top: -20%;
  left: -20%;
  animation: moveGradient1 25s infinite alternate;
}

.gradient2 {
  width: 70%;
  height: 70%;
  background: linear-gradient(45deg, #bc4e9c, #f80759);
  top: 50%;
  right: -30%;
  animation: moveGradient2 30s infinite alternate;
}

.gradient3 {
  width: 50%;
  height: 50%;
  background: linear-gradient(45deg, #f093fb, #f5576c);
  bottom: -20%;
  left: 30%;
  animation: moveGradient3 28s infinite alternate;
}

/* Sidebar with Enhanced Glassmorphism */
.sidebar {
  width: 300px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(15px);
  border-right: 1px solid rgba(255, 255, 255, 0.2);
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
}

/* Active Sidebar (for responsive design if needed) */
.sidebarOpen {
  transform: translateX(0);
}

.sidebarHeader {
  padding: 2rem;
  text-align: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.userProfile {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.userProfile:hover {
  transform: scale(1.05);
}

.userAvatar {
  width: 60px;
  height: 60px;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  color: white;
  border-radius: 50%;
  font-size: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 1rem;
  transition: box-shadow 0.3s ease;
}

.userAvatar:hover {
  box-shadow: 0 0 15px rgba(255, 65, 108, 0.6);
}

.userProfile h3 {
  color: white;
  font-size: 1.5rem;
  font-weight: 600;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.searchContainer {
  padding: 1rem 2rem;
  display: flex;
  align-items: center;
  position: relative;
}

.searchIcon {
  position: absolute;
  left: 2.5rem;
  font-size: 1.2rem;
  color: rgba(255, 255, 255, 0.6);
}

.searchInput {
  width: 100%;
  padding: 0.75rem 1rem 0.75rem 3rem; /* Increased left padding for icon */
  background: rgba(255, 255, 255, 0.05);
  border: none;
  border-radius: 25px;
  color: white;
  font-size: 1rem;
  transition: all 0.3s ease;
}

.searchInput::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.searchInput:focus {
  outline: none;
  border: 1px solid #FF416C;
  box-shadow: 0 0 10px rgba(255, 65, 108, 0.3);
}

.conversationsList {
  flex-grow: 1;
  overflow-y: auto;
  padding: 1rem;
}

.conversationItem {
  display: flex;
  align-items: center;
  padding: 1rem;
  border-radius: 12px;
  margin-bottom: 0.75rem;
  cursor: pointer;
  transition: background 0.3s ease, transform 0.3s ease;
}

.conversationItem:hover {
  background: rgba(255, 255, 255, 0.1);
  transform: translateY(-2px);
}

.active {
  background: rgba(255, 255, 255, 0.15);
}

.conversationAvatar {
  width: 50px;
  height: 50px;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  color: white;
  border-radius: 50%;
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 1rem;
  transition: box-shadow 0.3s ease;
}

.conversationAvatar:hover {
  box-shadow: 0 0 10px rgba(255, 65, 108, 0.6);
}

.conversationInfo h4 {
  color: white;
  font-size: 1rem;
  margin-bottom: 0.3rem;
  font-weight: 600;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.conversationInfo p {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.9rem;
}

.unreadBadge {
  background: #FF416C;
  color: white;
  border-radius: 12px;
  padding: 0.3rem 0.6rem;
  font-size: 0.75rem;
  margin-left: auto;
  transition: background 0.3s ease;
}

.unreadBadge:hover {
  background: #e63946;
}

/* Main Chat Area */
.chatArea {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background: #121212;
  position: relative;
}

/* Chat Header */
.chatHeader {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(15px);
  padding: 1.5rem 2rem;
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  position: relative;
}

.menuButton, .optionsButton {
  background: none;
  border: none;
  color: white;
  font-size: 1.5rem;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.menuButton:hover, .optionsButton:hover {
  transform: scale(1.1);
}

.chatInfo {
  flex-grow: 1;
  text-align: center;
}

.chatInfo h2 {
  color: white;
  font-size: 1.5rem;
  margin: 0;
  font-weight: 600;
}

.chatInfo span {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.9rem;
}

/* Messages Container */
.messagesContainer {
  flex-grow: 1;
  overflow-y: auto;
  padding: 2rem;
  background: #0a0a0a;
  position: relative;
  animation: fadeIn 1s ease-out;
}

.message {
  max-width: 70%;
  margin-bottom: 1.5rem;
  padding: 0.75rem 1.5rem;
  border-radius: 20px;
  position: relative;
  animation: slideIn 0.5s ease-out;
  color: white;
}

.sent {
  margin-left: auto;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
}

.received {
  margin-right: auto;
  background: rgba(255, 255, 255, 0.1);
}

.message p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.4;
}

.timestamp {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.7);
  text-align: right;
}

/* Message Form */
.messageForm {
  display: flex;
  align-items: center;
  padding: 1.5rem 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(15px);
}

.messageForm input[type="text"] {
  flex-grow: 1;
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 25px;
  background: rgba(255, 255, 255, 0.1);
  color: white;
  font-size: 1rem;
  transition: all 0.3s ease;
}

.messageForm input[type="text"]::placeholder {
  color: rgba(255, 255, 255, 0.7);
}

.messageForm input[type="text"]:focus {
  outline: none;
  border: 1px solid #FF416C;
  box-shadow: 0 0 10px rgba(255, 65, 108, 0.3);
}

.messageForm button {
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  border: none;
  border-radius: 50%;
  color: white;
  width: 50px;
  height: 50px;
  margin-left: 1rem;
  cursor: pointer;
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.messageForm button:hover {
  box-shadow: 0 5px 15px rgba(255, 65, 108, 0.4);
}

.messageForm button:active {
  transform: scale(0.95);
}

.messageForm button:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 65, 108, 0.3);
}

/* Welcome Screen */
.welcomeScreen {
  flex-grow: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  text-align: center;
  animation: fadeIn 1s ease-out;
}

.welcomeContent h2 {
  font-size: 2rem;
  color: white;
  margin-bottom: 1rem;
}

.welcomeContent p {
  font-size: 1rem;
  color: rgba(255, 255, 255, 0.7);
}

/* Mobile Overlay */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 2;
}

/* Keyframes Animations */
@keyframes moveGradient1 {
  0% { transform: translate(0, 0); }
  100% { transform: translate(100px, 50px); }
}

@keyframes moveGradient2 {
  0% { transform: translate(0, 0); }
  100% { transform: translate(-100px, -50px); }
}

@keyframes moveGradient3 {
  0% { transform: translate(0, 0); }
  100% { transform: translate(50px, -100px); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideIn {
  from { opacity: 0; transform: translateX(50px); }
  to { opacity: 1; transform: translateX(0); }
}

/* Custom Scrollbar */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(135deg, #FF4B2B, #FF416C);
}

/* Text Selection */
::selection {
  background: rgba(255, 65, 108, 0.3);
  color: white;
}

/* Global Transitions */
* {
  transition: all 0.3s ease;
}

/* Responsive Design */
@media (max-width: 768px) {
  .sidebar {
    position: fixed;
    left: -300px;
    top: 0;
    height: 100%;
    z-index: 3;
    transition: transform 0.3s ease;
  }

  .sidebarOpen {
    transform: translateX(300px);
  }

  .chatHeader {
    padding: 1rem 1.5rem;
  }

  .chatInfo h2 {
    font-size: 1.2rem;
  }

  .chatInfo span {
    font-size: 0.8rem;
  }

  .messagesContainer {
    padding: 1rem;
  }

  .messageForm {
    padding: 1rem;
  }

  .messageForm input[type="text"] {
    font-size: 0.9rem;
  }

  .messageForm button {
    width: 40px;
    height: 40px;
    font-size: 1rem;
  }
}

@media (max-width: 480px) {
  .userAvatar {
    width: 50px;
    height: 50px;
    font-size: 1rem;
  }

  .userProfile h3 {
    font-size: 1rem;
  }

  .searchInput {
    font-size: 0.9rem;
  }

  .conversationInfo h4 {
    font-size: 0.9rem;
  }

  .conversationInfo p {
    font-size: 0.8rem;
  }

  .chatHeader {
    padding: 0.5rem 1rem;
  }

  .chatInfo h2 {
    font-size: 1.2rem;
  }

  .messagesContainer {
    padding: 0.5rem 1rem;
  }

  .messageForm {
    padding: 0.5rem 1rem;
  }

  .messageForm input[type="text"] {
    font-size: 0.9rem;
  }

  .messageForm button {
    width: 40px;
    height: 40px;
    font-size: 1rem;
  }
}

/* Accessibility: Reduced Motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

// src/components/Chat/CreateConversationModal.jsx
import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import styles from './CreateConversationModal.module.css';
import axios from '../../utils/api';

function CreateConversationModal({ onClose, onCreate }) {
  const [name, setName] = useState('');
  const [participants, setParticipants] = useState([]);
  const [allUsers, setAllUsers] = useState([]);
  const [searchUser, setSearchUser] = useState('');
  const [error, setError] = useState('');

  useEffect(() => {
    fetchAllUsers();
  }, []);

  const fetchAllUsers = async () => {
    try {
      const response = await axios.get('/users');
      setAllUsers(response.data);
    } catch (error) {
      console.error('Error fetching users:', error);
      setError('Erreur lors du chargement des utilisateurs.');
    }
  };

  const handleAddParticipant = (userName) => {
    if (!participants.includes(userName)) {
      setParticipants([...participants, userName]);
    }
  };

  const handleRemoveParticipant = (userName) => {
    setParticipants(participants.filter(p => p !== userName));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!name.trim() || participants.length === 0) {
      setError('Veuillez entrer un nom de conversation et ajouter des participants.');
      return;
    }

    const conversationData = {
      name: name.trim(),
      participants: participants // Already names
    };

    onCreate(conversationData);
  };

  const filteredUsers = allUsers.filter(user =>
    user.name.toLowerCase().includes(searchUser.toLowerCase()) &&
    user.name !== '' // Remplacez par `user.name !== currentUserName` si nécessaire
  );

  return (
    <div className={styles.overlay}>
      <motion.div
        className={styles.modal}
        initial={{ opacity: 0, scale: 0.9 }}
        animate={{ opacity: 1, scale: 1 }}
        exit={{ opacity: 0, scale: 0.9 }}
        transition={{ duration: 0.3 }}
      >
        <h2>Créer une nouvelle conversation</h2>
        <form onSubmit={handleSubmit}>
          <div className={styles.inputGroup}>
            <label>Nom de la conversation</label>
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
              required
            />
          </div>

          <div className={styles.inputGroup}>
            <label>Ajouter des participants</label>
            <input
              type="text"
              placeholder="Rechercher des utilisateurs..."
              value={searchUser}
              onChange={(e) => setSearchUser(e.target.value)}
            />
            <div className={styles.usersList}>
              {filteredUsers.map(user => (
                <div key={user.name} className={styles.userItem}>
                  <span>{user.name}</span>
                  <button type="button" onClick={() => handleAddParticipant(user.name)}>
                    Ajouter
                  </button>
                </div>
              ))}
            </div>
          </div>

          <div className={styles.participants}>
            <h3>Participants :</h3>
            {participants.map(name => (
              <div key={name} className={styles.participantItem}>
                <span>{name}</span>
                <button type="button" onClick={() => handleRemoveParticipant(name)}>
                  Retirer
                </button>
              </div>
            ))}
          </div>

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

          <div className={styles.buttonGroup}>
            <button type="button" onClick={onClose} className={styles.cancelButton}>
              Annuler
            </button>
            <button type="submit" className={styles.createButton}>
              Créer
            </button>
          </div>
        </form>
      </motion.div>
    </div>
  );
}

export default CreateConversationModal;

/* CreateConversationModal.module.css */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(12px);
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 1rem;
}

.modal {
  background: #000000;
  border-radius: 24px;
  padding: 2.5rem;
  width: min(90vw, 480px);
  color: #ffffff;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.modal h2 {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  margin-bottom: 2rem;
  color: #ffffff;
}

.inputGroup {
  margin-bottom: 2rem;
}

.inputGroup label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  margin-bottom: 0.75rem;
  color: rgba(255, 255, 255, 0.7);
  letter-spacing: 0.025em;
}

.inputGroup input {
  width: 100%;
  padding: 1rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: #ffffff;
  font-size: 1rem;
  transition: all 0.2s ease;
}

.inputGroup input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.08);
}

.inputGroup input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.usersList {
  max-height: 200px;
  overflow-y: auto;
  margin-top: 1rem;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  padding: 0.75rem;
}

.usersList::-webkit-scrollbar {
  width: 4px;
}

.usersList::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.2);
  border-radius: 4px;
}

.userItem,
.participantItem {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  margin-bottom: 0.75rem;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.2s ease;
}

.userItem:hover,
.participantItem:hover {
  background: rgba(255, 255, 255, 0.08);
}

.userItem span,
.participantItem span {
  color: #ffffff;
  font-weight: 500;
}

.userItem button,
.participantItem button {
  border: none;
  padding: 0.625rem 1rem;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.userItem button {
  background: #ffffff;
  color: #000000;
}

.userItem button:hover {
  background: rgba(255, 255, 255, 0.9);
  transform: translateY(-1px);
}

.participantItem button {
  background: transparent;
  color: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.participantItem button:hover {
  background: rgba(255, 0, 0, 0.1);
  color: #ff4444;
  border-color: rgba(255, 68, 68, 0.3);
}

.participants {
  margin: 2rem 0;
}

.participants h3 {
  font-size: 0.875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: 1rem;
  letter-spacing: 0.025em;
}

.error {
  color: #ff4444;
  font-size: 0.875rem;
  margin-bottom: 1.5rem;
}

.buttonGroup {
  display: flex;
  justify-content: flex-end;
  gap: 1rem;
  margin-top: 2.5rem;
}

.buttonGroup button {
  padding: 0.875rem 1.5rem;
  border-radius: 12px;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  border: none;
  transition: all 0.2s ease;
}

.cancelButton {
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.createButton {
  background: #ffffff;
  color: #000000;
}

.cancelButton:hover {
  background: rgba(255, 255, 255, 0.1);
}

.createButton:hover {
  background: rgba(255, 255, 255, 0.9);
  transform: translateY(-1px);
}

@media (max-width: 480px) {
  .modal {
    padding: 2rem;
  }

  .buttonGroup button {
    padding: 0.75rem 1.25rem;
  }
}

import React, { useState, useEffect, useContext } from 'react';
import axios from '../../utils/api';
import { AuthContext } from '../../contexts/AuthContext';
import styles from './Profile.module.css';

function Profile() {
  const { user } = useContext(AuthContext);
  const [bio, setBio] = useState('');
  const [editing, setEditing] = useState(false);

  useEffect(() => {
    const fetchBio = async () => {
      try {
        const response = await axios.get(`/users/${user.name}`);
        setBio(response.data.bio || '');
      } catch (error) {
        console.error('Erreur lors du chargement de la bio:', error);
      }
    };
    fetchBio();
  }, [user.name]);

  const handleSave = async () => {
    try {
      await axios.put('/users/me/bio', { bio });
      setEditing(false);
    } catch (error) {
      console.error('Erreur lors de la sauvegarde de la bio:', error);
    }
  };

  return (
    <div className={styles.container}>
      <div className={styles.background}>
        <div className={styles.gradient1}></div>
        <div className={styles.gradient2}></div>
        <div className={styles.gradient3}></div>
      </div>
      
      <div className={styles.glassOverlay}>
        <div className={styles.profileHeader}>
          <div className={styles.avatarContainer}>
            <div className={styles.avatarRing}></div>
            <div className={styles.avatar}>
              {user.name.charAt(0).toUpperCase()}
            </div>
          </div>
          <h1 className={styles.username}>{user.name}</h1>
          <div className={styles.statusBadge}>En ligne</div>
        </div>

        <div className={styles.bioSection}>
          {editing ? (
            <div className={styles.editContainer}>
              <textarea
                value={bio || ''}
                onChange={(e) => setBio(e.target.value)}
                className={styles.bioInput}
                placeholder="Écrivez quelque chose à propos de vous..."
              />
              <div className={styles.buttonGroup}>
                <button onClick={() => setEditing(false)} className={styles.cancelButton}>
                  Annuler
                </button>
                <button onClick={handleSave} className={styles.saveButton}>
                  Sauvegarder
                </button>
              </div>
            </div>
          ) : (
            <div className={styles.bioContainer}>
              <p className={styles.bioText}>{bio || "Aucune bio définie."}</p>
              <button onClick={() => setEditing(true)} className={styles.editButton}>
                Éditer le profil
              </button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

export default Profile;

/* Profile.module.css */
.container {
    min-height: 100vh;
    width: 100%;
    background: #0a0a0a;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 2rem;
    position: relative;
    overflow: hidden;
  }
  
  .background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
  }
  
  .gradient1, .gradient2, .gradient3 {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
  }
  
  .gradient1 {
    width: 50%;
    height: 50%;
    background: rgba(255, 65, 108, 0.15);
    top: -10%;
    left: -10%;
    animation: moveGradient1 15s infinite alternate;
  }
  
  .gradient2 {
    width: 60%;
    height: 60%;
    background: rgba(59, 130, 246, 0.15);
    top: 30%;
    right: -20%;
    animation: moveGradient2 20s infinite alternate;
  }
  
  .gradient3 {
    width: 40%;
    height: 40%;
    background: rgba(46, 213, 115, 0.15);
    bottom: -10%;
    left: 20%;
    animation: moveGradient3 17s infinite alternate;
  }
  
  .glassOverlay {
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    padding: 3rem;
    width: 100%;
    max-width: 600px;
    position: relative;
    z-index: 1;
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
  }
  
  .profileHeader {
    text-align: center;
    margin-bottom: 3rem;
  }
  
  .avatarContainer {
    position: relative;
    width: 120px;
    height: 120px;
    margin: 0 auto 1.5rem;
  }
  
  .avatarRing {
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    background: linear-gradient(45deg, #FF416C, #FF4B2B);
    animation: spin 10s linear infinite;
  }
  
  .avatar {
    position: absolute;
    inset: 3px;
    background: #1a1a1a;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    color: white;
    z-index: 1;
    transition: transform 0.3s ease;
  }
  
  .avatar:hover {
    transform: scale(1.05);
  }
  
  .username {
    font-size: 2rem;
    color: white;
    margin: 1rem 0;
    background: linear-gradient(45deg, #FF416C, #FF4B2B);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: fadeIn 0.6s ease-out;
  }
  
  .statusBadge {
    display: inline-block;
    padding: 0.5rem 1rem;
    background: rgba(46, 213, 115, 0.2);
    color: #2ed573;
    border-radius: 20px;
    font-size: 0.9rem;
    animation: pulse 2s infinite;
  }
  
  .bioSection {
    margin-top: 2rem;
  }
  
  .bioInput {
    width: 100%;
    min-height: 120px;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    padding: 1rem;
    color: white;
    font-size: 1rem;
    resize: vertical;
    transition: all 0.3s ease;
  }
  
  .bioInput:focus {
    outline: none;
    border-color: #FF416C;
    box-shadow: 0 0 20px rgba(255, 65, 108, 0.2);
  }
  
  .buttonGroup {
    display: flex;
    gap: 1rem;
    margin-top: 1rem;
    justify-content: flex-end;
  }
  
  .editButton, .saveButton {
    padding: 0.8rem 2rem;
    background: linear-gradient(45deg, #FF416C, #FF4B2B);
    color: white;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.3s ease;
    font-weight: 500;
  }
  
  .cancelButton {
    padding: 0.8rem 2rem;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.3s ease;
    font-weight: 500;
  }
  
  .editButton:hover, .saveButton:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(255, 65, 108, 0.4);
  }
  
  .cancelButton:hover {
    background: rgba(255, 255, 255, 0.2);
    transform: translateY(-2px);
  }
  
  .bioText {
    color: rgba(255, 255, 255, 0.9);
    line-height: 1.6;
    font-size: 1.1rem;
    margin-bottom: 2rem;
  }
  
  @keyframes moveGradient1 {
    0% { transform: translate(0, 0); }
    100% { transform: translate(100px, 50px); }
  }
  
  @keyframes moveGradient2 {
    0% { transform: translate(0, 0); }
    100% { transform: translate(-100px, -50px); }
  }
  
  @keyframes moveGradient3 {
    0% { transform: translate(0, 0); }
    100% { transform: translate(50px, -100px); }
  }
  
  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
  
  @keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
  }
  
  @keyframes pulse {
    0% { box-shadow: 0 0 0 0 rgba(46, 213, 115, 0.4); }
    70% { box-shadow: 0 0 0 10px rgba(46, 213, 115, 0); }
    100% { box-shadow: 0 0 0 0 rgba(46, 213, 115, 0); }
  }
  
  @media (max-width: 768px) {
    .container {
      padding: 1rem;
    }
  
    .glassOverlay {
      padding: 2rem;
    }
  
    .username {
      font-size: 1.8rem;
    }
  
    .avatarContainer {
      width: 100px;
      height: 100px;
    }
  
    .avatar {
      font-size: 2rem;
    }
  
    .buttonGroup {
      flex-direction: column;
    }
  
    .editButton, .saveButton, .cancelButton {
      width: 100%;
    }
  }
  
/* Suite du CSS précédent... */

/* Scrollbar personnalisée */
::-webkit-scrollbar {
    width: 8px;
  }
  
  ::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
  }
  
  ::-webkit-scrollbar-thumb {
    background: linear-gradient(45deg, #FF416C, #FF4B2B);
    border-radius: 4px;
  }
  
  ::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(45deg, #FF4B2B, #FF416C);
  }
  
  /* Sélection de texte */
  ::selection {
    background: rgba(255, 65, 108, 0.3);
    color: white;
  }
  
  /* Animations supplémentaires */
  .bioContainer {
    animation: fadeIn 0.6s ease-out;
  }
  
  .editContainer {
    animation: fadeIn 0.6s ease-out;
  }
  
  /* Focus styles */
  .bioInput:focus {
    outline: none;
    border-color: #FF416C;
    box-shadow: 0 0 20px rgba(255, 65, 108, 0.2);
    transform: translateY(-2px);
  }
  
  button:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(255, 65, 108, 0.3);
  }
  
  /* Hover effects améliorés */
  .glassOverlay:hover {
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
    transform: translateY(-2px);
    transition: all 0.3s ease;
  }
  
  .avatarContainer:hover .avatarRing {
    animation: spin 5s linear infinite;
  }
  
  /* États actifs des boutons */
  .editButton:active,
  .saveButton:active,
  .cancelButton:active {
    transform: scale(0.98);
  }
  
  /* Transitions globales */
  * {
    transition: all 0.3s ease;
  }
  
  /* Styles pour les grands écrans */
  @media (min-width: 1200px) {
    .glassOverlay {
      max-width: 700px;
      padding: 4rem;
    }
  
    .username {
      font-size: 2.5rem;
    }
  
    .avatarContainer {
      width: 150px;
      height: 150px;
    }
  
    .avatar {
      font-size: 3rem;
    }
  }
  
  /* Styles pour les très petits écrans */
  @media (max-width: 480px) {
    .container {
      padding: 0.5rem;
    }
  
    .glassOverlay {
      padding: 1.5rem;
      border-radius: 15px;
    }
  
    .username {
      font-size: 1.5rem;
    }
  
    .avatarContainer {
      width: 80px;
      height: 80px;
    }
  
    .avatar {
      font-size: 1.8rem;
    }
  
    .statusBadge {
      padding: 0.4rem 0.8rem;
      font-size: 0.8rem;
    }
  
    .bioInput {
      min-height: 100px;
      font-size: 0.9rem;
    }
  
    .editButton,
    .saveButton,
    .cancelButton {
      padding: 0.6rem 1.5rem;
      font-size: 0.9rem;
    }
  }
  
  /* Animations de chargement */
  @keyframes shimmer {
    0% {
      background-position: -468px 0;
    }
    100% {
      background-position: 468px 0;
    }
  }
  
  .loading {
    background: linear-gradient(
      to right,
      rgba(255, 255, 255, 0.1) 8%,
      rgba(255, 255, 255, 0.2) 18%,
      rgba(255, 255, 255, 0.1) 33%
    );
    background-size: 800px 104px;
    animation: shimmer 1.5s linear infinite;
  }
  
  /* Optimisations de performance */
  @media (prefers-reduced-motion: reduce) {
    * {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }

import React, { useContext, useEffect, useState, useRef } from 'react';
import { AuthContext } from '../contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
import styles from './Home.module.css';
import backgroundVideo from './Space.mp4';

function Home() {
  const { user } = useContext(AuthContext);
  const navigate = useNavigate();
  const [scrollProgress, setScrollProgress] = useState(0);
  const sectionsRef = useRef([]);

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

  useEffect(() => {
    const handleScroll = () => {
      // Calculate scroll progress (0 to 1)
      const totalHeight = document.documentElement.scrollHeight - window.innerHeight;
      const progress = window.scrollY / totalHeight;
      setScrollProgress(progress);

      // Check each section for visibility
      sectionsRef.current.forEach(section => {
        if (!section) return;
        const rect = section.getBoundingClientRect();
        const isVisible = rect.top < window.innerHeight * 0.75;
        if (isVisible) {
          section.classList.add(styles.revealed);
        }
      });
    };

    window.addEventListener('scroll', handleScroll);
    handleScroll(); // Initial check

    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // Progress line width calculation
  const progressWidth = `${scrollProgress * 100}%`;

  return (
    <div className={styles.mainContainer}>
      {/* Progress Line */}
      <div className={styles.progressLine}>
        <div className={styles.progressFill} style={{ width: progressWidth }} />
      </div>

      {/* Background Video */}
      <div className={styles.videoOverlay} style={{ 
        opacity: Math.min(0.4 + scrollProgress * 0.4, 0.8) 
      }} />
      <video
        autoPlay
        muted
        loop
        playsInline
        className={styles.backgroundVideo}
      >
        <source src={backgroundVideo} type="video/mp4" />
      </video>

      {/* Hero Section */}
      <section 
        className={`${styles.section} ${styles.heroSection}`}
        ref={el => sectionsRef.current[0] = el}
      >
        <div className={styles.contentWrapper}>
          {user.name ? (
            <div className={styles.authenticatedContent}>
              <div className={styles.avatarWrapper}>
                <div className={styles.avatar}>
                  {user.name.charAt(0).toUpperCase()}
                </div>
              </div>
              <h1 className={styles.welcomeText}>
                Ravi de vous revoir, <span className={styles.userName}>{user.name}</span>
              </h1>
              <button className={styles.mainButton} onClick={handleStartChat}>
                Accéder aux conversations
              </button>
            </div>
          ) : (
            <div className={styles.unauthenticatedContent}>
              <h1 className={styles.heroTitle}>Connectez-vous pour commencer</h1>
              <p className={styles.heroText}>
                Rejoignez une communauté dynamique et échangez en temps réel
              </p>
              <div className={styles.actionButtons}>
                <button className={styles.mainButton} onClick={handleLogin}>
                  Se connecter
                </button>
                <button className={styles.mainButton} onClick={handleSignUp}>
                  Créer un compte
                </button>
              </div>
            </div>
          )}
        </div>
      </section>

      {/* Features Section */}
      <section 
        className={`${styles.section} ${styles.featuresSection}`}
        ref={el => sectionsRef.current[1] = el}
      >
        <div className={styles.contentWrapper}>
          <h2 className={styles.sectionTitle}>Nos Fonctionnalités</h2>
          <div className={styles.featuresGrid}>
            {[
              { icon: '🔒', title: 'Sécurisé', desc: 'Protection de bout en bout' },
              { icon: '⚡', title: 'Rapide', desc: 'Communication en temps réel' },
              { icon: '🌐', title: 'Global', desc: 'Accessible partout' },
              { icon: '📱', title: 'Mobile', desc: 'Application responsive' },
            ].map((feature, index) => (
              <div 
                key={index}
                className={styles.featureCard}
                style={{ transitionDelay: `${index * 0.1}s` }}
              >
                <span className={styles.featureIcon}>{feature.icon}</span>
                <h3>{feature.title}</h3>
                <p>{feature.desc}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Stats Section */}
      <section 
        className={`${styles.section} ${styles.statsSection}`}
        ref={el => sectionsRef.current[2] = el}
      >
        <div className={styles.contentWrapper}>
          <h2 className={styles.sectionTitle}>Nos Chiffres</h2>
          <div className={styles.statsGrid}>
            {[
              { number: <span style={{ fontFamily: 'serif' }}>&#x221A;100%</span>, label: 'de satisfaction client' },
              { number: <span style={{ fontFamily: 'serif' }}>10MD<sup>0</sup></span>, label: 'Messages' },
              { number: '99.9%', label: 'indisponibilité' },
            ].map((stat, index) => (
              <div 
                key={index}
                className={styles.statCard}
                style={{ transitionDelay: `${index * 0.1}s` }}
              >
                <span className={styles.statNumber}>{stat.number}</span>
                <span className={styles.statLabel}>{stat.label}</span>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Contact Section */}
      <section 
        className={`${styles.section} ${styles.contactSection}`}
        ref={el => sectionsRef.current[3] = el}
      >
        <div className={styles.contentWrapper}>
          <h2 className={styles.sectionTitle}>Contactez-nous</h2>
          <div className={styles.contactContent}>
            <p className={styles.contactText}>
              Prêt a nous rejoindre !
            </p>
            <button className={styles.mainButton}>
              Commencer
            </button>
          </div>
        </div>
      </section>
    </div>
  );
}

export default Home;



/* Home.module.css */
.mainContainer {
  position: relative;
  min-height: 100vh;
  color: #FFFFFF;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}

/* Progress Line */
.progressLine {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: rgba(255, 255, 255, 0.1);
  z-index: 1000;
}

.progressFill {
  height: 100%;
  background: linear-gradient(90deg, #FF416C, #FF4B2B);
  transition: width 0.1s ease-out;
}

/* Video Background */
.backgroundVideo {
  position: fixed;
  right: 0;
  bottom: 0;
  min-width: 100%;
  min-height: 100%;
  width: auto;
  height: auto;
  z-index: -2;
  object-fit: cover;
}

.videoOverlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  z-index: -1;
  transition: opacity 0.5s ease;
}

/* Sections Common Styles */
.section {
  min-height: 100vh;
  padding: 80px 20px;
  opacity: 0;
  transform: translateY(50px);
  transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.section.revealed {
  opacity: 1;
  transform: translateY(0);
}

.contentWrapper {
  max-width: 1200px;
  margin: 0 auto;
  position: relative;
}

/* Hero Section */
.heroSection {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.heroTitle {
  font-size: 3.5rem;
  margin-bottom: 1rem;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1) 0.2s;
}

.revealed .heroTitle {
  opacity: 1;
  transform: translateY(0);
}

.heroText {
  font-size: 1.5rem;
  margin-bottom: 2rem;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1) 0.4s;
}

.revealed .heroText {
  opacity: 1;
  transform: translateY(0);
}

/* Features Section */
.featuresGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 30px;
  margin-top: 50px;
}

.featureCard {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  padding: 30px;
  text-align: center;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.revealed .featureCard {
  opacity: 1;
  transform: translateY(0);
}

.featureCard:hover {
  transform: translateY(-10px);
  background: rgba(255, 255, 255, 0.15);
}

.featureIcon {
  font-size: 3rem;
  margin-bottom: 1rem;
  display: block;
}

/* Stats Section */
.statsGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 30px;
  margin-top: 50px;
}

.statCard {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  padding: 30px;
  text-align: center;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.revealed .statCard {
  opacity: 1;
  transform: translateY(0);
}

.statNumber {
  font-size: 3rem;
  font-weight: bold;
  background: linear-gradient(45deg, #FF416C, #FF4B2B);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  display: block;
  margin-bottom: 0.5rem;
}

.statLabel {
  font-size: 1.2rem;
  color: rgba(255, 255, 255, 0.8);
}

/* Contact Section */
.contactSection {
  text-align: center;
}

.contactContent {
  max-width: 600px;
  margin: 0 auto;
}

.contactText {
  font-size: 1.5rem;
  margin-bottom: 2rem;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1) 0.2s;
}

.revealed .contactText {
  opacity: 1;
  transform: translateY(0);
}

/* Section Titles */
.sectionTitle {
  font-size: 2.5rem;
  margin-bottom: 2rem;
  text-align: center;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.revealed .sectionTitle {
  opacity: 1;
  transform: translateY(0);
}

/* Buttons */
.mainButton {
  padding: 15px 30px;
  font-size: 1.1rem;
  font-weight: 600;
  border: none;
  border-radius: 25px;
  background: linear-gradient(45deg, #FF416C, #FF4B2B);
  color: white;
  cursor: pointer;
  transition: all 0.3s ease;
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1) 0.6s;
}

.revealed .mainButton {
  opacity: 1;
  transform: translateY(0);
}

.mainButton:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 20px rgba(255, 65, 108, 0.3);
}

.actionButtons {
  display: flex;
  gap: 20px;
  justify-content: center;
  margin-top: 2rem;
}

/* Responsive Design */
@media (max-width: 768px) {
  .heroTitle {
    font-size: 2.5rem;
  }
  
  .heroText {
    font-size: 1.2rem;
  }
  
  .section {
    padding: 60px 20px;
  }
  
  .statNumber {
    font-size: 2.5rem;
  }
  
  .actionButtons {
    flex-direction: column;
  }
}

/* Animation Keyframes */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Smooth Scroll */
html {
  scroll-behavior: smooth;
}


// src/components/Navbar/Navbar.jsx
import React, { useContext } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { AuthContext } from '../contexts/AuthContext';
import { motion, AnimatePresence } from 'framer-motion';
import styles from './Navbar.module.css';

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

  // Définir les routes où la navbar ne doit pas être affichée
  const hideNavbarRoutes = ['/chat']; // Ajoutez d'autres routes si nécessaire
  const shouldHideNavbar = hideNavbarRoutes.some(route => location.pathname.startsWith(route));

  return (
    <AnimatePresence>
      {!shouldHideNavbar && (
        <motion.nav
          className={styles.navbar}
          initial={{ y: -100, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          exit={{ y: -100, opacity: 0 }}
          transition={{ duration: 0.5 }}
        >
          <div className={styles.navbarContainer}>
            <Link to="/" className={styles.navbarLogo}>
              ChatApp
            </Link>

            <div className={styles.navbarContent}>
              {user.name ? (
                <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.charAt(0).toUpperCase()}
                      </div>
                      <span className={styles.userName}>{user.name}</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>
        </motion.nav>
      )}
    </AnimatePresence>
  );
}

export default Navbar;

/* Navbar.module.css */

.navbar {
  background: rgba(28, 28, 30, 0.8); /* Slightly lighter than the main container */
  backdrop-filter: blur(15px);
  padding: 1rem 2rem;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: all 0.3s ease;
}

.navbarContainer {
  max-width: 1200px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
}

.navbarLogo {
  font-size: 1.8rem;
  font-weight: 700;
  text-decoration: none;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  transition: opacity 0.3s ease;
}

.navbarLogo:hover {
  opacity: 0.8;
}

.navbarContent {
  display: flex;
  align-items: center;
}

.authenticatedNav {
  display: flex;
  align-items: center;
}

.navLinks {
  display: flex;
  gap: 1.5rem;
  margin-right: 1.5rem;
}

.navLink {
  color: #FFFFFF;
  text-decoration: none;
  font-weight: 500;
  position: relative;
  transition: color 0.3s ease;
}

.navLink::after {
  content: '';
  position: absolute;
  width: 0%;
  height: 2px;
  left: 0;
  bottom: -4px;
  background: linear-gradient(90deg, #FF416C, #FF4B2B);
  transition: width 0.3s ease;
}

.navLink:hover::after {
  width: 100%;
}

.userSection {
  display: flex;
  align-items: center;
}

.userInfo {
  display: flex;
  align-items: center;
  margin-right: 1rem;
}

.userAvatar {
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  margin-right: 0.5rem;
  transition: box-shadow 0.3s ease;
}

.userAvatar:hover {
  box-shadow: 0 0 10px rgba(255, 65, 108, 0.6);
}

.userName {
  color: white;
  font-size: 1rem;
  font-weight: 500;
}

.logoutButton, .loginButton, .signupButton {
  padding: 0.5rem 1rem;
  border-radius: 20px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  transition: background 0.3s ease, transform 0.3s ease;
}

.logoutButton {
  background: linear-gradient(135deg, #FF416C, #FF4B2B);
  color: white;
}

.logoutButton:hover {
  background: linear-gradient(135deg, #FF4B2B, #FF416C);
  transform: translateY(-2px);
  box-shadow: 0 4px 6px rgba(255, 65, 108, 0.3);
}

.loginButton, .signupButton {
  background: rgba(255, 255, 255, 0.1);
  color: white;
  margin-left: 0.5rem;
}

.loginButton:hover, .signupButton:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 4px 6px rgba(255, 255, 255, 0.3);
}

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

export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState({
    id: '',
    name: '',
    bio: ''
  });

  // Charger l'utilisateur depuis le localStorage au démarrage
  useEffect(() => {
    const storedUser = localStorage.getItem('user');
    const storedToken = localStorage.getItem('token');
    if (storedUser && storedToken) {
      const parsedUser = JSON.parse(storedUser);
      setUser({
        id: parsedUser.id || '',
        name: parsedUser.name || '',
        bio: parsedUser.bio || ''
      });
      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}`;

    // Récupérer les informations de l'utilisateur courant
    const userResponse = await axios.get('/users/me');
    const fetchedUser = userResponse.data;
    localStorage.setItem('user', JSON.stringify(fetchedUser));
    setUser({
      id: fetchedUser.id || '',
      name: fetchedUser.name || '',
      bio: fetchedUser.bio || ''
    });
  };

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

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

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

// src/utils/api.js
import axios from 'axios';

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

export default instance;

import React, { useContext } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { AuthContext } 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 Profile from './components/Profile/Profile';
import Navbar from './components/Navbar';


function App() {
  const { user } = useContext(AuthContext);

  return (
    <Router>
      <Navbar />
      <Routes>
        <Route path="/" element={user.name ? <Navigate to="/conversations" /> : <Home />} />
        <Route path="/login" element={user.name ? <Navigate to="/conversations" /> : <Login />} />
        <Route path="/signup" element={user.name ? <Navigate to="/conversations" /> : <Signup />} />
        <Route path="/profile" element={user.name ? <Profile /> : <Navigate to="/login" />} />
        <Route path="/conversations" element={user.name ? <Chat /> : <Navigate to="/login" />} />
        <Route path="/chat/:conversationId" element={user.name ? <Chat /> : <Navigate to="/login" />} />
        {/* Redirection pour les chemins non définis */}
        <Route path="*" element={<Navigate to="/" replace />} />
      </Routes>
    </Router>
  );
}

export default App;

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { AuthProvider } from './contexts/AuthContext';

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

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');

body {
  font-family: 'Inter', sans-serif;
  background-color: #FFFFFF;
  color: #333333;
  margin: 0;
  padding: 0;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

/* index.css */