"use client"; // Paramètres : profil (lecture), changement de mot de passe, thème, // raccourcis clavier documentés, transparence (à propos). import { useState } from "react"; import { Info, Keyboard, KeyRound, Palette, UserRound } from "lucide-react"; import { PageHeader } from "@/components/app-shell"; import { Button, Card, Input, Label, Spinner } from "@/components/ui"; import { ThemeToggle } from "@/components/theme-toggle"; import { ErrorBanner, postJson } from "./shared"; const SHORTCUTS: { keys: string[]; description: string }[] = [ { keys: ["⌘", "K"], description: "Nouvelle conversation dans le chat" }, { keys: ["⌘", "J"], description: "Ouvrir le centre d'apprentissage" }, { keys: ["Échap"], description: "Arrêter la réponse en cours (chat) ou fermer un panneau" }, { keys: ["Entrée"], description: "Envoyer le message (Maj+Entrée : nouvelle ligne)" }, { keys: ["Espace"], description: "Retourner la carte mémoire (flashcards)" }, { keys: ["1", "–", "4"], description: "Noter la carte : Encore / Difficile / Bien / Facile" }, ]; export function SettingsApp({ displayName, username, email, role, }: { displayName: string; username: string; email: string | null; role: "student" | "instructor" | "admin"; }) { const [current, setCurrent] = useState(""); const [next, setNext] = useState(""); const [confirmPwd, setConfirmPwd] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); async function changePassword(e: React.FormEvent) { e.preventDefault(); setError(null); setSuccess(false); if (next !== confirmPwd) { setError("La confirmation ne correspond pas au nouveau mot de passe."); return; } setBusy(true); try { await postJson("/api/auth/change-password", { currentPassword: current, newPassword: next }); setSuccess(true); setCurrent(""); setNext(""); setConfirmPwd(""); } catch (err) { setError(err instanceof Error ? err.message : "Erreur lors du changement de mot de passe."); } finally { setBusy(false); } } const roleLabel = role === "student" ? "Étudiant·e" : role === "admin" ? "Administrateur" : "Professeur"; return (
{/* Profil */}

Profil

Nom affiché
{displayName}
Identifiant
{username}
{email && ( <>
Courriel
{email}
)}
Rôle
{roleLabel}

Pour modifier votre nom affiché ou vos cours, contactez votre professeur.

{/* Mot de passe */}

Mot de passe

setCurrent(e.target.value)} />
setNext(e.target.value)} />
setConfirmPwd(e.target.value)} />
{error && } {success && (

Mot de passe modifié — vos autres sessions ont été déconnectées par sécurité.

)}
{/* Thème */}

Thème

Cliquez pour alterner entre clair, sombre et système. « Système » suit automatiquement le réglage de votre appareil. Le choix est mémorisé sur cet appareil.

{/* Raccourcis clavier */}

Raccourcis clavier

    {SHORTCUTS.map((s, i) => (
  • {s.keys.map((k, j) => ( {k} ))} {s.description}
  • ))}
{/* À propos / transparence */}

À propos et transparence

Modes de connaissances

Cours uniquement (par défaut) : les réponses s'appuient exclusivement sur le matériel officiel des cours, avec les diapositives citées.{" "} Cours + général : le matériel cité est complété par les connaissances du modèle, clairement distinguées.{" "} Général : réponse sans le matériel du cours, toujours signalée comme telle.

Origine des données

Le contenu pédagogique provient des documents officiels d'IMM1003 et IMM1033 (UQO), indexés localement. Vos activités (cartes, quiz, examens) restent sur le serveur du cours et servent uniquement à estimer votre maîtrise et à personnaliser les recommandations. La maîtrise affichée est une estimation, jamais une note.

Budget d'usage

Les fonctions d'IA (chat, résumés, génération de cartes) consomment un budget partagé plafonné par personne et par jour, pour garder la plateforme équitable et durable. Si vous atteignez la limite, un message vous l'indique — les révisions (flashcards, quiz, examens) restent toujours disponibles, car elles ne consomment pas d'IA.

Limites

Immbot AI peut se tromper. Vérifiez les sources citées, signalez les erreurs avec l'icône drapeau du chat, et référez-vous aux documents officiels du cours en cas de doute.

); }