-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
347 additions
and
351 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
apps/admin/app/studies/[studyId]/_components/assignment/AssignmentListItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
165 changes: 165 additions & 0 deletions
165
apps/admin/app/studies/[studyId]/_components/header/Header.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
"use client"; | ||
|
||
import { css } from "@styled-system/css"; | ||
import { Flex } from "@styled-system/jsx"; | ||
import { Space, Text } from "@wow-class/ui"; | ||
import { padWithZero, parseISODate } from "@wow-class/utils"; | ||
import { studyInfoApi } from "apis/study/studyInfoApi"; | ||
import { dayToKorean } from "constants/dayToKorean"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
import { useEffect, useState } from "react"; | ||
import type { StudyBasicInfoApiResponseDto } from "types/dtos/studyBasicInfo"; | ||
import { DownArrow } from "wowds-icons"; | ||
import TextButton from "wowds-ui/TextButton"; | ||
|
||
const Header = ({ studyId }: { studyId: string }) => { | ||
const [showIntro, setShowIntro] = useState(false); | ||
const [studyInfo, setStudyInfo] = useState< | ||
StudyBasicInfoApiResponseDto | undefined | ||
>(undefined); | ||
|
||
useEffect(() => { | ||
const fetchData = async () => { | ||
if (studyId) { | ||
const data = await studyInfoApi.getStudyBasicInfo( | ||
parseInt(studyId, 10) | ||
); | ||
if (data) setStudyInfo(data); | ||
} | ||
}; | ||
|
||
fetchData(); | ||
}, [studyId]); | ||
|
||
const handleClickShowIntro = () => { | ||
setShowIntro((prev) => !prev); | ||
}; | ||
|
||
const introSectionButtonAriaLabel = showIntro | ||
? "Collapse introduction" | ||
: "Expand introduction"; | ||
const introSectionIconAriaLabel = showIntro | ||
? "Collapse introduction icon" | ||
: "Expand introduction icon"; | ||
|
||
if (!studyInfo) return null; | ||
|
||
const { | ||
title, | ||
academicYear, | ||
semester, | ||
mentorName, | ||
studyType, | ||
dayOfWeek, | ||
startTime: { hour: startHour, minute: startMinute }, | ||
endTime: { hour: endHour, minute: endMinute }, | ||
totalWeek, | ||
period: { startDate, endDate }, | ||
introduction, | ||
notionLink, | ||
} = studyInfo; | ||
|
||
const { month: startMonth, day: startDay } = parseISODate(startDate); | ||
const { month: endMonth, day: endDay } = parseISODate(endDate); | ||
const studySemester = `${academicYear}-${semester === "FIRST" ? 1 : 2}`; | ||
const studySchedule = `${dayToKorean[dayOfWeek]} ${startHour}:${padWithZero(startMinute)}- | ||
${endHour}:${padWithZero(endMinute)}`; | ||
const studyPeriod = `${padWithZero(startMonth)}.${padWithZero(startDay)}- | ||
${padWithZero(endMonth)}.${padWithZero(endDay)}`; | ||
|
||
return ( | ||
<header> | ||
<section aria-label="my-study-header"> | ||
<Flex alignItems="center" gap={8}> | ||
<Text as="h1" typo="h1"> | ||
{title} | ||
</Text> | ||
<button | ||
aria-controls="intro-section" | ||
aria-expanded={showIntro} | ||
aria-label={introSectionButtonAriaLabel} | ||
tabIndex={0} | ||
onClick={handleClickShowIntro} | ||
> | ||
<DownArrow | ||
aria-label={introSectionIconAriaLabel} | ||
className={downArrowIconStyle} | ||
height={20} | ||
stroke="textBlack" | ||
style={{ rotate: showIntro ? "0deg" : "180deg" }} | ||
width={20} | ||
/> | ||
</button> | ||
</Flex> | ||
</section> | ||
<section> | ||
<Space height={8} /> | ||
<Flex gap="xs"> | ||
<Text as="h5" color="sub"> | ||
{studySemester} | ||
</Text> | ||
<ItemSeparator /> | ||
<Text as="h5" color="sub"> | ||
{mentorName} 멘토 | ||
</Text> | ||
<ItemSeparator /> | ||
<Text as="h5" color="sub"> | ||
{studyType} | ||
</Text> | ||
</Flex> | ||
</section> | ||
{showIntro && ( | ||
<section id="intro-section"> | ||
<section aria-labelledby="study-schedule-heading"> | ||
<Space height={24} /> | ||
<Flex direction="column" gap="4"> | ||
<Text as="h3" typo="h3"> | ||
스터디 일정 | ||
</Text> | ||
<Flex gap="xs"> | ||
<Text as="h5" color="sub"> | ||
{studySchedule} | ||
</Text> | ||
<ItemSeparator /> | ||
<Text as="h5" color="sub"> | ||
{totalWeek}주 코스 | ||
</Text> | ||
<ItemSeparator /> | ||
<Text as="h5" color="sub"> | ||
{studyPeriod} | ||
</Text> | ||
</Flex> | ||
</Flex> | ||
</section> | ||
<section aria-labelledby="study-intro-heading"> | ||
<Space height={28} /> | ||
<Flex direction="column" gap="xs"> | ||
<Text as="h3" typo="h3"> | ||
스터디 소개 | ||
</Text> | ||
<Flex alignItems="center" gap="sm"> | ||
<Link href={notionLink || ""} role="button" tabIndex={0}> | ||
<TextButton style={{ padding: "0px" }} text="스터디 소개" /> | ||
</Link> | ||
<Text color="sub" typo="body1"> | ||
{introduction} | ||
</Text> | ||
</Flex> | ||
</Flex> | ||
</section> | ||
</section> | ||
)} | ||
</header> | ||
); | ||
}; | ||
|
||
export default Header; | ||
|
||
const ItemSeparator = () => ( | ||
<Image alt="item separator" height={4} src="/images/dot.svg" width={4} /> | ||
); | ||
|
||
const downArrowIconStyle = css({ | ||
cursor: "pointer", | ||
}); |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.