Skip to content

Commit

Permalink
[Feature] 스터디 기본 정보 조회하기 UI 생성 및 api 연결 (#42)
Browse files Browse the repository at this point in the history
* chore: lock 패키지 변경 사항 반영

* chore: 중복된 Navbar 컴포넌트 삭제

* feat: 개설 스터디 기본 잡기

* feat: 스터디 개설 페이지 레이아웃

* fix: 찌그러짐 방지용 minWidth 추가

* feat: 스터디 개설하기 뷰 생성

* fix: 개설된 스터디로 화면 옮기기

* feat: auth 체크용 middleWare 생성

* fix: utils fetcher 함수 export 경로 변경

* feat: 스터디 생성하기 페이지 생성

* fix: router handler 삭제

* refactor: api path 상수로 수정

* feat: isAdmin 함수 추가

* fix: 코드리뷰 반영

* fix: admin여부에 따라 스터디 생성 박스 보이지 않도록

* chore: 패키지 설치

* fix: 빌드에러 고치기

* fix: isadmin 판별 로직 미들웨어에서 진행

* feat: 역할 논리 다시

* fix: 폴더명 변경

* fix: createStudy 경로 변경

* feat:wow-icons 추가

* refactor: 컴포넌트 폴더위치 변경

* chore:react-hook-form 설치

* feat: 복잡한 UI 설계 react-hook-form

* feat: 스터디 수강 시작 날짜 지정

* chore: timepicker 패키지 설치

* feat: 스터디 신청 UI 완성

* fix: 쓸데없는 콘솔로그 제거

* feat: api 연결

* feat:api 호출 성공시 redirect

* fix: 캐시 지워서 빌드에러 해결

* chore: 패키지 설치

* feat: 스터디 리스트 보기 뷰

* fix: api 관련 코드리뷰 반영

* fix: 코드리뷰 반영

* fix: navbar 두개인것 고치기

* feat: Header, 기본 레이아웃 세팅

* feat: Header 생성

* feat: 출석 보기

* fix: 코드리뷰 반영

* fix: 코드리뷰 반영

* fix: 코드리뷰 반영

* fix: api 추가 및 하드코딩 제거

* feat: 과제 목록 보기 api 연결

* feat: 과제 목록 생성

* feat: 스터디 커리큘럼 생성 기능 및 api 연결

* feat: 스터디 기본 정보 대시보드

* fix: 노션 링크 없을 때에 에러페이지 안뜨게끔 수정

* fix: padwithzero 추가

* fix: 노션 null 처리 진행

* fix: 중복 요소 제거

* fix: 코드리뷰 반영 및 모든 mock 데이터 제거

* fix: 필요없는 console 삭제

* fix: 코드리뷰 반영

---------

Co-authored-by: ghdtjgus76 <[email protected]>
  • Loading branch information
eugene028 and ghdtjgus76 authored Aug 25, 2024
1 parent 1fb9df9 commit 216c3f4
Show file tree
Hide file tree
Showing 30 changed files with 680 additions and 188 deletions.
47 changes: 47 additions & 0 deletions apps/admin/apis/study/studyInfoApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { fetcher } from "@wow-class/utils";
import { mentorApiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import type { AssignmentApiResponseDto } from "types/dtos/assignmentList";
import type { SessionApiResponseDto } from "types/dtos/sessionList";
import type { StudyBasicInfoApiResponseDto } from "types/dtos/studyBasicInfo";

export const studyInfoApi = {
getStudyBasicInfo: async (studyId: number) => {
const response = await fetcher.get<StudyBasicInfoApiResponseDto>(
`/common/studies/${studyId}`,
{
next: { tags: [tags.studyBasicInfo] },
cache: "force-cache",
}
);
return response.data;
},
getAssignmentList: async (studyId: number) => {
const response = await fetcher.get<AssignmentApiResponseDto[]>(
`${mentorApiPath.assignments}?studyId=${studyId}`,
{
next: { tags: [tags.assignments] },
cache: "force-cache",
}
);
return response.data;
},
cancelAssignment: async (studyDetailId: number) => {
const response = await fetcher.patch(
`/mentor/study-details/${studyDetailId}/assignments/cancel`,
{}
);

return { success: response.ok };
},
getSessionList: async (studyId: number) => {
const response = await fetcher.get<SessionApiResponseDto[]>(
`${mentorApiPath.sessions}?study=${studyId}`,
{
next: { tags: [tags.sessions] },
cache: "force-cache",
}
);
return response.data;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Space, Text } from "@wow-class/ui";
import { studyInfoApi } from "apis/study/studyInfoApi";

import AssignmentListItem from "./AssignmentListItem";

const AssignmentList = async ({ studyId }: { studyId: string }) => {
const assignmentList = await studyInfoApi.getAssignmentList(
parseInt(studyId, 10)
);

return (
<section aria-label="assignment-list">
<Text typo="h2">주차별 과제</Text>
<Space height={24} />
{assignmentList?.map((assignment, index) => {
return (
<AssignmentListItem
assignment={assignment}
key={`studyDetailId-${index}`}
/>
);
})}
</section>
);
};

export default AssignmentList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"use client";
import { cva } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Table, Text } from "@wow-class/ui";
import { padWithZero, parseISODate } from "@wow-class/utils";
import { studyInfoApi } from "apis/study/studyInfoApi";
import { tags } from "constants/tags";
import Link from "next/link";
import type { AssignmentApiResponseDto } from "types/dtos/assignmentList";
import getIsCurrentWeek from "utils/getIsCurrentWeek";
import { revalidateTagByName } from "utils/revalidateTagByName";
import Button from "wowds-ui/Button";

const AssignmentListItem = ({
assignment,
}: {
assignment: AssignmentApiResponseDto;
}) => {
const {
studyDetailId,
title,
deadline,
week,
descriptionLink,
assignmentStatus,
} = assignment;
const thisWeekAssignment = getIsCurrentWeek(deadline);
const { year, month, day, hours, minutes } = parseISODate(deadline);

const studyDeadline = `종료 : ${year}${month}${day}${padWithZero(hours)}:${padWithZero(minutes)}`;

const handleCancelAssignment = async (studyDetailId: number) => {
const { success } = await studyInfoApi.cancelAssignment(studyDetailId);
if (success) {
window.alert("휴강 처리에 성공했어요.");
revalidateTagByName(tags.assignments);
} else {
window.alert("휴강 처리에 실패했어요.");
}
};
return (
<Table>
<Table.Left style={TableLeftStyle}>
<Flex alignItems="center" gap="xxs">
<div
className={ThisWeekBarStyle({
type: thisWeekAssignment ? "thisWeek" : "notThisWeek",
})}
/>
<Text typo="body1">{week}주차</Text>
</Flex>
<Flex direction="column" gap="xxs">
<Text typo="h3">{title || "-"}</Text>
<Text color="sub" typo="body2">
{deadline ? studyDeadline : "-"}
</Text>
</Flex>
</Table.Left>
<Table.Right>
<>
{assignmentStatus === "OPEN" ? (
<Button
asProp={Link}
href={descriptionLink || ""}
size="sm"
variant="outline"
>
과제 내용보기
</Button>
) : (
<Flex gap="sm">
<Button
color="sub"
size="sm"
variant="sub"
onClick={() => handleCancelAssignment(studyDetailId)}
>
과제 휴강처리
</Button>
<Button
size="sm"
variant="solid"
onClick={() => {
console.log("TODO: 과제 개설 페이지 연결");
}}
>
과제 개설하기
</Button>
</Flex>
)}
</>
</Table.Right>
</Table>
);
};
export default AssignmentListItem;

const ThisWeekBarStyle = cva({
base: {
width: "4px",
height: "18px",
},
variants: {
type: {
thisWeek: {
backgroundColor: "primary",
},
notThisWeek: {
backgroundColor: "transparent",
},
},
},
});

const TableLeftStyle = {
display: "flex",
alignItems: "center",
gap: "47px",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Space, Text } from "@wow-class/ui";
import Box from "wowds-ui/Box";
import Tag from "wowds-ui/Tag";

const CheckAttendanceNumber = () => {
return (
<section>
<Text typo="h2">주차별 출결 번호</Text>
<Space height={24} />
<div className={AttendanceContainerStyle}>
<Box
style={AttendanceBoxStyle}
text={
<Flex direction="column" gap="lg">
<Flex direction="column" gap="xs">
<Flex alignItems="center" gap="xs">
<Text typo="h2">4주차 출결 번호</Text>
<Tag color="blue" variant="solid2">
진행중
</Tag>
</Flex>
<Text color="sub" typo="body1">
2024년 5월 23일 00:00 - 23:59까지
</Text>
</Flex>
<Text color="primary" style={AttendanceNumberStyle}>
2143
</Text>
</Flex>
}
/>
<Box
style={AttendanceBoxStyle}
text={
<Flex direction="column" gap="lg">
<Flex direction="column" gap="xs">
<Flex alignItems="center" gap="xs">
<Text typo="h2">5주차 출결 번호</Text>
<Tag color="grey" variant="solid2">
진행전
</Tag>
</Flex>
<Text color="sub" typo="body1">
2024년 5월 23일 00:00 - 23:59까지
</Text>
</Flex>
<Text color="outline" style={AttendanceNumberStyle}>
4176
</Text>
</Flex>
}
/>
</div>
</section>
);
};

export default CheckAttendanceNumber;

const AttendanceContainerStyle = css({
display: "flex",
direction: "row",
alignItems: "center",
gap: "md",
});

const AttendanceBoxStyle = {
maxWidth: "282px",
};

const AttendanceNumberStyle = {
fontSize: "40px",
fontWeight: 700,
};
Loading

0 comments on commit 216c3f4

Please sign in to comment.