Skip to content

Commit ae040a4

Browse files
authored
feat(web): 선수 관리 페이지 추가 (#410)
* feat: exclude test files from biome scanner includes * feat: add player management page with edit functionality * feat: implement player management functionality with player list and query integration * feat: enhance player management page with search functionality and improved player list display * feat: add Modal component and integrate with player management page * feat: add AlertDialog component for player deletion confirmation * feat: enhance player list display with student number and adjust typography sizes * feat: add spinner component with customizable size and color, and enhance color definitions * feat: add loading state to Button component and integrate Spinner for better user feedback * feat: add search functionality to player list with input field for filtering by name or student number * feat: add player management page with add player button and update player list layout * feat: add player creation and update functionality with form handling and toast notifications * feat: refactor player delete menu import path for better module organization * feat: update player form to display message when no teams are available * feat: improve loading state handling in alert dialog and refactor player delete function
1 parent 77119b9 commit ae040a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1378
-37
lines changed

apps/manager/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
"@vercel/analytics": "^1.5.0",
2929
"next": "^15.4.6",
3030
"react": "^19.1.1",
31-
"react-dom": "^19.1.1"
31+
"react-dom": "^19.1.1",
32+
"react-hook-form": "^7.62.0",
33+
"tailwind-merge": "^3.3.1"
3234
},
3335
"devDependencies": {
3436
"@hcc/typescript-config": "workspace:*",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
export * from './useCreatePlayers';
2+
export * from './useDeletePlayers';
13
export * from './useLogin';
4+
export * from './useUpdatePlayers';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { fetcher, useMutation, useQueryClient } from '@hcc/api-base';
2+
import type { PlayerType } from '~/api';
3+
import { queryKeys } from '~/api/queryKey';
4+
5+
export type PlayerFormType = Pick<PlayerType, 'name' | 'studentNumber'>;
6+
7+
export const postPlayers = (request: PlayerFormType) => {
8+
return fetcher.post<void>('players', { json: request });
9+
};
10+
11+
export const useCreatePlayers = () => {
12+
const queryClient = useQueryClient();
13+
14+
return useMutation({
15+
mutationFn: postPlayers,
16+
onSuccess: async () => {
17+
await queryClient.invalidateQueries({ queryKey: queryKeys.players._def });
18+
},
19+
});
20+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { fetcher, useMutation, useQueryClient } from '@hcc/api-base';
2+
import { queryKeys } from '~/api/queryKey';
3+
4+
type Request = {
5+
id: number;
6+
};
7+
8+
export const deletePlayers = ({ id }: Request) => {
9+
return fetcher.delete<void>(`players/${id}`, { json: null });
10+
};
11+
12+
export const useDeletePlayers = () => {
13+
const queryClient = useQueryClient();
14+
15+
return useMutation({
16+
mutationFn: deletePlayers,
17+
onSuccess: async () => {
18+
await queryClient.invalidateQueries({ queryKey: queryKeys.players._def });
19+
},
20+
});
21+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { fetcher, useMutation, useQueryClient } from '@hcc/api-base';
2+
import type { PlayerFormType } from '~/api';
3+
import { queryKeys } from '~/api/queryKey';
4+
5+
type Request = {
6+
id: number;
7+
} & PlayerFormType;
8+
9+
export const patchPlayers = ({ id, ...request }: Request) => {
10+
return fetcher.patch<void>(`players/${id}`, { json: request });
11+
};
12+
13+
export const useUpdatePlayers = () => {
14+
const queryClient = useQueryClient();
15+
16+
return useMutation({
17+
mutationFn: patchPlayers,
18+
onSuccess: async () => {
19+
await queryClient.invalidateQueries({ queryKey: queryKeys.players._def });
20+
},
21+
});
22+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export * from './useLeaguesHome';
22
export * from './useLeaguesLeague';
3+
export * from './usePlayer';
4+
export * from './usePlayers';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useQuery, useSuspenseQuery } from '@hcc/api-base';
2+
import type { PlayerDetailPayload } from '~/api';
3+
import { queryKeys } from '../queryKey';
4+
5+
export const usePlayer = (payload: PlayerDetailPayload) =>
6+
useQuery(queryKeys.players.detail(payload));
7+
8+
export const useSuspensePlayer = (payload: PlayerDetailPayload) =>
9+
useSuspenseQuery(queryKeys.players.detail(payload));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useQuery, useSuspenseQuery } from '@hcc/api-base';
2+
import { queryKeys } from '../queryKey';
3+
4+
export const usePlayers = () => useQuery(queryKeys.players.list);
5+
6+
export const useSuspensePlayers = () => useSuspenseQuery(queryKeys.players.list);

apps/manager/src/api/queryKey.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { fetcher } from '@hcc/api-base';
22
import { createQueryKeys, mergeQueryKeys } from '@lukemorales/query-key-factory';
3-
import type { LeagueDetailType, LeagueType } from './types';
3+
import type { LeagueDetailType, LeagueType, PlayerDetailPayload, PlayerType } from './types';
44

55
const leagueQueryKeys = createQueryKeys('leagues', {
66
home: {
@@ -13,4 +13,15 @@ const leagueQueryKeys = createQueryKeys('leagues', {
1313
},
1414
});
1515

16-
export const queryKeys = mergeQueryKeys(leagueQueryKeys);
16+
const playerQueryKeys = createQueryKeys('players', {
17+
list: {
18+
queryKey: null,
19+
queryFn: () => fetcher.get<PlayerType[]>('players'),
20+
},
21+
detail: (payload: PlayerDetailPayload) => ({
22+
queryKey: [payload],
23+
queryFn: () => fetcher.get<PlayerType>(`players/${payload.id}`),
24+
}),
25+
});
26+
27+
export const queryKeys = mergeQueryKeys(leagueQueryKeys, playerQueryKeys);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { TeamType } from '~/api/types/teams';
1+
import type { GameTeamType } from '~/api/types/teams';
22

33
export type GameType = {
44
id: number;
5+
isPkTaken: boolean;
56
startTime: string;
67
gameQuarter: string;
78
gameName: string;
89
round: number;
910
videoId: string;
10-
gameTeams: TeamType[];
11-
isPkTaken: boolean;
11+
gameTeams: GameTeamType[];
1212
};

0 commit comments

Comments
 (0)