fix: unwrap nested team data in hooks instead of components

- useMyTeams and useTeamsByUserId now unwrap {team: {...}} structure
- Simplified dashboard and user profile components

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Maulana Sodiqin
2025-11-30 14:13:11 +07:00
co-authored by Claude
parent 45c75b3283
commit 23b6677323
3 changed files with 60 additions and 58 deletions
+1 -2
View File
@@ -131,8 +131,7 @@ const DashboardPage: FC = (): ReactElement => {
{myTeams.length > 0 ? ( {myTeams.length > 0 ? (
(() => { (() => {
const item = myTeams[0] as any; const team = myTeams[0] as any;
const team = item.team || item;
return ( return (
<div className="mb-6 md:mb-8"> <div className="mb-6 md:mb-8">
<h2 className="text-xl md:text-2xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4"> <h2 className="text-xl md:text-2xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4">
+49 -52
View File
@@ -131,61 +131,58 @@ const UserProfilePage: FC = (): ReactElement => {
Team Team
</h2> </h2>
<div className="space-y-4"> <div className="space-y-4">
{userTeams.map((item: any) => { {userTeams.map((team: any) => (
const team = item.team || item; <Link
return ( key={team.id}
<Link to={'/teams/' + team.id}
key={team.id} className="block bg-white dark:bg-gray-800 rounded-lg shadow-md dark:shadow-gray-950/50 overflow-hidden hover:shadow-lg transition-shadow border dark:border-gray-700"
to={'/teams/' + team.id} >
className="block bg-white dark:bg-gray-800 rounded-lg shadow-md dark:shadow-gray-950/50 overflow-hidden hover:shadow-lg transition-shadow border dark:border-gray-700" <img
> src={team.banner || '/images/banner-imphnen.webp'}
<img alt={team.name}
src={team.banner || '/images/banner-imphnen.webp'} className="w-full aspect-3/1 object-cover"
alt={team.name} />
className="w-full aspect-3/1 object-cover" <div className="p-4">
/> <div className="flex items-center space-x-3 mb-3">
<div className="p-4"> {team.logo ? (
<div className="flex items-center space-x-3 mb-3"> <img
{team.logo ? ( src={team.logo}
<img alt={team.name}
src={team.logo} className="w-12 h-12 rounded-full object-cover"
alt={team.name} />
className="w-12 h-12 rounded-full object-cover" ) : (
/> <div className="w-12 h-12 rounded-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center">
) : ( <Icon icon="mdi:account-group" className="text-gray-500 dark:text-gray-400 text-xl" />
<div className="w-12 h-12 rounded-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center"> </div>
<Icon icon="mdi:account-group" className="text-gray-500 dark:text-gray-400 text-xl" /> )}
</div> <div className="flex-1 min-w-0">
)} <h3 className="font-bold text-gray-900 dark:text-white line-clamp-1 text-lg">
<div className="flex-1 min-w-0"> {team.name}
<h3 className="font-bold text-gray-900 dark:text-white line-clamp-1 text-lg"> </h3>
{team.name} <div className="text-sm text-gray-600 dark:text-gray-400 flex items-center gap-3 font-sans mt-1">
</h3> {team.has_submission && (
<div className="text-sm text-gray-600 dark:text-gray-400 flex items-center gap-3 font-sans mt-1"> <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 shrink-0">
{team.has_submission && ( <Icon icon="mdi:check-circle" className="text-sm" />
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 shrink-0"> Submitted
<Icon icon="mdi:check-circle" className="text-sm" /> </span>
Submitted )}
</span> {team.city && (
)} <span className="flex items-center gap-1 truncate">
{team.city && ( <Icon icon="mdi:map-marker" className="shrink-0" />
<span className="flex items-center gap-1 truncate"> <span className="truncate">{team.city}</span>
<Icon icon="mdi:map-marker" className="shrink-0" /> </span>
<span className="truncate">{team.city}</span> )}
</span>
)}
</div>
</div> </div>
</div> </div>
{team.description && (
<p className="text-gray-600 dark:text-gray-400 text-sm line-clamp-2 font-sans">
{team.description}
</p>
)}
</div> </div>
</Link> {team.description && (
); <p className="text-gray-600 dark:text-gray-400 text-sm line-clamp-2 font-sans">
})} {team.description}
</p>
)}
</div>
</Link>
))}
</div> </div>
</div> </div>
) : ( ) : (
+10 -4
View File
@@ -434,8 +434,11 @@ export const useMyTeams = () => {
return useQuery({ return useQuery({
queryKey: teamKeys.myTeams(), queryKey: teamKeys.myTeams(),
queryFn: async () => { queryFn: async () => {
const response = await hackathonApi.get<HackathonApiResponse<Team[]>>('/teams/my'); const response = await hackathonApi.get<HackathonApiResponse<any[]>>('/teams/my');
return { data: response.data.data || [] }; const rawData = response.data.data || [];
// Unwrap nested team data if present (API returns [{team: {...}}] or [{id, name, ...}])
const teams = rawData.map((item: any) => item.team || item);
return { data: teams };
}, },
enabled: !!session?.user?.id, enabled: !!session?.user?.id,
}); });
@@ -555,8 +558,11 @@ export const useTeamsByUserId = (userId: string) => {
return useQuery({ return useQuery({
queryKey: ['teams-by-user', userId], queryKey: ['teams-by-user', userId],
queryFn: async () => { queryFn: async () => {
const response = await hackathonApi.get<HackathonApiResponse<Team[]>>(`/users/${userId}/teams`); const response = await hackathonApi.get<HackathonApiResponse<any[]>>(`/users/${userId}/teams`);
return { data: response.data.data || [] }; const rawData = response.data.data || [];
// Unwrap nested team data if present (API returns [{team: {...}}] or [{id, name, ...}])
const teams = rawData.map((item: any) => item.team || item);
return { data: teams };
}, },
enabled: !!userId, enabled: !!userId,
}); });