Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@types/d3": "^7.4.0",
"@types/node": "20.4.2",
"@types/react": "18.2.15",
"@types/react-datepicker": "^4.11.2",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.14",
"cors": "^2.8.5",
Expand All @@ -36,10 +37,12 @@
"next": "13.4.10",
"postcss": "8.4.26",
"react": "18.2.0",
"react-datepicker": "^4.16.0",
"react-dnd": "^16.0.1",
"react-dom": "18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.45.2",
"react-intl": "^6.4.4",
"react-redux": "^8.1.1",
"tailwindcss": "3.3.3",
"typescript": "5.1.6"
Expand Down
3 changes: 3 additions & 0 deletions public/calenda-toggle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/right-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/next-mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/note.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/right-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/video.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const fetchClient = async (
endpoint: string,
options?: RequestInit,
): Promise<any> => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}${endpoint}`,
options,
);
return response.json();
};
Empty file added src/api/lecture.ts
Empty file.
5 changes: 4 additions & 1 deletion src/app/classroom/[lectureId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ const LectureHome: FC<lectureIdProps> = ({ lectureId }) => {
<LectureHeader />
<div className="mainContainer flex w-full h-screen">
<div className="Container flex flex-col w-3/4">
<TypeOfLecture type={data.lectureType} content={data.lectureContent} />
<TypeOfLecture
type={data.lectureType}
content={data.lectureContent}
/>
<LectureFooter />
</div>
<LectureComment />
Expand Down
47 changes: 47 additions & 0 deletions src/app/classroom/message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createIntl, createIntlCache, IntlShape } from "react-intl";

// 언어별 메시지 정의
interface Messages {
[key: string]: {
calendar: {
monthNames: string;
dayNames: string;
};
// 다른 언어 메시지 정의도 추가할 수 있습니다.
};
}

const messages: Messages = {
en: {
calendar: {
monthNames: `January, February, March, April, May, June, July, August, September, October, November, December`,
dayNames: `Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday`,
},
// 영어 메시지들을 정의합니다.
},
ko: {
calendar: {
monthNames:
"1월, 2월, 3월, 4월, 5월, 6월, 7월, 8월, 9월, 10월, 11월, 12월",
dayNames: "일, 월, 화, 수, 목, 금, 토",
},
// 한국어 메시지들을 정의합니다.
},
// 다른 언어의 메시지들도 정의합니다.
};

// 언어 설정과 캐시 생성
const cache = createIntlCache();
const defaultLocale = "ko";
const defaultMessages = messages[defaultLocale];
const defaultIntl: IntlShape = createIntl(
{
locale: defaultLocale,
messages: {
...defaultMessages.calendar,
},
},
cache,
);

export { defaultIntl, messages };
19 changes: 9 additions & 10 deletions src/app/classroom/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
'use client'
import Aside from "@/components/classroom/Aside"
import ClassContent from "@/components/classroom/ClassContent"
"use client";

import Aside from "@/components/classroom/Aside";
import ClassContent from "@/components/classroom/ClassContent";

const Classroom = () => {

return (
<div className="w-screen h-screen flex justify-center">
<section className="w-4/5 h-screen flex">
<Aside/>
<ClassContent/>
<Aside />
<ClassContent />
</section>
</div>
)
}

export default Classroom
);
};

export default Classroom;
1 change: 1 addition & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default function RootLayout({
<html lang="en">
<body className={inter.className}>
<Provider>{children}</Provider>
<ImageUpload />
</body>
</html>
);
Expand Down
17 changes: 10 additions & 7 deletions src/components/classroom/Aside.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import useRenderAsideButton from "@/hooks/useRenderAsideButton"
import { useState } from "react"
import useRenderAsideButton from "@/hooks/useRenderAsideButton";
import { useState } from "react";

const Aside = () => {
const {renderAsideButton, contentCardList} = useRenderAsideButton()
const { renderAsideButton, contentCardList } = useRenderAsideButton();
return (
<aside className="w-1/5 h-100 flex items-center flex-col mr-[20px] pt-[100px]">
{contentCardList.map((e, idx) => (
<div key={e} className="rounded w-[245px] h-[46px] bg-primary-5 flex justify-center items-center mb-[15px]">
<div
key={e}
className="rounded w-[245px] h-[46px] bg-primary-5 flex justify-center items-center mb-[15px]"
>
{e}
</div>
))}
{renderAsideButton("add")}
{renderAsideButton("edit")}
</aside>
)
}
);
};

export default Aside
export default Aside;
60 changes: 45 additions & 15 deletions src/components/classroom/ClassContent.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
import ContentCard from "./ContentCard"
import { MOCK_DATA } from "./MOCK_DATA"
import { IContent } from "./MOCK_DATA"
import ContentCard from "./ContentCard";
import { MOCK_DATA } from "./MOCK_DATA";
import { IContent } from "./MOCK_DATA";
import MakeModal from "../classroomModal/MakeLectureModal";
import LinkModal from "../classroomModal/AddLinkModal";
import DurationModal from "../classroomModal/LectureDurationModal";
import useClassroomModal from "@/hooks/useClassroomModal";
import { useDispatch } from "react-redux";
import { setModalVisibility } from "@/redux/slice/classroomModalSlice";
const ClassContent = () => {
const dispatch = useDispatch();
const {
lectureTypeModalOpen,
noteModalOpen,
linkModalOpen,
videoFileModalOpen,
lectureDurationModalOpen,
commentModalOpen,
replyCommentModalOpen,
} = useClassroomModal();

const handleModalOpen = () => {
dispatch(
setModalVisibility({ modalName: "lectureTypeModalOpen", visible: true }),
);
};
return (
<div className="w-4/5 h-100 pt-[100px] ml-[50px]">
<div className="flex justify-between w-100">
<div className="flex flex-col w-[150px] mb-[20px]">
<div className="text-lg font-bold">[DAY1] IT기본</div>
<div className="font-thin text-sm">강의 1개</div>
</div>
<button className="w-[109px] h-[35px] bg-primary-80 rounded-lg text-white text-sm">강의 만들기</button>
<div className="flex justify-between w-100">
<div className="flex flex-col w-[150px] mb-[20px]">
<div className="text-lg font-bold">[DAY1] IT기본</div>
<div className="font-thin text-sm">강의 1개</div>
</div>
{MOCK_DATA.map((e:IContent) => (
<ContentCard key={e.TITLE} props={e}/>
))}
<button
onClick={handleModalOpen}
className="w-[109px] h-[35px] bg-primary-80 rounded-lg text-white text-sm"
>
강의 만들기
</button>
</div>
{MOCK_DATA.map((e: IContent) => (
<ContentCard key={e.TITLE} props={e} />
))}
{lectureTypeModalOpen && <MakeModal />}
{linkModalOpen && <LinkModal />}
{lectureDurationModalOpen && <DurationModal />}
</div>
)
}
);
};

export default ClassContent
export default ClassContent;
22 changes: 14 additions & 8 deletions src/components/classroom/ContentCard.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { IContent } from "./MOCK_DATA"
import { IContent } from "./MOCK_DATA";

const ContentCard = ({props}:{props:IContent}) => {
const ContentCard = ({ props }: { props: IContent }) => {
return (
<div className="w-[775px] h-[200px] border rounded-lg p-[10px] flex flex-row items-center mb-[15px]">
<div className="w-1/3 h-5/6 bg-primary-40 rounded-lg mr-[10px]">img section</div>
<div className="w-1/3 h-5/6 bg-primary-40 rounded-lg mr-[10px]">
img section
</div>
<div className="w-2/3 h-5/6 ml-20px flex flex-col">
<div className="text-xs ml-auto">수정|삭제</div>
<div className="bg-grayscale-5 rounded w-[40px] h-[20px] text-xs text-center leading-[20px] mb-[10px]">{props.RUN_TIME}</div>
<div className="bg-grayscale-5 rounded w-[40px] h-[20px] text-xs text-center leading-[20px] mb-[10px]">
{props.RUN_TIME}
</div>
<div className="font-bold mb-[10px]">{props.TITLE}</div>
<div className="flex flex-row justify-between">
<div className="flex flex-col">
<div className="text-xs">[수강기간]</div>
<div className="text-xs">{props.CLASS_DATE}</div>
</div>
<button className="w-[140px] h-[35px] bg-grayscale-5 text-center leading-[35px] text-sm rounded-lg">수강하기</button>
<button className="w-[140px] h-[35px] bg-grayscale-5 text-center leading-[35px] text-sm rounded-lg">
수강하기
</button>
</div>
</div>
</div>
)
}
);
};

export default ContentCard
export default ContentCard;
30 changes: 15 additions & 15 deletions src/components/classroom/MOCK_DATA.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// 임시로 component 폴더에 놨습니다.

export interface IContent {
RUN_TIME : string;
TITLE : string;
CLASS_DATE : string
RUN_TIME: string;
TITLE: string;
CLASS_DATE: string;
}

export const MOCK_DATA:IContent[] = [
export const MOCK_DATA: IContent[] = [
{
RUN_TIME : '7',
TITLE : '[DAY1] 프론트엔드와 백엔드',
CLASS_DATE : '2023.03.03~2023.12.12'
RUN_TIME: "7",
TITLE: "[DAY1] 프론트엔드와 백엔드",
CLASS_DATE: "2023.03.03~2023.12.12",
},
{
RUN_TIME : '10',
TITLE : '[DAY2] 프론트엔드 라이브러이',
CLASS_DATE : '2023.04.06~2023.12.25'
RUN_TIME: "10",
TITLE: "[DAY2] 프론트엔드 라이브러이",
CLASS_DATE: "2023.04.06~2023.12.25",
},
{
RUN_TIME : '15',
TITLE : '[DAY3] 백엔드 라이브러이',
CLASS_DATE : '2023.05.04~2023.12.27'
}
]
RUN_TIME: "15",
TITLE: "[DAY3] 백엔드 라이브러이",
CLASS_DATE: "2023.05.04~2023.12.27",
},
];
68 changes: 68 additions & 0 deletions src/components/classroomModal/AddLinkModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useSelector, useDispatch } from "react-redux";
import { setInputContent } from "@/redux/contentSlice";
import { setInputTitle } from "@/redux/titleSlice";
import Layout from "./common/Layout";
//import { ModalSubmitButton } from "./common/ModalSubmitButton";
import useClassroomModal from "@/hooks/useClassroomModal";

const LinkModal: React.FC = ({}) => {
const inputTitle = useSelector((state: any) => state.title.inputTitle);
const inputContent = useSelector((state: any) => state.content.inputContent);
const dispatch = useDispatch();

const { handleModalMove } = useClassroomModal();

const handleInputTitle = (e: React.ChangeEvent<HTMLInputElement>) => {
dispatch(setInputTitle(e.target.value));
};
const handleInputContent = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
dispatch(
setInputContent(value.startsWith("http://") ? value : "http://" + value),
);
};
return (
<Layout>
<div className="text-left">
<button className="text-xl font-bold text-grayscale-100">
강의 만들기
</button>
<span className="relative text-xl font-bold text-grayscale-100 pl-[17px] before:absolute before:top-[9px] before:left-0 before:w-[7px] before:h-[11px] before:bg-[url('/images/right-arrow.svg')]">
링크 만들기
</span>
<div className="flex items-center py-[20px]">
<input
type="text"
name="title"
placeholder="제목을 입력해주세요.(선택)"
className="justify-left text-[20px]"
value={inputTitle}
onChange={handleInputTitle}
/>
</div>
<input
type="text"
name="link"
placeholder="http://..."
className="justify-center text-[16px] w-[707px] h-[42px] flex-shrink-0 border-[1px] border-gray-300 bg-white rounded-md pl-[14px]"
value={inputContent}
onChange={handleInputContent}
/>
<button
onClick={() =>
handleModalMove("lectureDurationModalOpen", "linkModalOpen")
}
className="rounded-md py-[15.5] px-[18.3] ml-[599px] mt-[20px] text-white bg-blue-500 w-[107px] h-[45px] "
>
다음
</button>
{/* <ModalSubmitButton
handleCloseModal={onDurationModalOpen}
contents="다음"
/> */}
</div>
</Layout>
);
};

export default LinkModal;
Loading