diff --git a/src/app/(user)/page.tsx b/src/app/(user)/page.tsx index 8364553f..fef6a093 100644 --- a/src/app/(user)/page.tsx +++ b/src/app/(user)/page.tsx @@ -1,3 +1,26 @@ +"use client"; + +import { CommonAxios } from "@/utils/CommonAxios"; +import { Button } from "@mantine/core"; + export default function Home() { - return
Hello, world!
; + const body = { + name: "stop-user", + phoneNumber: "010-1234-1234", + userType: "INACTIVE_PROFESSOR", + email: "email@gmail.com", + signUpSource: "ad", + division: null, + position: null, + }; + + return ( +
+
+ ); } diff --git a/src/components/common/Row/Row.tsx b/src/components/common/Row/Row.tsx index 1c903a7a..7bbeea75 100644 --- a/src/components/common/Row/Row.tsx +++ b/src/components/common/Row/Row.tsx @@ -1,10 +1,11 @@ -import { Box, BoxProps, Group, Text } from "@mantine/core"; +import { Box, BoxProps, Group, StyleProp, Text } from "@mantine/core"; import classes from "./Row.module.css"; export interface RowProps extends BoxProps { field?: string; // 필드 이름 children: React.ReactNode; fieldSize?: "sm" | "md" | "lg" | "xl" | number; // 필드 부분이 차지하는 길이 + fieldWeight?: StyleProp; flexStart?: boolean; } @@ -12,6 +13,7 @@ export function Row({ field = "", fieldSize = "md", children, + fieldWeight, flexStart = false, ...props }: RowProps) { @@ -32,6 +34,7 @@ export function Row({ : fieldSize, }} fz={16} + fw={fieldWeight} > {field} diff --git a/src/components/pages/AdminApplicationListSection/AdminApplicationListSection.tsx b/src/components/pages/AdminApplicationListSection/AdminApplicationListSection.tsx index 6929b908..a5ba7b3f 100644 --- a/src/components/pages/AdminApplicationListSection/AdminApplicationListSection.tsx +++ b/src/components/pages/AdminApplicationListSection/AdminApplicationListSection.tsx @@ -5,17 +5,17 @@ import { DataTable } from "@/components/common/DataTable"; import { DataTableData } from "@/components/common/DataTable/elements/DataTableData"; import { DataTableRow } from "@/components/common/DataTable/elements/DataTableRow"; import { APPLICATION_TABLE_HEADERS } from "@/constants/DataTableHeaders"; +import { USER_TYPE_LOOKUP_TABLE } from "@/constants/LookupTables"; import { PAGE_SIZES, REFRESH_DEFAULT_PAGE_NUMBER } from "@/constants/PageSize"; import { useApplications } from "@/hooks/swr/useApplications"; import { useTableSort } from "@/hooks/useTableSort"; import { CommonAxios } from "@/utils/CommonAxios"; -import { Button, Checkbox, Group, Stack } from "@mantine/core"; -import { useRouter } from "next/navigation"; +import { Checkbox, Group, Stack } from "@mantine/core"; +import { useDisclosure } from "@mantine/hooks"; import { useEffect, useState } from "react"; +import { ApplicationConfirmModal } from "./ApplicationConfirmModal"; export function AdminApplicationListSection() { - /* next 라우터, 페이지 이동에 이용 */ - const { push } = useRouter(); /* 페이지당 행 개수 */ const [pageSize, setPageSize] = useState(String(PAGE_SIZES[0])); /* 페이지네이션 페이지 넘버*/ @@ -24,9 +24,8 @@ export function AdminApplicationListSection() { const { sortBy, order, handleSortButton } = useTableSort(); /* SWR 훅을 사용하여 공지사항 목록 패칭 */ - // TODO: 백엔드 수정 이후 sort 파라미터 추가 const { data, pageData, mutate } = useApplications({ - params: { page: pageNumber - 1, size: Number(pageSize) }, + params: { page: pageNumber - 1, size: Number(pageSize), sort: sortBy + "," + order }, }); /* 체크박스 전체선택, 일괄선택 다루는 파트 */ @@ -61,6 +60,20 @@ export function AdminApplicationListSection() { ); }; + /* 전체 승인 버튼 핸들러 */ + const handleConfirm = () => { + // TODO: 삭제 확인하는 모달 추가 + Promise.all(selectedApplications.map((id) => CommonAxios.patch(`/applications/${id}`))).then( + () => { + setSelectedApplications([]); + mutate(); + } + ); + }; + + /* 가입 승인 모달 hook */ + const [opened, { open, close }] = useDisclosure(); + useEffect(() => { setPageNumber(REFRESH_DEFAULT_PAGE_NUMBER); }, [data, pageSize]); @@ -68,15 +81,9 @@ export function AdminApplicationListSection() { return ( <> - + 선택 삭제 - { - push("notices/create"); - }} - > - 게시글 등록 - + 선택 승인 {application.name} {application.division} {application.position} - {application.userType} + {USER_TYPE_LOOKUP_TABLE[application.userType]} {application.createdAt} - + 승인 + ))} diff --git a/src/components/pages/AdminApplicationListSection/ApplicationConfirmModal.tsx b/src/components/pages/AdminApplicationListSection/ApplicationConfirmModal.tsx new file mode 100644 index 00000000..897e453f --- /dev/null +++ b/src/components/pages/AdminApplicationListSection/ApplicationConfirmModal.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { PrimaryButton } from "@/components/common/Buttons"; +import { Row } from "@/components/common/Row"; +import { DetailedApplication, PagedApplicationsResponse } from "@/types/application"; +import { CommonAxios } from "@/utils/CommonAxios"; +import { Modal, ModalProps, Stack, Text } from "@mantine/core"; +import { useEffect, useState } from "react"; +import { KeyedMutator } from "swr"; + +interface ApplicationConfirmModalProps extends ModalProps { + applicationId: number; + mutate: KeyedMutator; +} + +export function ApplicationConfirmModal({ + applicationId, + mutate, + ...props +}: ApplicationConfirmModalProps) { + const [application, setApplication] = useState(null); + + // 가입 승인 + const handleConfirm = async () => { + try { + await CommonAxios.patch(`/applications/${applicationId}`); + mutate(); + close(); + } catch (error) { + // TODO: 에러 처리 + console.error(error); + } + }; + + // 가입 신청 정보 가져오기 + useEffect(() => { + const fetchApplication = async () => { + const { data } = await CommonAxios.get(`/applications/${applicationId}`); + setApplication(data); + }; + + fetchApplication(); + }, [applicationId]); + + return ( + + + + 가입 승인 + + + + {application?.name} + + + {application?.phone} + + + {application?.email} + + + {application?.division} + + + {application?.position} + + + + 승인 + + + + ); +} diff --git a/src/constants/LookupTables.ts b/src/constants/LookupTables.ts new file mode 100644 index 00000000..b3407cf9 --- /dev/null +++ b/src/constants/LookupTables.ts @@ -0,0 +1,12 @@ +import { Role } from "@/types/user"; + +export const USER_TYPE_LOOKUP_TABLE: Record = { + STUDENT: "학생", + PROFESSOR: "교수", + COMPANY: "기업관계자", + ADMIN: "관리자", + INACTIVE_PROFESSOR: "미승인 교수", + INACTIVE_COMPANY: "미승인 기업관계자", + OTHERS: "기타", + TEMP: "임시", +};