import { useEffect, useState } from "react"; import { useAuth } from "../context/AuthContext"; const OAUTH_URL = import.meta.env.VITE_OAUTH_URL || ""; const PROVIDERS = ["discord", "github", "google", "twitch"]; const EMOJIS = { discord: "🎮", github: "🐙", google: "🌐", twitch: "🎬" }; function getOAuthToken() { return localStorage.getItem("clkz_oauth_token"); } async function oauthFetch(path, options = {}) { const token = getOAuthToken(); if (!token) throw new Error("Not authenticated with SuperOAuth"); const res = await fetch(`${OAUTH_URL}/api/v1${path}`, { ...options, headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, ...options.headers, }, }); if (res.status === 401) { localStorage.removeItem("clkz_oauth_token"); throw new Error("SuperOAuth token expired — re-login required"); } if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.message || `HTTP ${res.status}`); } return res.json(); } export default function Settings() { const { user, logout } = useAuth(); const [profile, setProfile] = useState(null); const [linkedProviders, setLinkedProviders] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [actionLoading, setActionLoading] = useState(null); // Handle ?linked= or ?error= from link callback useEffect(() => { const params = new URLSearchParams(window.location.search); const linked = params.get("linked"); const err = params.get("error"); if (linked) { window.history.replaceState({}, "", "/settings"); } if (err) { setError(err); window.history.replaceState({}, "", "/settings"); } }, []); useEffect(() => { if (!user) return; fetchProfile(); }, [user]); async function fetchProfile() { setLoading(true); setError(null); try { const data = await oauthFetch("/user/profile"); setProfile(data.data.user); setLinkedProviders(data.data.linkedProviders); } catch (e) { setError(e.message); } finally { setLoading(false); } } async function handleLink(provider) { setActionLoading(provider); setError(null); try { const data = await oauthFetch(`/oauth/${provider}/link`, { method: "POST", body: JSON.stringify({ returnUrl: `${window.location.origin}/settings`, }), }); window.location.href = data.data.authUrl; } catch (e) { setError(e.message); setActionLoading(null); } } async function handleUnlink(provider) { if (!confirm(`Délier ${provider} ?`)) return; setActionLoading(provider); setError(null); try { await oauthFetch(`/oauth/${provider}/unlink`, { method: "DELETE" }); await fetchProfile(); } catch (e) { setError(e.message); } finally { setActionLoading(null); } } if (!user) { return (

Connecte-toi pour accéder aux paramètres.

); } if (loading) { return (

Chargement du profil...

); } const linkedNames = new Set(linkedProviders.map((p) => p.provider)); const canUnlink = linkedProviders.length > 1; return (

Paramètres

{error && (

{error}

)} {/* Profile info */} {profile && (

Pseudo : {profile.nickname}

Email : {profile.email || "—"}

)} {/* Linked providers */}

Comptes liés

{PROVIDERS.map((provider) => { const linked = linkedNames.has(provider); const isLoading = actionLoading === provider; return (
{EMOJIS[provider]} {provider.charAt(0).toUpperCase() + provider.slice(1)} {linked && ( ✓ lié )} {linked ? ( ) : ( )}
); })}
{/* Logout */}
); }