Hackathon: better frontend (#61)

* feat: enhance team browsing with member count and view team option

* feat: add default banner image for teams without a custom banner

* feat: implement user profile page and user layout component

* feat: improve browse team filtering layout

* feat: limit join request button visibility based on team member count

* feat: enhance user profile and team dashboard layouts for improved responsiveness

* feat: add location, bio, and skills fields to user profile schema and form

* feat: enhance team display and user information layout for better readability

* feat: update join request button visibility logic based on user team membership

* feat: enhance team and user profile layouts with improved text truncation and responsiveness
This commit is contained in:
Ivan Rizkyanto
2025-11-26 10:18:36 +07:00
committed by GitHub
parent 083a912e91
commit cbb880a053
10 changed files with 473 additions and 97 deletions
+47 -1
View File
@@ -37,7 +37,10 @@ export const useTeams = (params?: {
queryFn: async () => {
try {
// Supabase client now has auth context from setSession()
let query = supabase.from('teams').select('*');
let query = supabase.from('teams').select(`
*,
members:team_members(id)
`);
// Filter by visibility
if (params?.visibility) {
@@ -691,3 +694,46 @@ export const useLeaveTeam = () => {
},
});
};
// Get Teams by User ID
export const useTeamsByUserId = (userId: string) => {
return useQuery({
queryKey: ['teams-by-user', userId],
queryFn: async () => {
if (!userId) {
return { data: [] };
}
// Query team_members to find teams where user is a member
const { data: memberships, error: membershipsError } = await supabase
.from('team_members')
.select(`
team_id,
team:teams(
id,
name,
logo,
banner,
description,
city,
visibility,
leader_id,
created_at
)
`)
.eq('user_id', userId)
.eq('status', 'active');
if (membershipsError) {
console.error('Failed to fetch user teams:', membershipsError);
return { data: [] };
}
// Extract teams from memberships
const teams = memberships?.map((m: any) => m.team).filter(Boolean) || [];
return { data: teams };
},
enabled: !!userId,
});
};
+20
View File
@@ -92,3 +92,23 @@ export const useUpdateUserById = () => {
},
});
};
export const useUserDetailsById = (userId: string) => {
return useQuery({
queryKey: ['user-supabase', userId],
queryFn: async () => {
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', userId)
.single();
if (error) {
throw new Error(error.message || 'Failed to fetch user');
}
return { data };
},
enabled: !!userId,
});
};
+3
View File
@@ -76,6 +76,9 @@ export const userOnboardingSchema = z.object({
export const userEditProfileSchema = z.object({
fullname: z.string().min(3, 'Nama lengkap minimal 3 karakter'),
avatar: z.string().url('Avatar harus berupa URL yang valid').nullable().optional(),
location: z.string().optional(),
bio: z.string().max(500, 'Bio maksimal 500 karakter').optional(),
skills: z.array(z.string()).optional(),
});
export type TTeamCreateForm = z.infer<typeof teamCreateSchema>;