([]);
+
+ // Profiles are bounded by RLS to rows the current user is allowed to
+ // see — today that's just the current user, but the dropdown keeps the
+ // shape ready for shared-team workspaces without a refactor.
+ useEffect(() => {
+ let cancelled = false;
+ const supabase = createClient();
+ supabase
+ .from("profiles")
+ .select("*")
+ .order("full_name")
+ .then(({ data, error }) => {
+ if (cancelled) return;
+ if (error) {
+ console.error("Failed to fetch profiles:", error);
+ return;
+ }
+ setProfiles((data as Profile[]) ?? []);
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, []);
// 24-hour session timer
const sessionInfo = useMemo(() => {
@@ -266,6 +304,27 @@ export function MessageThread({
// Template modal implementation would go here
}, []);
+ const handleAssignChange = useCallback(
+ async (agentId: string | null) => {
+ if (!conversation) return;
+
+ const supabase = createClient();
+ const { error } = await supabase
+ .from("conversations")
+ .update({ assigned_agent_id: agentId })
+ .eq("id", conversation.id);
+
+ if (error) {
+ console.error("Failed to update assignment:", error);
+ toast.error("Failed to update assignment");
+ return;
+ }
+
+ onAssignChange(conversation.id, agentId);
+ },
+ [conversation, onAssignChange],
+ );
+
// Empty state
if (!conversation || !contact) {
return (
@@ -288,6 +347,11 @@ export function MessageThread({
const currentStatus = STATUS_OPTIONS.find(
(s) => s.value === conversation.status
);
+ const assignedAgentId = conversation.assigned_agent_id ?? null;
+ const currentAssignee = profiles.find((p) => p.user_id === assignedAgentId);
+ const assignLabel = assignedAgentId
+ ? (currentAssignee?.full_name ?? "Assigned")
+ : "Assign";
return (
@@ -353,15 +417,60 @@ export function MessageThread({
- {/* Assign button */}
-
+ {/* Assign dropdown */}
+
+
+
+ {assignLabel}
+
+
+
+ {profiles.length === 0 ? (
+
+ No teammates available
+
+ ) : (
+ profiles.map((p) => {
+ const isSelected = p.user_id === assignedAgentId;
+ return (
+ handleAssignChange(p.user_id)}
+ className={cn(
+ "text-sm",
+ isSelected ? "text-violet-400" : "text-slate-300"
+ )}
+ >
+
+ {p.full_name}
+ {p.user_id === user?.id ? " (me)" : ""}
+
+ {isSelected && }
+
+ );
+ })
+ )}
+ {assignedAgentId && (
+ <>
+
+ handleAssignChange(null)}
+ className="text-sm text-slate-400"
+ >
+ Unassign
+
+ >
+ )}
+
+