feat: integrate all backend APIs into frontend apps
- Fix API service paths to use /v1/iam/, /v1/dimentorin/, /v1/gacha/, /v1/hackathon/ prefixes - Add roles, permissions, events, testimonials, sessions API services and hooks - Rewrite gacha service with full CRUD + roll/claim endpoints - Replace all mock data in backoffice pages with real API calls (accounts, roles, permissions, gacha-roll, dashboard, sessions, users-dimentorin, feedback-review, settings) - Wire dimentorin mentoring list to useMentorList with search + pagination - Wire dimentorin mentor detail page to useMentorById, pass real data to all sections - Wire appointment modal to useBookSession with controlled schedule inputs - Wire gacha app Spin Now to useExecuteGachaRoll, show credits and real items Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
8d2aaf5188
commit
53ad40f3fd
@@ -1,5 +1,5 @@
|
||||
import { useMutation, useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { hackathonApi, HackathonApiResponse } from '../../api/hackathon';
|
||||
import { api } from '../../api/index';
|
||||
import { useAuthStore } from '../auth';
|
||||
import type {
|
||||
TCreateTeamRequest,
|
||||
@@ -23,110 +23,41 @@ export const teamKeys = {
|
||||
};
|
||||
|
||||
interface TeamMember {
|
||||
id: string;
|
||||
team_id: string;
|
||||
user_id: string;
|
||||
role: string;
|
||||
status: string;
|
||||
joined_at: string;
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
fullname: string;
|
||||
avatar: string;
|
||||
};
|
||||
id: string; team_id: string; user_id: string; role: string; status: string;
|
||||
joined_at: string; user?: { id: string; email: string; fullname: string; avatar: string };
|
||||
}
|
||||
|
||||
interface Team {
|
||||
id: string;
|
||||
name: string;
|
||||
logo?: string;
|
||||
banner?: string;
|
||||
description?: string;
|
||||
city?: string;
|
||||
visibility: string;
|
||||
leader_id: string;
|
||||
created_at: string;
|
||||
leader?: {
|
||||
id: string;
|
||||
email: string;
|
||||
fullname: string;
|
||||
avatar: string;
|
||||
};
|
||||
members?: TeamMember[];
|
||||
member_count?: number;
|
||||
has_submission?: boolean;
|
||||
id: string; name: string; logo?: string; banner?: string; description?: string;
|
||||
city?: string; visibility: string; leader_id: string; created_at: string;
|
||||
leader?: { id: string; email: string; fullname: string; avatar: string };
|
||||
members?: TeamMember[]; member_count?: number; has_submission?: boolean;
|
||||
}
|
||||
|
||||
interface JoinRequest {
|
||||
id: string;
|
||||
team_id: string;
|
||||
user_id: string;
|
||||
message?: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
fullname: string;
|
||||
avatar: string;
|
||||
};
|
||||
id: string; team_id: string; user_id: string; message?: string; status: string;
|
||||
created_at: string; user?: { id: string; email: string; fullname: string; avatar: string };
|
||||
}
|
||||
|
||||
interface Invitation {
|
||||
id: string;
|
||||
team_id: string;
|
||||
inviter_id: string;
|
||||
invitee_email: string;
|
||||
invitee_id?: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
team?: Team;
|
||||
inviter?: {
|
||||
id: string;
|
||||
fullname: string;
|
||||
email: string;
|
||||
avatar: string;
|
||||
};
|
||||
id: string; team_id: string; inviter_id: string; invitee_email: string;
|
||||
invitee_id?: string; status: string; created_at: string; team?: Team;
|
||||
inviter?: { id: string; fullname: string; email: string; avatar: string };
|
||||
}
|
||||
|
||||
interface Submission {
|
||||
id: string;
|
||||
team_id: string;
|
||||
project_name: string;
|
||||
description?: string;
|
||||
repository_url?: string;
|
||||
demo_url?: string;
|
||||
video_url?: string;
|
||||
presentation_url?: string;
|
||||
status: string;
|
||||
submitted_at?: string;
|
||||
created_at: string;
|
||||
id: string; team_id: string; project_name: string; description?: string;
|
||||
repository_url?: string; demo_url?: string; video_url?: string;
|
||||
presentation_url?: string; status: string; submitted_at?: string; created_at: string;
|
||||
}
|
||||
interface ListMeta { page: number; per_page: number; total_page: number; total_data: number; }
|
||||
interface ListResponse<T> { message: string; data: T[]; meta: ListMeta; }
|
||||
interface ApiResp<T> { data: T; message?: string; }
|
||||
|
||||
interface ListResponseWithMeta<T> {
|
||||
message: string;
|
||||
data: T[];
|
||||
meta: {
|
||||
page: number;
|
||||
per_page: number;
|
||||
total_page: number;
|
||||
total_data: number;
|
||||
};
|
||||
}
|
||||
const TEAMS_PAGE_SIZE = 12;
|
||||
|
||||
export const useTeams = (params?: {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
city?: string;
|
||||
visibility?: string;
|
||||
search?: string;
|
||||
minMembers?: number;
|
||||
maxMembers?: number;
|
||||
hasSubmission?: boolean;
|
||||
page?: number; limit?: number; city?: string; visibility?: string; search?: string;
|
||||
minMembers?: number; maxMembers?: number; hasSubmission?: boolean;
|
||||
}) => {
|
||||
return useQuery({
|
||||
queryKey: teamKeys.list(params),
|
||||
queryKey: teamKeys.list(params as Record<string, unknown>),
|
||||
queryFn: async () => {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (params?.page) queryParams.append('page', String(params.page));
|
||||
@@ -137,11 +68,10 @@ export const useTeams = (params?: {
|
||||
if (params?.minMembers) queryParams.append('min_members', String(params.minMembers));
|
||||
if (params?.maxMembers) queryParams.append('max_members', String(params.maxMembers));
|
||||
if (params?.hasSubmission !== undefined) queryParams.append('has_submission', String(params.hasSubmission));
|
||||
|
||||
const response = await hackathonApi.get<ListResponseWithMeta<Team>>(
|
||||
`/teams/browse${queryParams.toString() ? `?${queryParams.toString()}` : ''}`
|
||||
const qs = queryParams.toString();
|
||||
const response = await api.get<ListResponse<Team>>(
|
||||
`/v1/hackathon/teams/browse${qs ? `?${qs}` : ''}`
|
||||
);
|
||||
|
||||
const { data, meta } = response.data;
|
||||
return {
|
||||
teams: data || [],
|
||||
@@ -154,13 +84,7 @@ export const useTeams = (params?: {
|
||||
});
|
||||
};
|
||||
|
||||
const TEAMS_PAGE_SIZE = 12;
|
||||
|
||||
export const useInfiniteTeams = (params?: {
|
||||
city?: string;
|
||||
visibility?: string;
|
||||
search?: string;
|
||||
}) => {
|
||||
export const useInfiniteTeams = (params?: { city?: string; visibility?: string; search?: string }) => {
|
||||
return useInfiniteQuery({
|
||||
queryKey: [...teamKeys.lists(), 'infinite', params],
|
||||
queryFn: async ({ pageParam = 1 }) => {
|
||||
@@ -170,19 +94,12 @@ export const useInfiniteTeams = (params?: {
|
||||
if (params?.search) queryParams.append('search', params.search);
|
||||
if (params?.city) queryParams.append('city', params.city);
|
||||
if (params?.visibility) queryParams.append('visibility', params.visibility);
|
||||
|
||||
const response = await hackathonApi.get<HackathonApiResponse<Team[]>>(
|
||||
`/teams/browse?${queryParams.toString()}`
|
||||
);
|
||||
|
||||
const response = await api.get<ApiResp<Team[]>>(`/v1/hackathon/teams/browse?${queryParams}`);
|
||||
const teams = response.data.data || [];
|
||||
return {
|
||||
data: teams,
|
||||
nextPage: teams.length === TEAMS_PAGE_SIZE ? pageParam + 1 : undefined,
|
||||
};
|
||||
return { data: teams, nextPage: teams.length === TEAMS_PAGE_SIZE ? pageParam + 1 : undefined };
|
||||
},
|
||||
initialPageParam: 1,
|
||||
getNextPageParam: (lastPage) => lastPage.nextPage,
|
||||
getNextPageParam: (lastPage: { nextPage?: number }) => lastPage.nextPage,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -190,7 +107,7 @@ export const useTeamById = (teamId: string, enabled = true) => {
|
||||
return useQuery({
|
||||
queryKey: teamKeys.detail(teamId),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<Team>>(`/teams/${teamId}`);
|
||||
const response = await api.get<ApiResp<Team>>(`/v1/hackathon/teams/${teamId}`);
|
||||
return { data: response.data.data };
|
||||
},
|
||||
enabled: enabled && !!teamId,
|
||||
@@ -200,22 +117,10 @@ export const useTeamById = (teamId: string, enabled = true) => {
|
||||
export const useCreateTeam = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: TCreateTeamRequest) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to create a team');
|
||||
}
|
||||
|
||||
const response = await hackathonApi.post<HackathonApiResponse<Team>>('/teams', {
|
||||
name: data.name,
|
||||
logo: data.logo,
|
||||
banner: data.banner,
|
||||
description: data.description,
|
||||
city: data.city,
|
||||
visibility: data.visibility,
|
||||
});
|
||||
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to create a team');
|
||||
const response = await api.post<ApiResp<Team>>('/v1/hackathon/teams', data);
|
||||
return { data: response.data.data };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -228,22 +133,10 @@ export const useCreateTeam = () => {
|
||||
export const useUpdateTeam = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: TUpdateTeamRequest) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to update a team');
|
||||
}
|
||||
|
||||
const response = await hackathonApi.put<HackathonApiResponse<Team>>(`/teams/${teamId}`, {
|
||||
name: data.name,
|
||||
logo: data.logo,
|
||||
banner: data.banner,
|
||||
description: data.description,
|
||||
city: data.city,
|
||||
visibility: data.visibility,
|
||||
});
|
||||
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to update a team');
|
||||
const response = await api.put<ApiResp<Team>>(`/v1/hackathon/teams/${teamId}`, data);
|
||||
return { data: response.data.data };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -257,7 +150,7 @@ export const useTeamMembers = (teamId: string, enabled = true) => {
|
||||
return useQuery({
|
||||
queryKey: teamKeys.members(teamId),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<Team>>(`/teams/${teamId}`);
|
||||
const response = await api.get<ApiResp<Team>>(`/v1/hackathon/teams/${teamId}`);
|
||||
return { data: response.data.data?.members || [] };
|
||||
},
|
||||
enabled: enabled && !!teamId,
|
||||
@@ -267,32 +160,26 @@ export const useTeamMembers = (teamId: string, enabled = true) => {
|
||||
export const useInviteMember = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: TInviteMemberRequest) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to invite a member');
|
||||
}
|
||||
|
||||
const response = await hackathonApi.post<HackathonApiResponse<Invitation>>(
|
||||
`/teams/${teamId}/invite`,
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to invite a member');
|
||||
const response = await api.post<ApiResp<Invitation>>(
|
||||
`/v1/hackathon/invitations/teams/${teamId}/invite`,
|
||||
{ invitee_email: data.email }
|
||||
);
|
||||
|
||||
return { data: response.data.data };
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: teamKeys.members(teamId) });
|
||||
},
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: teamKeys.members(teamId) }),
|
||||
});
|
||||
};
|
||||
|
||||
export const useManageMember = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ userId, data }: { userId: string; data: { role?: string; status?: string } }) => {
|
||||
throw new Error('Manage member functionality not yet implemented in backend');
|
||||
// Remove member is the available operation; role management not exposed by backend
|
||||
await api.delete(`/v1/hackathon/teams/${teamId}/members/${userId}`);
|
||||
return { success: true };
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: teamKeys.members(teamId) });
|
||||
@@ -304,14 +191,10 @@ export const useManageMember = (teamId: string) => {
|
||||
export const useRemoveMember = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (userId: string) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to remove a member');
|
||||
}
|
||||
|
||||
await hackathonApi.delete(`/teams/${teamId}/members/${userId}`);
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to remove a member');
|
||||
await api.delete(`/v1/hackathon/teams/${teamId}/members/${userId}`);
|
||||
return { success: true };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -324,23 +207,16 @@ export const useRemoveMember = (teamId: string) => {
|
||||
export const useJoinTeam = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ teamId, data }: { teamId: string; data: TJoinTeamRequest }) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to join a team');
|
||||
}
|
||||
|
||||
const response = await hackathonApi.post<HackathonApiResponse<JoinRequest>>(
|
||||
`/join-requests/teams/${teamId}`,
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to join a team');
|
||||
const response = await api.post<ApiResp<JoinRequest>>(
|
||||
`/v1/hackathon/join-requests/teams/${teamId}`,
|
||||
{ message: data.message }
|
||||
);
|
||||
|
||||
return { data: response.data.data };
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: teamKeys.lists() });
|
||||
},
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: teamKeys.lists() }),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -348,8 +224,8 @@ export const useTeamJoinRequests = (teamId: string, enabled = true) => {
|
||||
return useQuery({
|
||||
queryKey: teamKeys.joinRequests(teamId),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<JoinRequest[]>>(
|
||||
`/join-requests/teams/${teamId}/pending`
|
||||
const response = await api.get<ApiResp<JoinRequest[]>>(
|
||||
`/v1/hackathon/join-requests/teams/${teamId}/pending`
|
||||
);
|
||||
return { data: response.data.data || [] };
|
||||
},
|
||||
@@ -360,19 +236,11 @@ export const useTeamJoinRequests = (teamId: string, enabled = true) => {
|
||||
export const useRespondToJoinRequest = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ requestId, action }: { requestId: string; action: 'approve' | 'reject' }) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to respond to join requests');
|
||||
}
|
||||
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to respond to join requests');
|
||||
const backendAction = action === 'approve' ? 'accept' : 'reject';
|
||||
|
||||
await hackathonApi.post(`/join-requests/${requestId}/respond`, {
|
||||
action: backendAction,
|
||||
});
|
||||
|
||||
await api.post(`/v1/hackathon/join-requests/${requestId}/respond`, { action: backendAction });
|
||||
return { success: true, action };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -385,11 +253,10 @@ export const useRespondToJoinRequest = (teamId: string) => {
|
||||
|
||||
export const useMyInvitations = () => {
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useQuery({
|
||||
queryKey: teamKeys.myInvitations(),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<Invitation[]>>('/invitations/my');
|
||||
const response = await api.get<ApiResp<Invitation[]>>('/v1/hackathon/invitations/my');
|
||||
return { data: response.data.data || [] };
|
||||
},
|
||||
enabled: !!session?.user?.id,
|
||||
@@ -399,15 +266,10 @@ export const useMyInvitations = () => {
|
||||
export const useRespondToInvitation = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ invitationId, action }: { invitationId: string; action: 'accept' | 'reject' }) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('User not authenticated');
|
||||
}
|
||||
|
||||
await hackathonApi.post(`/invitations/${invitationId}/respond`, { action });
|
||||
|
||||
if (!session?.user?.id) throw new Error('User not authenticated');
|
||||
await api.post(`/v1/hackathon/invitations/${invitationId}/respond`, { action });
|
||||
return { success: true, action };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -420,13 +282,12 @@ export const useRespondToInvitation = () => {
|
||||
|
||||
export const useMyTeams = () => {
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useQuery({
|
||||
queryKey: teamKeys.myTeams(),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<any[]>>('/teams/my');
|
||||
const response = await api.get<ApiResp<unknown[]>>('/v1/hackathon/teams/my');
|
||||
const rawData = response.data.data || [];
|
||||
const teams = rawData.map((item: any) => item.team || item);
|
||||
const teams = rawData.map((item: unknown) => (item as Record<string, unknown>).team ?? item);
|
||||
return { data: teams };
|
||||
},
|
||||
enabled: !!session?.user?.id,
|
||||
@@ -435,58 +296,22 @@ export const useMyTeams = () => {
|
||||
|
||||
export const useSubmitProject = (teamId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: TSubmitProjectRequest) => {
|
||||
let submissionId: string;
|
||||
|
||||
try {
|
||||
const existingResponse = await hackathonApi.get<HackathonApiResponse<Submission | null>>(
|
||||
`/submissions/teams/${teamId}`
|
||||
);
|
||||
|
||||
if (existingResponse.data.data?.id) {
|
||||
const response = await hackathonApi.put<HackathonApiResponse<Submission>>(
|
||||
`/submissions/${existingResponse.data.data.id}`,
|
||||
{
|
||||
project_name: data.project_name,
|
||||
description: data.description,
|
||||
repository_url: data.repository_url,
|
||||
demo_url: data.demo_url,
|
||||
video_url: data.video_url,
|
||||
presentation_url: data.presentation_url,
|
||||
screenshots: data.screenshots,
|
||||
}
|
||||
);
|
||||
submissionId = response.data.data.id;
|
||||
} else {
|
||||
throw new Error('No existing submission');
|
||||
}
|
||||
const existing = await api.get<ApiResp<Submission | null>>(`/v1/hackathon/submissions/teams/${teamId}`);
|
||||
if (existing.data.data?.id) {
|
||||
const res = await api.put<ApiResp<Submission>>(`/v1/hackathon/submissions/${existing.data.data.id}`, data);
|
||||
submissionId = res.data.data.id;
|
||||
} else throw new Error('No existing submission');
|
||||
} catch {
|
||||
const response = await hackathonApi.post<HackathonApiResponse<Submission>>(
|
||||
`/submissions/teams/${teamId}`,
|
||||
{
|
||||
project_name: data.project_name,
|
||||
description: data.description,
|
||||
repository_url: data.repository_url,
|
||||
demo_url: data.demo_url,
|
||||
video_url: data.video_url,
|
||||
presentation_url: data.presentation_url,
|
||||
screenshots: data.screenshots,
|
||||
}
|
||||
);
|
||||
submissionId = response.data.data.id;
|
||||
const res = await api.post<ApiResp<Submission>>(`/v1/hackathon/submissions/teams/${teamId}`, data);
|
||||
submissionId = res.data.data.id;
|
||||
}
|
||||
|
||||
await hackathonApi.post<HackathonApiResponse<Submission>>(
|
||||
`/submissions/${submissionId}/submit`
|
||||
);
|
||||
|
||||
const finalResponse = await hackathonApi.post<HackathonApiResponse<Submission>>(
|
||||
`/submissions/${submissionId}/confirm`
|
||||
);
|
||||
|
||||
return { data: finalResponse.data.data };
|
||||
await api.post<ApiResp<Submission>>(`/v1/hackathon/submissions/${submissionId}/submit`);
|
||||
const final = await api.post<ApiResp<Submission>>(`/v1/hackathon/submissions/${submissionId}/confirm`);
|
||||
return { data: final.data.data };
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: teamKeys.submission(teamId) });
|
||||
@@ -499,9 +324,7 @@ export const useTeamSubmission = (teamId: string, enabled = true) => {
|
||||
return useQuery({
|
||||
queryKey: teamKeys.submission(teamId),
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<Submission | null>>(
|
||||
`/submissions/teams/${teamId}`
|
||||
);
|
||||
const response = await api.get<ApiResp<Submission | null>>(`/v1/hackathon/submissions/teams/${teamId}`);
|
||||
return { data: response.data.data };
|
||||
},
|
||||
enabled: enabled && !!teamId,
|
||||
@@ -511,14 +334,10 @@ export const useTeamSubmission = (teamId: string, enabled = true) => {
|
||||
export const useLeaveTeam = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (teamId: string) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to leave a team');
|
||||
}
|
||||
|
||||
await hackathonApi.post(`/teams/${teamId}/leave`);
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to leave a team');
|
||||
await api.post(`/v1/hackathon/teams/${teamId}/leave`);
|
||||
return { success: true };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -531,14 +350,10 @@ export const useLeaveTeam = () => {
|
||||
export const useDeleteTeam = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { session } = useAuthStore();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (teamId: string) => {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('You must be logged in to delete a team');
|
||||
}
|
||||
|
||||
await hackathonApi.delete(`/teams/${teamId}`);
|
||||
if (!session?.user?.id) throw new Error('You must be logged in to delete a team');
|
||||
await api.delete(`/v1/hackathon/teams/${teamId}`);
|
||||
return { success: true };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -552,9 +367,9 @@ export const useTeamsByUserId = (userId: string) => {
|
||||
return useQuery({
|
||||
queryKey: ['teams-by-user', userId],
|
||||
queryFn: async () => {
|
||||
const response = await hackathonApi.get<HackathonApiResponse<any[]>>(`/users/${userId}/teams`);
|
||||
const response = await api.get<ApiResp<unknown[]>>(`/v1/hackathon/users/${userId}/teams`);
|
||||
const rawData = response.data.data || [];
|
||||
const teams = rawData.map((item: any) => item.team || item);
|
||||
const teams = rawData.map((item: unknown) => (item as Record<string, unknown>).team ?? item);
|
||||
return { data: teams };
|
||||
},
|
||||
enabled: !!userId,
|
||||
|
||||
Reference in New Issue
Block a user