diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/_components/Navigation.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/_components/Navigation.tsx
new file mode 100644
index 00000000..515d6105
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/_components/Navigation.tsx
@@ -0,0 +1,67 @@
+"use client";
+
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import { Alarm } from "components/Icon/Alarm";
+import { Calendar } from "components/Icon/Calendar";
+import { Home } from "components/Icon/Home";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+
+const Navigation = () => {
+ const pathname = usePathname();
+
+ return (
+
+ );
+};
+
+export default Navigation;
+
+const navigationStyle = css({
+ position: "fixed",
+ left: 0,
+ bottom: 0,
+ backgroundColor: "backgroundNormal",
+ height: "90px",
+ width: "100%",
+ paddingTop: "16px",
+ boxShadow: "0px -2px 10px 0px rgba(0, 0, 0, 0.10)",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/_components/PageHeader.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/_components/PageHeader.tsx
new file mode 100644
index 00000000..c6daaf03
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/_components/PageHeader.tsx
@@ -0,0 +1,21 @@
+import { css } from "@styled-system/css";
+import { membersApi } from "apis/membersApi";
+import Header from "wowds-ui/Header";
+
+const PageHeader = async () => {
+ const myInfo = await membersApi.getMyAccountInfo();
+
+ return (
+
+
+
+ );
+};
+
+const headerStyle = css({
+ position: "fixed",
+ backgroundColor: "backgroundNormal",
+ width: "100%",
+});
+
+export default PageHeader;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/layout.tsx
new file mode 100644
index 00000000..87bfa702
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/layout.tsx
@@ -0,0 +1,23 @@
+import { css } from "@styled-system/css";
+import type { Metadata } from "next";
+
+import Navigation from "../_components/Navigation";
+
+export const metadata: Metadata = {
+ title: "스터디 공지",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Layout;
+
+const layoutContainerStyle = css({
+ marginBottom: "90px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/page.tsx
new file mode 100644
index 00000000..eb8c96ff
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/announcement/page.tsx
@@ -0,0 +1,85 @@
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import { formatISODateWithDot } from "@wow-class/utils";
+import { myStudyApi } from "apis/myStudyApi";
+import Image from "next/image";
+
+const MobileStudyAnnouncementPage = async () => {
+ const myOngoingStudyInfoData = await myStudyApi.getMyOngoingStudyInfo();
+
+ if (!myOngoingStudyInfoData?.studyId) {
+ return;
+ }
+
+ const studyAnnouncementListData = await myStudyApi.getStudyAnnouncementList(
+ myOngoingStudyInfoData?.studyId
+ );
+
+ return (
+
+
+ 스터디 공지
+
+
+ {studyAnnouncementListData?.length ? (
+ studyAnnouncementListData?.map(
+ ({ studyAnnounceId, title, createdDate }) => (
+
+
+ {title}
+
+
+ {formatISODateWithDot(createdDate)}
+
+
+ )
+ )
+ ) : (
+
+
+
+ 올라온 공지가 없어요.
+
+
+ )}
+
+
+ );
+};
+
+export default MobileStudyAnnouncementPage;
+
+const studyAnnouncementListHeadingStyle = css({
+ marginBottom: "md",
+});
+
+const studyAnnouncementListBoxStyle = css({
+ alignItems: "center",
+ borderRadius: "10px",
+ height: "72px",
+ display: "flex",
+ justifyContent: "space-between",
+ border: "1px solid",
+ borderColor: "outline",
+ backgroundColor: "backgroundNormal",
+ padding: "24px",
+});
+
+const studyAnnouncementTitleStyle = css({
+ whiteSpace: "nowrap",
+ overflow: "hidden",
+ textOverflow: "ellipsis",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/_components/AttendanceCheckBox.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/_components/AttendanceCheckBox.tsx
new file mode 100644
index 00000000..4e216f84
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/_components/AttendanceCheckBox.tsx
@@ -0,0 +1,57 @@
+"use client";
+
+import { Divider, Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import { parseISODate } from "@wow-class/utils";
+import useAttendanceCheckSearchParams from "hooks/useAttendanceCheckSearchParams";
+import Link from "next/link";
+import Button from "wowds-ui/Button";
+
+export const AttendanceCheckBox = () => {
+ const { studyDetailId, studyName, deadLine, currentWeek, mentorName } =
+ useAttendanceCheckSearchParams();
+
+ const { year, month, day, hours, minutes } = parseISODate(deadLine);
+
+ const {
+ year: currentYear,
+ month: currentMonth,
+ day: currentDay,
+ } = parseISODate(new Date().toISOString());
+
+ return (
+ <>
+
+ {studyName}
+
+ {mentorName}
+
+
+
+
+
+ 출석 체크
+ {currentWeek}주차
+
+
+ 수강 날짜
+
+ {currentYear}년 {currentMonth}월 {currentDay}일
+
+
+
+ 출석 인정 시간
+
+ {year}년 {month}월 {day}일 00:00 - {hours}:{minutes}
+
+
+
+
+ >
+ );
+};
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/layout.tsx
new file mode 100644
index 00000000..4cc7ba6e
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/layout.tsx
@@ -0,0 +1,11 @@
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "출석 체크",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return <>{children}>;
+};
+
+export default Layout;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/page.tsx
new file mode 100644
index 00000000..7852bc6e
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-info/page.tsx
@@ -0,0 +1,22 @@
+"use client";
+
+import { Space, Text } from "@wow-class/ui";
+import { Suspense } from "react";
+
+import { AttendanceCheckBox } from "./_components/AttendanceCheckBox";
+
+const MobileAttendanceCheckInfoPage = () => {
+ return (
+ <>
+
+ 출석 체크
+
+
+
+
+
+ >
+ );
+};
+
+export default MobileAttendanceCheckInfoPage;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/AttendanceCheckForm.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/AttendanceCheckForm.tsx
new file mode 100644
index 00000000..4c9fcced
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/AttendanceCheckForm.tsx
@@ -0,0 +1,112 @@
+"use client";
+
+import { myStudyApi } from "apis/myStudyApi";
+import { tags } from "constants/tags";
+import useAttendanceCheckSearchParams from "hooks/useAttendanceCheckSearchParams";
+import type { CSSProperties, KeyboardEventHandler } from "react";
+import { useState } from "react";
+import { revalidateTagByName } from "utils/revalidateTagByName";
+import { validateAttendanceNumber } from "utils/validateAttendanceNumber";
+import { color } from "wowds-tokens";
+import Button from "wowds-ui/Button";
+import TextField from "wowds-ui/TextField";
+
+const AttendanceCheckForm = ({
+ onAttendanceSuccess,
+}: {
+ onAttendanceSuccess: () => void;
+}) => {
+ const { studyDetailId } = useAttendanceCheckSearchParams();
+
+ const [error, setError] = useState(false);
+ const [attendanceNumber, setAttendanceNumber] = useState("");
+
+ const handleChangeAttendanceNumber = (value: string) => {
+ setAttendanceNumber(value);
+ };
+
+ const isAttendanceNumberValid = (attendanceNumber: string) => {
+ return validateAttendanceNumber(attendanceNumber);
+ };
+
+ const checkAttendance = async (
+ studyDetailId: number,
+ attendanceNumber: string
+ ) => {
+ const { success } = await myStudyApi.checkAttendance(
+ studyDetailId,
+ attendanceNumber
+ );
+ return success;
+ };
+
+ const handleClickAttendanceCheckButton = async () => {
+ const trimmedAttendanceNumber = attendanceNumber.trim();
+
+ if (!isAttendanceNumberValid(trimmedAttendanceNumber)) {
+ return setError(true);
+ }
+
+ const success = await checkAttendance(
+ +studyDetailId,
+ trimmedAttendanceNumber
+ );
+
+ if (!success) {
+ return setError(true);
+ }
+
+ handleAttendanceSuccess();
+ };
+
+ const handleAttendanceSuccess = () => {
+ onAttendanceSuccess();
+ setError(false);
+ revalidateTagByName(tags.dailyTask);
+ };
+
+ const handleKeyDown: KeyboardEventHandler = (event) => {
+ if (event.key === "Enter" || event.key === " ") {
+ event.preventDefault();
+ }
+ };
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default AttendanceCheckForm;
+
+const textfieldHelperText = • 출석 실패! 출결번호를 확인해주세요.
;
+
+const buttonStyle: CSSProperties = {
+ bottom: "20px",
+ position: "absolute",
+ width: "calc(100% - 32px)",
+ color: color.white,
+};
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/StudyInfo.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/StudyInfo.tsx
new file mode 100644
index 00000000..69f14ccb
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/_components/StudyInfo.tsx
@@ -0,0 +1,17 @@
+"use client";
+
+import { Text } from "@wow-class/ui";
+import useAttendanceCheckSearchParams from "hooks/useAttendanceCheckSearchParams";
+const StudyInfo = () => {
+ const { studyName, currentWeek } = useAttendanceCheckSearchParams();
+ return (
+ <>
+
+ {studyName}
+ {currentWeek}주차
+
+ >
+ );
+};
+
+export default StudyInfo;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/layout.tsx
new file mode 100644
index 00000000..4cc7ba6e
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/layout.tsx
@@ -0,0 +1,11 @@
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "출석 체크",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return <>{children}>;
+};
+
+export default Layout;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/page.tsx
new file mode 100644
index 00000000..263e0133
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/attendance-check-input/page.tsx
@@ -0,0 +1,69 @@
+"use client";
+
+import { Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import Image from "next/image";
+import Link from "next/link";
+import { Suspense, useState } from "react";
+import { color } from "wowds-tokens";
+import Button from "wowds-ui/Button";
+
+import AttendanceCheckForm from "./_components/AttendanceCheckForm";
+import StudyInfo from "./_components/StudyInfo";
+
+const MobileAttendanceCheckInputPage = () => {
+ const [attended, setAttended] = useState(false);
+
+ return attended ? (
+
+
+
+ 출석이 완료되었어요
+
+
+
+
+
+
+ ) : (
+
+
+ 출석 체크
+
+
+
+ 스터디 시작 후 멘토의 안내에 따라
+ 출결번호를 입력해주세요.
+
+
+
+ {
+ setAttended(true);
+ }}
+ />
+
+
+ );
+};
+
+export default MobileAttendanceCheckInputPage;
+
+const buttonStyle: React.CSSProperties = {
+ bottom: "20px",
+ position: "absolute",
+ width: "calc(100% - 32px)",
+ color: color.white,
+};
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/auth/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/auth/page.tsx
new file mode 100644
index 00000000..9add65cc
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/auth/page.tsx
@@ -0,0 +1,51 @@
+import { Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import { routePath } from "constants/routePath";
+import Image from "next/image";
+import Link from "next/link";
+import type { CSSProperties } from "react";
+import { color } from "wowds-tokens";
+import Button from "wowds-ui/Button";
+
+const MobileAuthPage = async () => {
+ return (
+ <>
+
+ 로그인
+
+
+ 와우클래스는 GDGoC 정회원만 이용 가능해요.
+ GDGoC 가입을 위해선 GitHub 계정이 필요해요.
+
+
+
+ >
+ );
+};
+
+const githubLogoIcon = (
+
+);
+
+export default MobileAuthPage;
+
+const githubLoginButtonStyle: CSSProperties = {
+ backgroundColor: `${color.github}`,
+ marginTop: "40px",
+ bottom: "20px",
+ position: "absolute",
+ width: "calc(100% - 32px)",
+};
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/layout.tsx
new file mode 100644
index 00000000..228019da
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/layout.tsx
@@ -0,0 +1,23 @@
+import { css } from "@styled-system/css";
+import type { Metadata } from "next";
+
+import Navigation from "../_components/Navigation";
+
+export const metadata: Metadata = {
+ title: "커리큘럼",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Layout;
+
+const layoutContainerStyle = css({
+ marginBottom: "90px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/page.tsx
new file mode 100644
index 00000000..05068a88
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/curriculum/page.tsx
@@ -0,0 +1,169 @@
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import { myStudyApi } from "apis/myStudyApi";
+import { attendanceStatusMap } from "constants/attendanceStatusMap";
+import { routePath } from "constants/routePath";
+import Link from "next/link";
+import type { ComponentProps } from "react";
+import type {
+ AssignmentSubmissionStatusType,
+ StudyDifficultyType,
+} from "types/entities/myStudy";
+import Tag from "wowds-ui/Tag";
+
+const MobileStudyCurriculumPage = async () => {
+ const myOngoingStudyInfoData = await myStudyApi.getMyOngoingStudyInfo();
+
+ if (!myOngoingStudyInfoData?.studyId) {
+ return;
+ }
+
+ const studyCurriculumData = await myStudyApi.getStudyCurriculumList(
+ myOngoingStudyInfoData?.studyId
+ );
+
+ return (
+
+ 커리큘럼
+
+
+ {studyCurriculumData?.map(
+ (
+ {
+ week,
+ title,
+ description,
+ difficulty,
+ attendanceStatus,
+ assignmentStatus,
+ assignmentSubmissionStatus,
+ curriculumStatus,
+ },
+ index
+ ) => {
+ const { label: difficultyLabel, color: difficultyColor } =
+ difficultyMap[difficulty || "LOW"];
+ const {
+ label: attendanceStatusLabel,
+ color: attendanceStatusColor,
+ } =
+ attendanceStatusMap[
+ curriculumStatus === "CANCELED" ? "ATTENDED" : attendanceStatus
+ ];
+ const {
+ label: assignmentSubmissionStatusLabel,
+ color: assignmentSubmissionStatusColor,
+ } =
+ assignmentStatus === "CANCELED"
+ ? {
+ label: "과제 휴강",
+ color: "grey" as ComponentProps["color"],
+ }
+ : assignmentMap[assignmentSubmissionStatus || "NOT_SUBMITTED"];
+
+ return (
+
+
+
+
+
+ {week}주차
+
+
+
+ {curriculumStatus === "CANCELED" ? (
+
+ 휴강 주차
+
+ ) : description ? (
+
+
+
+ {title}
+
+
+ {difficultyLabel}
+
+
+
+ ) : (
+
+ 작성된 내용이 없어요
+
+ )}
+
+
+
+
+
+ {attendanceStatusLabel}
+
+
+ {assignmentSubmissionStatusLabel}
+
+
+
+
+
+ );
+ }
+ )}
+
+
+ );
+};
+
+export default MobileStudyCurriculumPage;
+
+const difficultyMap: Record<
+ StudyDifficultyType,
+ { label: string; color: ComponentProps["color"] }
+> = {
+ BASIC: { label: "기초", color: "blue" },
+ LOW: { label: "초급", color: "yellow" },
+ MEDIUM: { label: "중급", color: "green" },
+ HIGH: { label: "고급", color: "red" },
+};
+
+const assignmentMap: Record<
+ AssignmentSubmissionStatusType,
+ { label: string; color: ComponentProps["color"] }
+> = {
+ SUCCESS: { label: "과제 제출", color: "blue" },
+ FAILURE: { label: "과제 미제출", color: "red" },
+ NOT_SUBMITTED: { label: "과제 진행전", color: "grey" },
+};
+const boxContainerStyle = css({
+ backgroundColor: "backgroundNormal",
+ border: "1px solid",
+ borderColor: "outline",
+ padding: "24px",
+ borderRadius: "10px",
+ justifyContent: "space-between",
+});
+
+const weekContainerStyle = css({
+ minWidth: "84px",
+ display: "flex",
+ alignItems: "center",
+ gap: "4px",
+});
+
+const tagStyle = {
+ margin: "auto",
+};
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/layout.tsx
new file mode 100644
index 00000000..64120006
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/layout.tsx
@@ -0,0 +1,40 @@
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Space } from "@wow-class/ui";
+import type { Metadata } from "next";
+
+import PageHeader from "./_components/PageHeader";
+
+export const metadata: Metadata = {
+ robots: {
+ index: false,
+ follow: true,
+ },
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+
+
+
+ {children}
+
+
+ );
+};
+
+export default Layout;
+
+const layoutContainerStyle = css({
+ left: 0,
+ lg: {
+ maxWidth: "390px",
+ },
+ width: "100%",
+ backgroundColor: "#f8f8f8",
+ paddingX: "16px",
+ marginTop: "66px",
+ minHeight: "calc(100vh - 66px)",
+ paddingBottom: "20px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AssignmentStatusBox.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AssignmentStatusBox.tsx
new file mode 100644
index 00000000..28512225
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AssignmentStatusBox.tsx
@@ -0,0 +1,103 @@
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import { padWithZero, parseISODate } from "@wow-class/utils";
+import type { ComponentProps } from "react";
+import type { AssignmentSubmissionStatusType } from "types/entities/myStudy";
+import Box from "wowds-ui/Box";
+import Tag from "wowds-ui/Tag";
+
+interface AssignmentStatusBoxProps {
+ week: number;
+ name: string;
+ assignmentSubmissionStatus: AssignmentSubmissionStatusType;
+ deadLine: string;
+}
+
+const AssignmentStatusBox = ({
+ week,
+ name,
+ assignmentSubmissionStatus,
+ deadLine,
+}: AssignmentStatusBoxProps) => {
+ const { year, month, day, hours, minutes } = parseISODate(deadLine);
+
+ const attendanceDeadline = `${year}년 ${month}월 ${day}일 ${padWithZero(hours)}:${padWithZero(minutes)}까지`;
+ const {
+ label: assignmentSubmissionStatusLabel,
+ color: assignmentSubmissionStatusColor,
+ } = assignmentSubmissionStatusMap[assignmentSubmissionStatus];
+
+ return (
+
+
+ 과제
+
+
+
+
+
+ {week}주차 과제
+
+ {assignmentSubmissionStatusLabel && (
+
+ {assignmentSubmissionStatusLabel}
+
+ )}
+
+
+ {name}
+
+
+ {attendanceDeadline}
+
+
+
+
+ }
+ />
+ );
+};
+
+export default AssignmentStatusBox;
+
+const assignmentSubmissionStatusMap: Record<
+ AssignmentSubmissionStatusType,
+ { label: string; color: ComponentProps["color"] }
+> = {
+ SUCCESS: { label: "제출 완료", color: "blue" },
+ FAILURE: { label: "제출 실패", color: "red" },
+ NOT_SUBMITTED: { label: "", color: "grey" },
+};
+
+const dailyTaskBoxStyle = {
+ paddingBottom: "24px",
+};
+
+const dailyTaskBoxContentContainerStyle = css({});
+
+const assignmentNameStyle = css({
+ whiteSpace: "nowrap",
+ overflow: "hidden",
+ textOverflow: "ellipsis",
+});
+
+const tagStyle = css({
+ height: "20px",
+});
+
+const assignmentTextStyle = css({
+ paddingTop: "3.5px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AttendanceStatusBox.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AttendanceStatusBox.tsx
new file mode 100644
index 00000000..3c0d2dd2
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/AttendanceStatusBox.tsx
@@ -0,0 +1,117 @@
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import { padWithZero, parseISODate } from "@wow-class/utils";
+import { myStudyApi } from "apis/myStudyApi";
+import { attendanceStatusMap } from "constants/attendanceStatusMap";
+import Link from "next/link";
+import type { AttendanceStatusType } from "types/entities/myStudy";
+import Box from "wowds-ui/Box";
+import Button from "wowds-ui/Button";
+import Tag from "wowds-ui/Tag";
+
+interface AttendanceStatusBoxProps {
+ week: number;
+ studyDetailId: number;
+ attendanceStatus: AttendanceStatusType;
+ deadLine: string;
+}
+
+const AttendanceStatusBox = async ({
+ week,
+ attendanceStatus,
+ studyDetailId,
+ deadLine,
+}: AttendanceStatusBoxProps) => {
+ const myOngoingStudyInfoResponse = await myStudyApi.getMyOngoingStudyInfo();
+
+ if (!myOngoingStudyInfoResponse?.studyId) {
+ return null;
+ }
+
+ const basicStudyInfoResponse = await myStudyApi.getBasicStudyInfo(
+ myOngoingStudyInfoResponse?.studyId
+ );
+ const studyName = basicStudyInfoResponse?.title;
+ const mentorName = basicStudyInfoResponse?.mentorName;
+ const {
+ year: startYear,
+ month: startMonth,
+ day: startDay,
+ hours: endHours,
+ minutes: endMinutes,
+ } = parseISODate(deadLine);
+
+ const attendancePeriod = `${startYear}년 ${startMonth}월 ${startDay}일 00:00 - ${padWithZero(endHours)}:${padWithZero(endMinutes)}까지`;
+ const { label: attendanceStatusLabel, color: attendanceStatusColor } =
+ attendanceStatusMap[attendanceStatus];
+
+ const attendanceButtonText =
+ attendanceStatus === "ATTENDED" ? "출석 체크 완료" : "출석 체크하기";
+ return (
+
+
+
+ 출석
+
+
+
+
+
+ {week}주차 출석체크
+
+
+ {attendanceStatusLabel}
+
+
+
+ {attendancePeriod}
+
+
+
+
+
+
+ }
+ />
+ );
+};
+
+export default AttendanceStatusBox;
+
+const dailyTaskBoxStyle = {
+ paddingBottom: "24px",
+ gap: "0px",
+};
+
+const dailyTaskBoxContentContainerStyle = css({});
+
+const attendanceButtonStyle = {};
+
+const attendanceTextStyle = css({
+ paddingTop: "3.5px",
+});
+
+const tagStyle = css({
+ height: "20px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTaskItem.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTaskItem.tsx
new file mode 100644
index 00000000..5fb68aed
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTaskItem.tsx
@@ -0,0 +1,43 @@
+import type { DailyTaskDto } from "types/dtos/myStudy";
+import type { DailyTaskType } from "types/entities/myStudy";
+
+import AssignmentStatusBox from "./AssignmentStatusBox";
+import AttendanceStatusBox from "./AttendanceStatusBox";
+
+const DailyTaskItem = ({
+ dailyTask,
+ index,
+}: {
+ dailyTask: DailyTaskDto;
+ index: number;
+}) => {
+ const {
+ taskType,
+ week,
+ deadLine,
+ attendanceStatus,
+ assignmentTitle,
+ assignmentSubmissionStatus,
+ studyDetailId,
+ } = dailyTask;
+
+ return taskType === "ATTENDANCE" ? (
+
+ ) : (
+
+ );
+};
+
+export default DailyTaskItem;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTasks.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTasks.tsx
new file mode 100644
index 00000000..372af9a1
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/DailyTasks.tsx
@@ -0,0 +1,50 @@
+import { Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import { myStudyApi } from "apis/myStudyApi";
+import Image from "next/image";
+
+import DailyTaskItem from "./DailyTaskItem";
+
+const DailyTasks = async () => {
+ const myOngoingStudyData = await myStudyApi.getMyOngoingStudyInfo();
+
+ if (!myOngoingStudyData?.studyId) {
+ return null;
+ }
+
+ const dailyTaskData = await myStudyApi.getDailyTaskList(
+ myOngoingStudyData?.studyId
+ );
+
+ return (
+ <>
+ 오늘의 할 일
+
+
+ {dailyTaskData?.length ? (
+ dailyTaskData.map((dailyTask, index) => (
+
+ ))
+ ) : (
+
+
+
+ 아직 할 일이 없어요.
+
+
+ )}
+
+ >
+ );
+};
+
+export default DailyTasks;
diff --git a/apps/client/app/(afterLogin)/my-study/_components/EmptyStudy.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/EmptyStudy.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/EmptyStudy.tsx
rename to apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/EmptyStudy.tsx
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/Header.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/Header.tsx
new file mode 100644
index 00000000..eae73d94
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/_components/Header.tsx
@@ -0,0 +1,21 @@
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import { myStudyApi } from "apis/myStudyApi";
+
+const Header = async ({ studyId }: { studyId: number }) => {
+ const basicStudyInfoData = await myStudyApi.getBasicStudyInfo(studyId);
+ return (
+
+
+
+ 수강 중인 스터디
+
+
+ {basicStudyInfoData?.title}
+
+
+
+ );
+};
+
+export default Header;
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/layout.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/layout.tsx
new file mode 100644
index 00000000..90000bf3
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/layout.tsx
@@ -0,0 +1,23 @@
+import { css } from "@styled-system/css";
+import type { Metadata } from "next";
+
+import Navigation from "../_components/Navigation";
+
+export const metadata: Metadata = {
+ title: "나의 스터디",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Layout;
+
+const layoutContainerStyle = css({
+ marginBottom: "90px",
+});
diff --git a/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/page.tsx b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/page.tsx
new file mode 100644
index 00000000..bc108d61
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(mobile)/mobile/my-study/page.tsx
@@ -0,0 +1,21 @@
+import { Space } from "@wow-class/ui";
+import { myStudyApi } from "apis/myStudyApi";
+
+import DailyTasks from "./_components/DailyTasks";
+import EmptyStudy from "./_components/EmptyStudy";
+import Header from "./_components/Header";
+
+const MobileMyStudyPage = async () => {
+ const myOngoingStudyInfoData = await myStudyApi.getMyOngoingStudyInfo();
+ return myOngoingStudyInfoData?.studyId ? (
+ <>
+
+
+
+ >
+ ) : (
+
+ );
+};
+
+export default MobileMyStudyPage;
diff --git a/apps/client/app/(afterLogin)/layout.tsx b/apps/client/app/(afterLogin)/(pc)/layout.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/layout.tsx
rename to apps/client/app/(afterLogin)/(pc)/layout.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/@modal/(.)logout/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/@modal/(.)logout/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/@modal/(.)logout/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/@modal/(.)logout/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/@modal/default.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/@modal/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/@modal/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/@modal/default.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/_components/CompletedStudy.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/_components/CompletedStudy.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/_components/CompletedStudy.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/_components/CompletedStudy.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/_components/MyInfoBox.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/_components/MyInfoBox.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/_components/MyInfoBox.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/_components/MyInfoBox.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/default.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/default.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/layout.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/layout.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/layout.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/layout.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/logout/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/logout/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/logout/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/logout/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-page/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-page/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-page/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-page/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/@modal/(.)attendance-check/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/@modal/(.)attendance-check/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/@modal/(.)attendance-check/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/@modal/(.)attendance-check/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/@modal/default.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/@modal/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/@modal/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/@modal/default.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/AssignmentStatusBox.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/AssignmentStatusBox.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/AssignmentStatusBox.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/AssignmentStatusBox.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/AttendanceStatusBox.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/AttendanceStatusBox.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/AttendanceStatusBox.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/AttendanceStatusBox.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/DailyTaskCarousel.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTaskCarousel.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/DailyTaskCarousel.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTaskCarousel.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTaskItem.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTaskItem.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/DailyTasks.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTasks.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/DailyTasks.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/DailyTasks.tsx
diff --git a/apps/client/app/(afterLogin)/(pc)/my-study/_components/EmptyStudy.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/EmptyStudy.tsx
new file mode 100644
index 00000000..9b41450c
--- /dev/null
+++ b/apps/client/app/(afterLogin)/(pc)/my-study/_components/EmptyStudy.tsx
@@ -0,0 +1,27 @@
+import { Flex } from "@styled-system/jsx";
+import { Text } from "@wow-class/ui";
+import Image from "next/image";
+
+const EmptyStudy = () => {
+ return (
+
+
+
+ 현재 수강 중인 스터디가 없어요
+
+
+ );
+};
+
+export default EmptyStudy;
diff --git a/apps/client/app/(afterLogin)/my-study/_components/Header.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/Header.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/Header.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/Header.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/StudyAnnouncementList.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/StudyAnnouncementList.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/StudyAnnouncementList.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/StudyAnnouncementList.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/_components/StudyCurriculum.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/StudyCurriculum.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/_components/index.ts b/apps/client/app/(afterLogin)/(pc)/my-study/_components/index.ts
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/_components/index.ts
rename to apps/client/app/(afterLogin)/(pc)/my-study/_components/index.ts
diff --git a/apps/client/app/(afterLogin)/my-study/attendance-check/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/attendance-check/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/attendance-check/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/attendance-check/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/default.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/default.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/layout.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/layout.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/layout.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/layout.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/FailurePopover.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/FailurePopover.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/FailurePopover.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/FailurePopover.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/index.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentContent/index.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentDescription.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentDescription.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHeader.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHeader.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHeader.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHeader.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/index.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/index.ts b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/index.ts
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/_components/index.ts
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/_components/index.ts
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/default.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/layout.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/layout.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/my-assignment/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/my-assignment/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/page.tsx b/apps/client/app/(afterLogin)/(pc)/my-study/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-study/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/my-study/page.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/@modal/(.)study-application/[studyId]/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/@modal/(.)study-application/[studyId]/page.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/@modal/default.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/@modal/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/@modal/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/@modal/default.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/_components/EmptyStudyApplication.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/_components/EmptyStudyApplication.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/_components/EmptyStudyApplication.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/_components/EmptyStudyApplication.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/_components/StudyItem.tsx
similarity index 99%
rename from apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/_components/StudyItem.tsx
index 7f39fbf1..fe205104 100644
--- a/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx
+++ b/apps/client/app/(afterLogin)/(pc)/study-apply/_components/StudyItem.tsx
@@ -48,6 +48,7 @@ const StudyItem = ({ study, appliedStudyId }: StudyItemProps) => {
const isApplicable = appliedStudyId === null;
const isCancelable = appliedStudyId === studyId;
const isNotApplicable = !isApplicable && !isCancelable;
+ console.log(appliedStudyId, studyId);
return (
diff --git a/apps/client/app/(afterLogin)/study-apply/_components/index.ts b/apps/client/app/(afterLogin)/(pc)/study-apply/_components/index.ts
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/_components/index.ts
rename to apps/client/app/(afterLogin)/(pc)/study-apply/_components/index.ts
diff --git a/apps/client/app/(afterLogin)/study-apply/default.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/default.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/default.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/default.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/layout.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/layout.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/layout.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/layout.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/page.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/page.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/study-application/[studyId]/page.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/study-application/[studyId]/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/study-application/[studyId]/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/study-application/[studyId]/page.tsx
diff --git a/apps/client/app/(afterLogin)/study-apply/study-cancellation/[studyId]/page.tsx b/apps/client/app/(afterLogin)/(pc)/study-apply/study-cancellation/[studyId]/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/study-apply/study-cancellation/[studyId]/page.tsx
rename to apps/client/app/(afterLogin)/(pc)/study-apply/study-cancellation/[studyId]/page.tsx
diff --git a/apps/client/components/Icon/Alarm.tsx b/apps/client/components/Icon/Alarm.tsx
new file mode 100644
index 00000000..e437851c
--- /dev/null
+++ b/apps/client/components/Icon/Alarm.tsx
@@ -0,0 +1,29 @@
+import { color } from "wowds-tokens";
+
+export const Alarm = ({ selected = false }: { selected?: boolean }) => {
+ return (
+
+ );
+};
diff --git a/apps/client/components/Icon/Calendar.tsx b/apps/client/components/Icon/Calendar.tsx
new file mode 100644
index 00000000..0f38550e
--- /dev/null
+++ b/apps/client/components/Icon/Calendar.tsx
@@ -0,0 +1,46 @@
+import { color } from "wowds-tokens";
+
+export const Calendar = ({ selected = false }: { selected?: boolean }) => {
+ return (
+ <>
+
+ >
+ );
+};
diff --git a/apps/client/components/Icon/Home.tsx b/apps/client/components/Icon/Home.tsx
new file mode 100644
index 00000000..9415c394
--- /dev/null
+++ b/apps/client/components/Icon/Home.tsx
@@ -0,0 +1,30 @@
+import { color } from "wowds-tokens";
+
+export const Home = ({ selected = false }: { selected?: boolean }) => {
+ return (
+
+ );
+};
diff --git a/apps/client/hooks/useAttendanceCheckSearchParams.ts b/apps/client/hooks/useAttendanceCheckSearchParams.ts
index b8d6302e..78004156 100644
--- a/apps/client/hooks/useAttendanceCheckSearchParams.ts
+++ b/apps/client/hooks/useAttendanceCheckSearchParams.ts
@@ -1,3 +1,5 @@
+"use client";
+
import { useSearchParams } from "next/navigation";
const useAttendanceCheckSearchParams = () => {
@@ -7,8 +9,9 @@ const useAttendanceCheckSearchParams = () => {
const studyName = searchParams.get("study-name");
const deadLine = searchParams.get("deadline") || "";
const currentWeek = searchParams.get("week");
+ const mentorName = searchParams.get("mentor");
- return { studyDetailId, studyName, deadLine, currentWeek };
+ return { studyDetailId, studyName, deadLine, currentWeek, mentorName };
};
export default useAttendanceCheckSearchParams;
diff --git a/apps/client/middleware.ts b/apps/client/middleware.ts
index 21eb5885..d59d3d18 100644
--- a/apps/client/middleware.ts
+++ b/apps/client/middleware.ts
@@ -4,20 +4,35 @@ import { routePath } from "constants/routePath";
import { cookies } from "next/headers";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
+import { isMobileUser } from "utils/isMobileUser";
export const config = {
- matcher: ["/my-page/:path*", "/my-study/:path*", "/study-apply/:path*"],
+ matcher: [
+ "/my-page/:path*",
+ "/my-study/:path*",
+ "/study-apply/:path*",
+ "/mobile/:path*",
+ ],
};
const middleware = async (req: NextRequest) => {
const cookieStore = cookies();
const accessToken = cookieStore.get(cookieKey.accessToken)?.value;
const middlewareExecuted = cookieStore.get(cookieKey["middleware-executed"]);
+ const userAgent = req.headers.get("user-agent") || "";
+ const isMobile = isMobileUser(userAgent);
+
+ const url = new URL(req.url);
if (!accessToken) {
return NextResponse.redirect(new URL(routePath.auth, req.url));
}
+ if (isMobile && (url.pathname === "/my-study" || url.pathname === "/auth")) {
+ url.pathname = `/mobile/${url.pathname}`;
+ return NextResponse.redirect(url);
+ }
+
if (!middlewareExecuted) {
const { memberRole } = await dashboardApi.getDashboardInfo();
diff --git a/apps/client/public/images/success.svg b/apps/client/public/images/success.svg
new file mode 100644
index 00000000..b6ebb9d4
--- /dev/null
+++ b/apps/client/public/images/success.svg
@@ -0,0 +1,10 @@
+
diff --git a/apps/client/utils/isMobileUser.ts b/apps/client/utils/isMobileUser.ts
new file mode 100644
index 00000000..14844706
--- /dev/null
+++ b/apps/client/utils/isMobileUser.ts
@@ -0,0 +1,5 @@
+export const isMobileUser = (userAgent: string) => {
+ const mobileRegex =
+ /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
+ return mobileRegex.test(userAgent);
+};