140 lines
4.0 KiB
TypeScript
140 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import type { Database } from '@/types/supabase';
|
|
import { Select } from './Select';
|
|
import { getSupabaseClient } from '../../utils/supabase';
|
|
import { AuthChangeEvent, Session } from '@supabase/supabase-js';
|
|
|
|
type Team = Database['limq']['Tables']['teams']['Row'];
|
|
|
|
interface TeamSelectorProps {
|
|
value?: string;
|
|
onChange?: (teamId: string) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function TeamSelector({ value, onChange, className }: TeamSelectorProps) {
|
|
const [teams, setTeams] = useState<Team[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
let isMounted = true;
|
|
|
|
const fetchTeams = async (userId: string) => {
|
|
if (!isMounted) return;
|
|
|
|
console.log('Starting to fetch teams for user:', userId);
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const supabase = getSupabaseClient();
|
|
|
|
// 获取用户的团队成员关系
|
|
console.log('Fetching team memberships for user:', userId);
|
|
const { data: memberships, error: membershipError } = await supabase
|
|
.from('team_membership')
|
|
.select('team_id')
|
|
.eq('user_id', userId);
|
|
|
|
console.log('Team memberships result:', { memberships, membershipError });
|
|
|
|
if (membershipError) {
|
|
console.error('Membership error:', membershipError);
|
|
throw membershipError;
|
|
}
|
|
|
|
if (!memberships || memberships.length === 0) {
|
|
console.log('No team memberships found');
|
|
if (isMounted) {
|
|
setTeams([]);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 获取团队详细信息
|
|
const teamIds = memberships.map(m => m.team_id);
|
|
console.log('Fetching teams with IDs:', teamIds);
|
|
const { data: teamsData, error: teamsError } = await supabase
|
|
.from('teams')
|
|
.select('*')
|
|
.in('id', teamIds)
|
|
.is('deleted_at', null);
|
|
|
|
console.log('Teams result:', { teamsData, teamsError });
|
|
|
|
if (teamsError) {
|
|
console.error('Teams error:', teamsError);
|
|
throw teamsError;
|
|
}
|
|
|
|
if (isMounted && teamsData) {
|
|
setTeams(teamsData);
|
|
}
|
|
} catch (err) {
|
|
console.error('Error fetching teams:', err);
|
|
if (isMounted) {
|
|
setError(err instanceof Error ? err.message : 'Failed to load teams');
|
|
}
|
|
} finally {
|
|
if (isMounted) {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
};
|
|
|
|
const supabase = getSupabaseClient();
|
|
|
|
// 设置认证状态监听器
|
|
const { data: { subscription } } = supabase.auth.onAuthStateChange((event: AuthChangeEvent, session: Session | null) => {
|
|
console.log('Auth state changed:', event, session?.user);
|
|
if (event === 'SIGNED_IN' && session?.user?.id) {
|
|
fetchTeams(session.user.id);
|
|
} else if (event === 'SIGNED_OUT') {
|
|
setTeams([]);
|
|
setError(null);
|
|
}
|
|
});
|
|
|
|
// 初始检查session
|
|
supabase.auth.getSession().then(({ data: { session } }: { data: { session: Session | null } }) => {
|
|
console.log('Initial session check:', session?.user);
|
|
if (session?.user?.id) {
|
|
fetchTeams(session.user.id);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
isMounted = false;
|
|
subscription.unsubscribe();
|
|
};
|
|
}, []);
|
|
|
|
if (loading) {
|
|
return <div className="animate-pulse h-10 bg-gray-200 rounded-md dark:bg-gray-700" />;
|
|
}
|
|
|
|
if (error) {
|
|
return <div className="text-red-500 text-sm">{error}</div>;
|
|
}
|
|
|
|
if (teams.length === 0) {
|
|
return <div className="text-sm text-gray-500">No teams available</div>;
|
|
}
|
|
|
|
return (
|
|
<Select
|
|
className={className}
|
|
value={value}
|
|
onChange={(newValue: string) => onChange?.(newValue)}
|
|
options={teams.map(team => ({
|
|
value: team.id,
|
|
label: team.name,
|
|
icon: team.avatar_url || undefined
|
|
}))}
|
|
placeholder="Select a team"
|
|
/>
|
|
);
|
|
}
|