Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: 스터디 개설하기 api 연동 #30

Merged
merged 51 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
1ae4c49
feat: layout
eugene028 Aug 12, 2024
3c8b5e3
chore: lock 패키지 변경 사항 반영
eugene028 Aug 12, 2024
96dcb69
chore: 중복된 Navbar 컴포넌트 삭제
ghdtjgus76 Aug 12, 2024
10a576b
feat: 개설 스터디 기본 잡기
eugene028 Aug 12, 2024
dcd3e0b
feat: 스터디 개설 페이지 레이아웃
eugene028 Aug 13, 2024
e135d97
chore:패키지 설치
eugene028 Aug 13, 2024
5d35442
fix: 찌그러짐 방지용 minWidth 추가
eugene028 Aug 13, 2024
a77f7e6
feat: 스터디 개설하기 뷰 생성
eugene028 Aug 13, 2024
dcbb5b3
fix: 개설된 스터디로 화면 옮기기
eugene028 Aug 13, 2024
cec09ee
feat: auth 체크용 middleWare 생성
eugene028 Aug 13, 2024
333e298
fix: utils fetcher 함수 export 경로 변경
eugene028 Aug 13, 2024
f122b3d
feat: 스터디 생성하기 페이지 생성
eugene028 Aug 13, 2024
d1b9aa6
fix: router handler 삭제
eugene028 Aug 13, 2024
ab0a88f
fix:로그인 로직 합치기
eugene028 Aug 13, 2024
38dcff3
refactor: api path 상수로 수정
eugene028 Aug 13, 2024
0ccf38f
feat: isAdmin 함수 추가
eugene028 Aug 13, 2024
96dead7
fix: 코드리뷰 반영
eugene028 Aug 13, 2024
beae0f1
fix: admin여부에 따라 스터디 생성 박스 보이지 않도록
eugene028 Aug 13, 2024
329670f
chore: dev 머지
eugene028 Aug 14, 2024
8bbc939
chore: 패키지 설치
eugene028 Aug 14, 2024
30d8e7c
fix: 빌드에러 고치기
eugene028 Aug 14, 2024
9e03318
fix: 고친 로그인 로직 머지
eugene028 Aug 14, 2024
e09a96d
fix: isadmin 판별 로직 미들웨어에서 진행
eugene028 Aug 14, 2024
8efc686
feat: 역할 논리 다시
eugene028 Aug 14, 2024
00020f8
fix: 폴더명 변경
eugene028 Aug 14, 2024
625326e
fix: createStudy 경로 변경
eugene028 Aug 14, 2024
387950c
feat:wow-icons 추가
eugene028 Aug 14, 2024
2c771c5
feat: 기존 브랜치 머지
eugene028 Aug 14, 2024
ca7e7f4
refactor: 컴포넌트 폴더위치 변경
eugene028 Aug 14, 2024
5622e3f
chore:react-hook-form 설치
eugene028 Aug 14, 2024
317d492
feat: 복잡한 UI 설계 react-hook-form
eugene028 Aug 14, 2024
0a4bc8a
feat: 스터디 수강 시작 날짜 지정
eugene028 Aug 14, 2024
5ca5232
chore: dev 머지
eugene028 Aug 16, 2024
dee4824
chore: timepicker 패키지 설치
eugene028 Aug 16, 2024
12c8c0e
feat: 스터디 신청 UI 완성
eugene028 Aug 16, 2024
21fea58
fix: 쓸데없는 콘솔로그 제거
eugene028 Aug 16, 2024
ac11d0a
feat: api 연결
eugene028 Aug 16, 2024
4022961
feat:api 호출 성공시 redirect
eugene028 Aug 16, 2024
2b97234
fix: 캐시 지워서 빌드에러 해결
eugene028 Aug 16, 2024
361cf66
chore: fetcher 테스트
eugene028 Aug 19, 2024
058b69f
chore: dev 브랜치에서 머지
eugene028 Aug 20, 2024
78b414e
chore: 패키지 설치
eugene028 Aug 20, 2024
a7c4c78
fix: api 관련 코드리뷰 반영
eugene028 Aug 20, 2024
1cd3527
fix: 코드리뷰 반영
eugene028 Aug 20, 2024
2cb887e
fix: 메인에서 머지
eugene028 Aug 20, 2024
3c23f8f
fix: navbar 두개인것 고치기
eugene028 Aug 20, 2024
5cf6d7b
fix: 코드리뷰 반영
eugene028 Aug 20, 2024
1e9ac2a
fix: 코드리뷰 반영
eugene028 Aug 20, 2024
6e97e57
fix: 코드리뷰 반영
eugene028 Aug 20, 2024
3bfec83
chore: dev 머지
eugene028 Aug 20, 2024
6ae5dbc
fix: 멘토 id 변경
eugene028 Aug 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/admin/apis/auth/dashboardApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fetcher } from "@wow-class/utils";
import { apiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import { cookies } from "next/headers";
import type { DashboardApiResponseDto } from "types/dto/auth";
import type { DashboardApiResponseDto } from "types/dtos/auth";

export const dashboardApi = {
getDashboardInfo: async () => {
Expand Down
18 changes: 18 additions & 0 deletions apps/admin/apis/form/createStudyApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use client";
import { fetcher } from "@wow-class/utils";
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
import { apiPath } from "constants/apiPath";
import { redirect } from "next/navigation";
import { useRouter } from "next/router";
import type { CreateStudyApiRequestDto } from "types/dtos/createStudy";
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

export const createStudyApi = {
postCreateStudy: async (data: CreateStudyApiRequestDto) => {
const response = await fetcher.post(apiPath.createStudy, data, {
credentials: "include",
});
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

if (response.ok) {
redirect("/create-study");
}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
},
};
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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";

const StudyMentorSelect = () => {
const { control } = useFormContext();
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="1" />
</DropDown>
</Flex>
)}
rules={{
required: true,
}}
/>
);
};

