espace-paie-odentas/components/OrganizationSwitcher.tsx
2025-10-12 17:05:46 +02:00

104 lines
No EOL
3.5 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
type Org = { id: string; name: string; structure_api: string | null };
type Props = {
visible: boolean;
};
export function OrganizationSwitcher({ visible }: Props) {
const [orgs, setOrgs] = useState<Org[]>([]);
const [activeId, setActiveId] = useState<string>("");
useEffect(() => {
if (!visible) return;
(async () => {
try {
const res = await fetch("/api/organizations", { credentials: "include", cache: "no-store" });
const raw = await res.text();
if (!res.ok) {
console.error("/api/organizations error", res.status, raw);
setOrgs([]);
return;
}
const json: any = raw ? JSON.parse(raw) : { items: [] };
const items: Org[] = json.items || [];
setOrgs(items);
// Déterminer l'org active au chargement via /api/me
if (!activeId && items.length) {
try {
const meRes = await fetch("/api/me", { credentials: "include", cache: "no-store" });
if (meRes.ok) {
const meData = await meRes.json();
if (meData.active_org_id && items.some(o => o.id === meData.active_org_id)) {
setActiveId(meData.active_org_id);
// Mirror in localStorage so client-side fetcher can include header immediately
if (typeof window !== "undefined") {
try { localStorage.setItem("active_org_id", meData.active_org_id); } catch {}
}
}
}
} catch (err) {
console.warn("Could not fetch current org from /api/me", err);
}
}
} catch (err) {
console.error("Failed to load organizations", err);
setOrgs([]);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [visible]);
async function onChange(id: string) {
const org = orgs.find(o => o.id === id);
if (!org) return;
// Utiliser l'API pour mettre à jour l'organisation active
try {
const response = await fetch("/api/active-org", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ org_id: org.id }),
credentials: "include",
});
if (!response.ok) {
const errorText = await response.text();
console.error("Failed to set active org:", response.status, errorText);
return;
}
// Mettre à jour l'état local
setActiveId(id);
// Mettre à jour le localStorage pour l'affichage UI et pour que
// lib/fetcher puisse envoyer immédiatement le header x-active-org-id
if (typeof window !== "undefined") {
try {
localStorage.setItem("company_name", org.structure_api || org.name);
localStorage.setItem("active_org_id", org.id);
} catch {}
}
// Recharger pour que toutes les pages voient le changement côté serveur
window.location.reload();
} catch (error) {
console.error("Error setting active organization:", error);
}
}
if (!visible) return null;
return (
<select
value={activeId}
onChange={(e) => onChange(e.target.value)}
className="px-3 py-1.5 rounded-lg border text-sm"
>
<option value="" disabled>Sélectionner un client</option>
{orgs.map(o => <option key={o.id} value={o.id}>{o.name}</option>)}
</select>
);
}