Skip to content

Commit

Permalink
[Feature] 스터디 멘토 검색 기능 추가 (#111)
Browse files Browse the repository at this point in the history
* feat: 스터디 멘토 검색 기능 추가

* chore: cursor pointer 스타일 추가
  • Loading branch information
eugene028 authored Sep 2, 2024
1 parent 349e972 commit 8c27c28
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 30 deletions.
14 changes: 14 additions & 0 deletions apps/admin/apis/study/createStudyApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { fetcher } from "@wow-class/utils";
import { apiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import type { CreateStudyApiRequestDto } from "types/dtos/createStudy";
import type { SearchStudyMentorResponseDto } from "types/dtos/searchStudyMentor";
import type { CreateStudyDetailInfoApiRequestDto } from "types/dtos/studyDetailInfo";

export const createStudyApi = {
Expand All @@ -19,4 +21,16 @@ export const createStudyApi = {
);
return { success: response.ok };
},
searchStudyMentor: async (
name: string
): Promise<SearchStudyMentorResponseDto[]> => {
const response = await fetcher.get(
`${apiPath.searchMentor}?name=${name}&roles=REGULAR`,
{
next: { tags: [tags.memberList] },
cache: "force-cache",
}
);
return response.data.content;
},
};
118 changes: 88 additions & 30 deletions apps/admin/app/studies/create-study/_components/StudyMentorSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,98 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
"use client";
import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Text } from "@wow-class/ui";
import { Controller, useFormContext } from "react-hook-form";
import DropDown from "wowds-ui/DropDown";
import DropDownOption from "wowds-ui/DropDownOption";
import { createStudyApi } from "apis/study/createStudyApi";
import { useState } from "react";
import { useFormContext } from "react-hook-form";
import SearchBar from "wowds-ui/SearchBar";

type MentorListType = {
memberId: number;
name: string;
};

const StudyMentorSelect = () => {
const { control } = useFormContext();
const { setValue } = useFormContext();
const [memberList, setMemberList] = useState<MentorListType[]>([]);
const [openPopup, setOpenPopup] = useState(false);
const [mentor, setMentor] = useState("");

const fetchStudyMentor = async (name: string) => {
const response = await createStudyApi.searchStudyMentor(name);
const formatMentorList = response.map((data) => {
return {
memberId: data.memberId,
name: data.name,
};
});
setMemberList([...formatMentorList]);
setOpenPopup(true);
};

return (
<Controller
control={control}
defaultValue={0}
name="mentorId"
render={({ field }) => (
<Flex direction="column" gap="xl">
<Text typo="h2">스터디 멘토</Text>
<DropDown
{...field}
placeholder="선택하세요"
style={{ width: "270px" }}
value={field.value ? String(field.value) : ""}
onChange={({ selectedValue }) => {
field.onChange(Number(selectedValue));
}}
>
<DropDownOption text="김유진" value="3" />
<DropDownOption text="홍서현" value="5" />
<DropDownOption text="이현영" value="15" />
</DropDown>
</Flex>
)}
rules={{
required: true,
}}
/>
<Flex direction="column" gap="xl">
<Text typo="h2">스터디 멘토</Text>
<div style={{ position: "relative" }}>
<SearchBar
placeholder="멘토를 검색해주세요"
style={{ width: "270px" }}
value={mentor}
onChange={(value) => {
setMentor(value);
fetchStudyMentor(value);
}}
/>
{openPopup && mentor.length > 0 && (
<ul className={MemberListPopupStyle}>
{memberList.length > 0 ? (
<>
{memberList.map((data) => (
<li
className={MemberListItemStyle}
key={data.memberId}
onClick={() => {
setValue("mentorId", data.memberId, {
shouldValidate: true,
});
setOpenPopup(false);
setMentor(data.name);
}}
>
<Text color="sub" typo="body1">
{data.name}
</Text>
</li>
))}
</>
) : (
<Text color="sub" typo="body1">
일치하는 결과가 없어요.
</Text>
)}
</ul>
)}
</div>
</Flex>
);
};

export default StudyMentorSelect;

const MemberListPopupStyle = css({
position: "absolute",
top: "50px",
width: "320px",
zIndex: 999,
borderRadius: "8px",
backgroundColor: "white",
shadow: "mono",
padding: "xs",
});

const MemberListItemStyle = css({
marginY: "5px",
cursor: "pointer",
});
1 change: 1 addition & 0 deletions apps/admin/constants/apiPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const enum apiPath {
studyList = "/admin/studies",
createStudy = "/admin/studies",
createStudyDetailInfo = "/mentor/studies",
searchMentor = "/admin/members",
}

export const enum mentorApiPath {
Expand Down
1 change: 1 addition & 0 deletions apps/admin/constants/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export const enum tags {
studyList = "studyList",
studyBasicInfo = "studyBasicInfo",
announcements = "announcements",
memberList = "memberList",
attendances = "attendances",
}
18 changes: 18 additions & 0 deletions apps/admin/types/dtos/searchStudyMentor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface SearchStudyMentorResponseDto {
memberId: number;
studentId: string;
name: string;
phone: string;
department: {
code: string;
name: string;
};
email: string;
discordUsername: string;
nickname: string;
requirement: {
univStatus: string;
discordStatus: string;
bevyStatus: string;
};
}

0 comments on commit 8c27c28

Please sign in to comment.