export default StudyMentorSelect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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";

const StudyNameTextField = () => {
const { control } = useFormContext();
return (
<Controller
control={control}
defaultValue=""
name="title"
render={({ field }) => (
<Flex direction="column" gap="sm">
<Text color="sub" typo="h3">
새로 개설할 스터디 정보를 입력해주세요
</Text>
<textarea
{...field}
className={TextFieldStyle}
placeholder="새로운 스터디"
onChange={field.onChange}
/>
</Flex>
)}
rules={{
required: true,
}}
/>
);
};

export default StudyNameTextField;

const TextFieldStyle = css({
width: "250px",
height: "31px",
border: "none",
color: "textBlack",

textStyle: "h1",
_placeholder: {
color: "darkDisabled",
},
_focus: {
outline: "none",
},
resize: "none",
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import "react-day-picker/style.css";

import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Text } from "@wow-class/ui";
import useClickOutside from "hooks/useClickOutSide";
import { useEffect, useRef, useState } from "react";
import { DayPicker } from "react-day-picker";
import { Controller, useFormContext } from "react-hook-form";
import { dateToFormatString, formatStringToDate } from "utils/formatDate";

const StudyApplyDatePick = () => {
const [studyDate, setStudyDate] = useState({
fromValue: "",
toValue: "",
});
const datepickerRef = useRef(null);
const [isOpen, setOpen] = useState<boolean>(false);
const { control, setValue } = useFormContext();
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
const [inputValue, setInputValue] = useState("");

useClickOutside(datepickerRef, () => {
setOpen(false);
});

useEffect(() => {
if (studyDate.fromValue) {
setInputValue(`${studyDate.fromValue} ~ ${studyDate.toValue}`);
setValue("applicationStartDate", studyDate.fromValue);
setValue("applicationEndDate", studyDate.toValue);
} else {
setInputValue("");
}
}, [studyDate, setValue]);
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

return (
<Flex direction="column" gap="xs" height="128px" position="relative">
<Text color="sub" typo="label2">
스터디 신청 기간
</Text>
<Controller
control={control}
name="applicationStartDate"
render={() => (
<input
className={StudyDatePickerStyle}
placeholder="YYYY-MM-DD ~ YYYY-MM-DD"
value={inputValue}
onClick={() => {
setOpen(!isOpen);
}}
/>
)}
rules={{
required: true,
}}
/>

{isOpen && (
<div ref={datepickerRef}>
<DayPicker
mode="range"
weekStartsOn={1}
selected={{
from: formatStringToDate(studyDate.fromValue),
to: formatStringToDate(studyDate.toValue),
}}
style={{
position: "absolute",
top: "100px",
zIndex: 99,
backgroundColor: "white",
}}
onSelect={(triggerDate) => {
setStudyDate({
fromValue: dateToFormatString(triggerDate?.from),
toValue: dateToFormatString(triggerDate?.to),
});
}}
/>
</div>
)}
</Flex>
);
};

export default StudyApplyDatePick;

const StudyDatePickerStyle = css({
width: "100%",
maxWidth: "358px",
border: "1px solid",
borderRadius: "sm",
borderColor: "outline",
height: "44px",
padding: "8px 12px",
caretColor: "transparent",
cursor: "pointer",
_placeholder: {
color: "outline",
},
_focus: {
outline: "none",
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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";

const StudyCourseSelect = () => {
const { control } = useFormContext();
return (
<Flex direction="column" gap="xs">
<Controller
control={control}
name="totalWeek"
render={({ field }) => (
<DropDown
{...field}
label="스터디 코스"
placeholder="선택하세요"
value={field.value ? String(field.value) : ""}
onChange={({ selectedValue }) => {
field.onChange(Number(selectedValue));
}}
>
<DropDownOption text="1주" value="1" />
<DropDownOption text="2주" value="2" />
<DropDownOption text="3주" value="3" />
<DropDownOption text="4주" value="4" />
<DropDownOption text="5주" value="5" />
<DropDownOption text="6주" value="6" />
<DropDownOption text="7주" value="7" />
<DropDownOption text="8주" value="8" />
<DropDownOption text="9주" value="9" />
<DropDownOption text="10주" value="10" />
</DropDown>
)}
rules={{
required: true,
}}
/>
<Text color="primary" typo="body3">
* 휴강 주차 포함
</Text>
</Flex>
);
};

export default StudyCourseSelect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Controller, useFormContext } from "react-hook-form";
import DropDown from "wowds-ui/DropDown";
import DropDownOption from "wowds-ui/DropDownOption";

const StudyDayOfWeekSelect = () => {
const { control } = useFormContext();
return (
<Controller
control={control}
name="dayOfWeek"
render={({ field }) => (
<DropDown
label="스터디 요일"
placeholder="선택하세요"
{...field}
onChange={({ selectedValue }) => {
field.onChange(selectedValue);
}}
>
<DropDownOption text="월요일" value="MONDAY" />
<DropDownOption text="화요일" value="TUESDAY" />
<DropDownOption text="수요일" value="WEDNESDAY" />
<DropDownOption text="목요일" value="THURSDAY" />
<DropDownOption text="금요일" value="FRIDAY" />
<DropDownOption text="토요일" value="SATURDAY" />
<DropDownOption text="일요일" value="SUNDAY" />
</DropDown>
)}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
rules={{
required: true,
}}
/>
);
};

export default StudyDayOfWeekSelect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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";

const StudyFormatSelect = () => {
const { control } = useFormContext();
return (
<Controller
control={control}
name="studyType"
render={({ field }) => (
<DropDown
{...field}
label="스터디 형식"
placeholder="선택하세요"
onChange={({ selectedValue }) => {
field.onChange(selectedValue);
}}
>
<DropDownOption
value="ASSIGNMENT"
text={
<Flex alignItems="center" gap="md">
<Text typo="body1">오프라인 세션</Text>
<Text color="sub" typo="body2">
오프라인으로 진행해요.
</Text>
</Flex>
}
/>
<DropDownOption
value="ONLINE"
text={
<Flex alignItems="center" gap="md">
<Text typo="body1">온라인 세션</Text>
<Text color="sub" typo="body2">
온라인으로 진행해요.
</Text>
</Flex>
}
/>
<DropDownOption
value="OFFLINE"
text={
<Flex alignItems="center" gap="md">
<Text typo="body1">과제 스터디</Text>
<Text color="sub" typo="body2">
별도 강의 없이 과제만 진행해요.
</Text>
</Flex>
}
/>
</DropDown>
)}
rules={{
required: true,
}}
/>
);
};

export default StudyFormatSelect;
Loading