From c88ac973d111b210a0dde5fe7c52ce0efc9d43d0 Mon Sep 17 00:00:00 2001 From: y-r-m Date: Thu, 20 Jul 2023 17:45:37 +0900 Subject: [PATCH 1/6] =?UTF-8?q?Feat:=EA=B0=95=EC=9D=98=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 +++ next-env.d.ts | 5 ++ package.json | 6 ++ src/app/modals/DurationModal.tsx | 65 +++++++++++++++++++ src/app/modals/LinkModal.tsx | 66 ++++++++++++++++++++ src/app/modals/Main.tsx | 21 +++++++ src/app/modals/MakeModal.tsx | 56 +++++++++++++++++ src/app/page.tsx | 10 ++- src/redux/contentSlice.tsx | 18 ++++++ src/redux/store.tsx | 7 ++- src/redux/titleSlice.tsx | 18 ++++++ yarn.lock | 103 ++++++++++++++++++++++++++++++- 12 files changed, 378 insertions(+), 5 deletions(-) create mode 100644 .gitignore create mode 100644 next-env.d.ts create mode 100644 src/app/modals/DurationModal.tsx create mode 100644 src/app/modals/LinkModal.tsx create mode 100644 src/app/modals/Main.tsx create mode 100644 src/app/modals/MakeModal.tsx create mode 100644 src/redux/contentSlice.tsx create mode 100644 src/redux/titleSlice.tsx diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cff9d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +dev +/node_modules +/.pnp +.pnp.js + +/.next/ +/out/ +.env \ No newline at end of file diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/package.json b/package.json index a632864..8c3c062 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,10 @@ "format": "npx prettier . --write --cache" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.4.0", + "@fortawesome/free-regular-svg-icons": "^6.4.0", + "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/react-fontawesome": "^0.2.0", "@reduxjs/toolkit": "^1.9.5", "@tanstack/react-query": "^4.29.25", "@tanstack/react-query-devtools": "^4.29.25", @@ -21,6 +25,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", "d3": "^7.8.5", @@ -31,6 +36,7 @@ "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-hook-form": "^7.45.2", diff --git a/src/app/modals/DurationModal.tsx b/src/app/modals/DurationModal.tsx new file mode 100644 index 0000000..02a177c --- /dev/null +++ b/src/app/modals/DurationModal.tsx @@ -0,0 +1,65 @@ +"use client"; +import React, { useState } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faXmark } from "@fortawesome/free-solid-svg-icons"; +import DatePicker from "react-datepicker"; +import LinkModal from "./LinkModal"; +import { ko } from "date-fns/esm/locale"; + +interface DurationModalProps { + onClose: () => void; +} + +export default function DurationModal({ onClose }: DurationModalProps) { + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date()); + const [openLinkModal, setOpenLinkModal] = useState(false); + + const onModalLinkOpen = () => { + setOpenLinkModal(true); + }; + const onModalLinkClose = () => { + setOpenLinkModal(false); + }; + const handleClose = () => { + onClose(); + onModalLinkOpen(); + }; + return ( +
+
+
+
+ +
+
+

교육과정 > 기간 설정

+
+ setStartDate(date)} + className="w-3/4" + /> + ~ + setEndDate(date)} + className="w-3/4" + /> +
+
+ +
+
+ {openLinkModal && } +
+ ); +} diff --git a/src/app/modals/LinkModal.tsx b/src/app/modals/LinkModal.tsx new file mode 100644 index 0000000..85ead70 --- /dev/null +++ b/src/app/modals/LinkModal.tsx @@ -0,0 +1,66 @@ +"use client"; +import React, { useState } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faXmark } from "@fortawesome/free-solid-svg-icons"; +import DurationModal from "./DurationModal"; +import { useSelector } from "react-redux"; +import { setInputContent } from "@/redux/contentSlice"; +import { useDispatch } from "react-redux"; + +interface LinkModalProps { + onClose: () => void; +} + +export default function LinkModal({ onClose }: LinkModalProps) { + const [openDurationModal, setOpenDurationModal] = useState(false); + const inputValue = useSelector((state: any) => state.title); + const [inputContent, setInputContentLocal] = useState(""); + const dispatch = useDispatch(); + + const onDurationModalOpen = () => { + dispatch(setInputContent(inputContent)); + setOpenDurationModal(true); + }; + const handleInputChange = (e: any) => { + setInputContentLocal(e.target.value); + }; + return ( +
+
+
+
+ +
+
+

교육과정 > 링크 만들기

+
+
+ +
+ +
+
+ +
+
+ {openDurationModal && } +
+ ); +} diff --git a/src/app/modals/Main.tsx b/src/app/modals/Main.tsx new file mode 100644 index 0000000..f0d9c6c --- /dev/null +++ b/src/app/modals/Main.tsx @@ -0,0 +1,21 @@ +"use client"; +import React, { useState } from "react"; +import MakeModal from "./MakeModal"; + +export default function Main() { + const [openModal, setOpenModal] = useState(false); + const onModalOpen = () => { + setOpenModal(!openModal); + }; + return ( +
+ {openModal && } + +
+ ); +} diff --git a/src/app/modals/MakeModal.tsx b/src/app/modals/MakeModal.tsx new file mode 100644 index 0000000..95fed41 --- /dev/null +++ b/src/app/modals/MakeModal.tsx @@ -0,0 +1,56 @@ +"use client"; +import React, { useState } from "react"; +import LinkModal from "./LinkModal"; +import { useDispatch } from "react-redux"; +import { setInputTitle } from "@/redux/titleSlice"; + +export default function MakeModal({ onOpenModal }: any) { + const [openLinkModal, setOpenLinkModal] = useState(false); + const [inputTitle, setInputTitleLocal] = useState(""); + const dispatch = useDispatch(); + + const onLinkModalOpen = () => { + dispatch(setInputTitle(inputTitle)); + setOpenLinkModal(true); + }; + const onLinkModalClose = () => { + setOpenLinkModal(false); + }; + const handleInputChange = (e: any) => { + setInputTitleLocal(e.target.value); + }; + return ( +
+
+
+

강의 만들기

+ +
+
+
+ 노트 만들기 +
+
+ 영상 강의 만들기 +
+
+ 링크 만들기 +
+
+ +
+ {openLinkModal && } +
+ ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 5c1883b..b8e317b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,13 @@ import { LOGOUT } from "@/constants/a"; +import Main from "./modals/Main"; export default function Home() { - return
{LOGOUT}11
; + return ( +
+ {LOGOUT}11 +
+
+
+
+ ); } diff --git a/src/redux/contentSlice.tsx b/src/redux/contentSlice.tsx new file mode 100644 index 0000000..2afde38 --- /dev/null +++ b/src/redux/contentSlice.tsx @@ -0,0 +1,18 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + inputValue: "", +}; + +const contentSlice = createSlice({ + name: "content", + initialState, + reducers: { + setInputContent: (state, action) => { + return action.payload; + }, + }, +}); + +export const { setInputContent } = contentSlice.actions; +export default contentSlice.reducer; diff --git a/src/redux/store.tsx b/src/redux/store.tsx index 7d38ceb..b3c0a51 100644 --- a/src/redux/store.tsx +++ b/src/redux/store.tsx @@ -1,7 +1,12 @@ import { configureStore } from "@reduxjs/toolkit"; +import titleReducer from "./titleSlice"; +import contentReducer from "./contentSlice"; export const store = configureStore({ - reducer: {}, + reducer: { + title: titleReducer, + content: contentReducer, + }, devTools: process.env.NODE_ENV !== "production", }); diff --git a/src/redux/titleSlice.tsx b/src/redux/titleSlice.tsx new file mode 100644 index 0000000..b4d6463 --- /dev/null +++ b/src/redux/titleSlice.tsx @@ -0,0 +1,18 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + inputTitle: "", +}; + +const titleSlice = createSlice({ + name: "title", + initialState, + reducers: { + setInputTitle: (state, action) => { + return action.payload; + }, + }, +}); + +export const { setInputTitle } = titleSlice.actions; +export default titleSlice.reducer; diff --git a/yarn.lock b/yarn.lock index 45b1c1a..ec01e9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -272,7 +272,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.9.2": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== @@ -723,6 +723,39 @@ resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.1.tgz#60bb2aaf129f9e00621f8d698722ddba6ee1f8ac" integrity sha512-Dq5rYfEpdeel0bLVN+nfD1VWmzCkK+pJbSjIawGE+RY4+NIJqhbUDDQjvV0NUK84fMfwxvtFoCtEe70HfZjFcw== +"@fortawesome/fontawesome-common-types@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz#88da2b70d6ca18aaa6ed3687832e11f39e80624b" + integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ== + +"@fortawesome/fontawesome-svg-core@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz#3727552eff9179506e9203d72feb5b1063c11a21" + integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/free-regular-svg-icons@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz#cacc53bd8d832d46feead412d9ea9ce80a55e13a" + integrity sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/free-solid-svg-icons@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz#48c0e790847fa56299e2f26b82b39663b8ad7119" + integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/react-fontawesome@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" + integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== + dependencies: + prop-types "^15.8.1" + "@grpc/grpc-js@~1.7.0": version "1.7.3" resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.7.3.tgz#f2ea79f65e31622d7f86d4b4c9ae38f13ccab99a" @@ -1107,6 +1140,11 @@ picocolors "^1.0.0" tslib "^2.6.0" +"@popperjs/core@^2.11.8", "@popperjs/core@^2.9.2": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1629,6 +1667,16 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/react-datepicker@^4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@types/react-datepicker/-/react-datepicker-4.11.2.tgz#44abfc6379faa58d28eb5730a058d6a389d40eac" + integrity sha512-ELYyX3lb3K1WltqdlF1hbnaDGgzlF6PIR5T4W38cSEcfrQDIrPE+Ioq5pwRe/KEJ+ihHMjvTVZQkwJx0pWMNHQ== + dependencies: + "@popperjs/core" "^2.9.2" + "@types/react" "*" + date-fns "^2.0.1" + react-popper "^2.2.5" + "@types/react-dom@18.2.7", "@types/react-dom@^18.0.0": version "18.2.7" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" @@ -2266,6 +2314,11 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== +classnames@^2.2.6: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + client-only@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" @@ -2661,6 +2714,13 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +date-fns@^2.0.1, date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -4601,7 +4661,7 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5144,7 +5204,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.8.1: +prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -5215,6 +5275,18 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +react-datepicker@^4.16.0: + version "4.16.0" + resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.16.0.tgz#b9dd389bb5611a1acc514bba1dd944be21dd877f" + integrity sha512-hNQ0PAg/LQoVbDUO/RWAdm/RYmPhN3cz7LuQ3hqbs24OSp69QCiKOJRrQ4jk1gv1jNR5oYu8SjjgfDh8q6Q1yw== + dependencies: + "@popperjs/core" "^2.11.8" + classnames "^2.2.6" + date-fns "^2.30.0" + prop-types "^15.7.2" + react-onclickoutside "^6.12.2" + react-popper "^2.3.0" + react-dnd@^16.0.1: version "16.0.1" resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-16.0.1.tgz#2442a3ec67892c60d40a1559eef45498ba26fa37" @@ -5234,6 +5306,11 @@ react-dom@18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-fast-compare@^3.0.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + react-hook-form@^7.45.2: version "7.45.2" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.2.tgz#c757f3d5e633ccb186443d57c10fc511df35721a" @@ -5254,6 +5331,19 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-onclickoutside@^6.12.2: + version "6.13.0" + resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz#e165ea4e5157f3da94f4376a3ab3e22a565f4ffc" + integrity sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A== + +react-popper@^2.2.5, react-popper@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" + integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== + dependencies: + react-fast-compare "^3.0.1" + warning "^4.0.2" + react-redux@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.1.tgz#8e740f3fd864a4cd0de5ba9cdc8ad39cc9e7c81a" @@ -6007,6 +6097,13 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" +warning@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + watchpack@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" From 4625e30ca63e7f52f2f67a44afc6efd5143c34cd Mon Sep 17 00:00:00 2001 From: y-r-m Date: Sun, 23 Jul 2023 22:13:56 +0900 Subject: [PATCH 2/6] =?UTF-8?q?Docs:=20svg=EC=9A=94=EC=86=8C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/calendar_toggle.svg | 3 +++ public/link.svg | 9 +++++++++ public/next_mark.svg | 3 +++ public/note.svg | 9 +++++++++ public/right_arrow.svg | 5 +++++ public/video.svg | 9 +++++++++ 6 files changed, 38 insertions(+) create mode 100644 public/calendar_toggle.svg create mode 100644 public/link.svg create mode 100644 public/next_mark.svg create mode 100644 public/note.svg create mode 100644 public/right_arrow.svg create mode 100644 public/video.svg diff --git a/public/calendar_toggle.svg b/public/calendar_toggle.svg new file mode 100644 index 0000000..b73fa0e --- /dev/null +++ b/public/calendar_toggle.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/link.svg b/public/link.svg new file mode 100644 index 0000000..9e51cc6 --- /dev/null +++ b/public/link.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/next_mark.svg b/public/next_mark.svg new file mode 100644 index 0000000..3e2576b --- /dev/null +++ b/public/next_mark.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/note.svg b/public/note.svg new file mode 100644 index 0000000..88fe678 --- /dev/null +++ b/public/note.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/right_arrow.svg b/public/right_arrow.svg new file mode 100644 index 0000000..cfc824c --- /dev/null +++ b/public/right_arrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/video.svg b/public/video.svg new file mode 100644 index 0000000..e56ac42 --- /dev/null +++ b/public/video.svg @@ -0,0 +1,9 @@ + + + + + + + + + From 7d21b83d07ecbb5481637bc5768c2cee3708656f Mon Sep 17 00:00:00 2001 From: sweeeeetpotato Date: Mon, 24 Jul 2023 14:30:38 +0900 Subject: [PATCH 3/6] =?UTF-8?q?Feat:=20=EA=B0=95=EC=9D=98=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=AA=A8=EB=8B=AC=EC=9D=98=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=EC=A0=81=EC=9D=B8=20=EC=98=81=EC=97=AD=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/right-arrow.svg | 3 +++ src/components/modal/Layout.tsx | 8 +++--- src/components/modal/lecture/LectureTitle.tsx | 15 +++++++++++ .../modal/lecture/ModalSubmitButton.tsx | 26 +++++++++++++++++++ src/components/modal/lecture/ModalTtile.tsx | 24 +++++++++++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 public/images/right-arrow.svg create mode 100644 src/components/modal/lecture/LectureTitle.tsx create mode 100644 src/components/modal/lecture/ModalSubmitButton.tsx create mode 100644 src/components/modal/lecture/ModalTtile.tsx diff --git a/public/images/right-arrow.svg b/public/images/right-arrow.svg new file mode 100644 index 0000000..6a6818a --- /dev/null +++ b/public/images/right-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/modal/Layout.tsx b/src/components/modal/Layout.tsx index 51a86ce..decf318 100644 --- a/src/components/modal/Layout.tsx +++ b/src/components/modal/Layout.tsx @@ -9,21 +9,21 @@ interface ModalProps { const Layout: React.FC = ({ handleBtn, children }) => { return (
e.stopPropagation()} > {children} diff --git a/src/components/modal/lecture/LectureTitle.tsx b/src/components/modal/lecture/LectureTitle.tsx new file mode 100644 index 0000000..abff54e --- /dev/null +++ b/src/components/modal/lecture/LectureTitle.tsx @@ -0,0 +1,15 @@ +const LectureTitle: React.FC = () => { + return ( + + ); +}; + +export default LectureTitle; diff --git a/src/components/modal/lecture/ModalSubmitButton.tsx b/src/components/modal/lecture/ModalSubmitButton.tsx new file mode 100644 index 0000000..cdcb5f0 --- /dev/null +++ b/src/components/modal/lecture/ModalSubmitButton.tsx @@ -0,0 +1,26 @@ +interface ModalSubmitButtonProps { + handleCloseModal: () => void; + contents: string; +} + +export const ModalSubmitButton: React.FC = ({ + handleCloseModal, + contents, +}) => { + const handleSubmitBtn = () => { + // 이 위치에 다음 모달로 넘기는 코드 추가 예정 + handleCloseModal; + }; + + return ( +
+ +
+ ); +}; diff --git a/src/components/modal/lecture/ModalTtile.tsx b/src/components/modal/lecture/ModalTtile.tsx new file mode 100644 index 0000000..f32bd42 --- /dev/null +++ b/src/components/modal/lecture/ModalTtile.tsx @@ -0,0 +1,24 @@ +interface ModalTtileProps { + modalTitle: string[]; +} + +const ModalTtile: React.FC = ({ modalTitle }) => { + return ( +

+ {modalTitle.map((val, idx) => + idx === 0 ? ( + {val} + ) : ( + + {val} + + ), + )} +

+ ); +}; + +export default ModalTtile; From 5105aecd26a37b341eba19c867a7b9649373307a Mon Sep 17 00:00:00 2001 From: y-r-m <109524400+y-r-m@users.noreply.github.com> Date: Wed, 26 Jul 2023 15:45:25 +0900 Subject: [PATCH 4/6] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index c8bfecf..3cc02a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ dev -/.next/ -/out/ node_modules .next .env From a5dc058030e594d41aff6bce4a770d8b0edc8808 Mon Sep 17 00:00:00 2001 From: y-r-m <109524400+y-r-m@users.noreply.github.com> Date: Wed, 26 Jul 2023 16:07:52 +0900 Subject: [PATCH 5/6] Update package.json --- package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package.json b/package.json index 9a07a71..34634a8 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,6 @@ "format": "npx prettier . --write --cache" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.4.0", - "@fortawesome/free-regular-svg-icons": "^6.4.0", - "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@fortawesome/react-fontawesome": "^0.2.0", "@reduxjs/toolkit": "^1.9.5", "@tanstack/react-query": "^4.29.25", "@tanstack/react-query-devtools": "^4.29.25", From 5fa7b628bef4e8b9ca6242196431b759880e410d Mon Sep 17 00:00:00 2001 From: y-r-m Date: Wed, 26 Jul 2023 16:53:51 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Update:=20=EA=B0=95=EC=9D=98=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0=20=EB=AA=A8=EB=8B=AC=EC=B0=BD/=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EB=A7=8C=EB=93=A4=EA=B8=B0/=EC=84=B8=EB=B6=80=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/.eslintrc.js | 9 ++-- functions/src/apis/lecture/comments.ts | 4 +- functions/src/apis/lecture/lecture.ts | 9 ++-- src/app/classroom/[lectureId]/page.tsx | 12 +++-- src/app/layout.tsx | 2 +- src/components/classroom/Aside.tsx | 17 +++--- src/components/classroom/ContentCard.tsx | 22 +++++--- src/components/classroom/MOCK_DATA.ts | 30 +++++------ src/components/index.tsx | 52 ++++++++++++------- src/components/lecture/LectureComment.tsx | 6 ++- src/components/lecture/LectureHeader.tsx | 8 +-- src/components/lecture/LectureNavigation.tsx | 2 +- .../lecture/typesOf/LinkLecture.tsx | 2 +- .../lecture/typesOf/NoteLecture.tsx | 6 +-- .../lecture/typesOf/VideoLecture.tsx | 4 +- src/components/modal/comment/CommentForm.tsx | 8 ++- src/hooks/useFetchLecture.ts | 14 +++-- src/hooks/useLectureComment.ts | 6 ++- src/hooks/useRenderAsideButton.tsx | 26 ++++++---- src/types/firebase.Types.ts | 2 +- src/utils/teamSixFirebase.ts | 4 +- 21 files changed, 144 insertions(+), 101 deletions(-) diff --git a/functions/.eslintrc.js b/functions/.eslintrc.js index b16341a..1d24ceb 100644 --- a/functions/.eslintrc.js +++ b/functions/.eslintrc.js @@ -20,13 +20,10 @@ module.exports = { ignorePatterns: [ "/lib/**/*", // Ignore built files. ], - plugins: [ - "@typescript-eslint", - "import", - ], + plugins: ["@typescript-eslint", "import"], rules: { - "quotes": ["error", "double"], + quotes: ["error", "double"], "import/no-unresolved": 0, - "indent": ["error", 2], + indent: ["error", 2], }, }; diff --git a/functions/src/apis/lecture/comments.ts b/functions/src/apis/lecture/comments.ts index f1c04e6..0f875bc 100644 --- a/functions/src/apis/lecture/comments.ts +++ b/functions/src/apis/lecture/comments.ts @@ -2,7 +2,7 @@ import * as functions from "firebase-functions"; import * as admin from "firebase-admin"; import * as cors from "cors"; -const corsHandler = cors({origin: true}); +const corsHandler = cors({ origin: true }); export const getComments = functions.https.onRequest((request, response) => { corsHandler(request, response, async () => { @@ -18,7 +18,7 @@ export const getComments = functions.https.onRequest((request, response) => { response.send([]); return; } - const comments = commentsSnap.docs.map((doc) => { + const comments = commentsSnap.docs.map(doc => { const data = doc.data(); data.createdAt = new Date(data.createdAt._seconds * 1000); data.updatedAt = new Date(data.updatedAt._seconds * 1000); diff --git a/functions/src/apis/lecture/lecture.ts b/functions/src/apis/lecture/lecture.ts index 7b4a378..8e9a10f 100644 --- a/functions/src/apis/lecture/lecture.ts +++ b/functions/src/apis/lecture/lecture.ts @@ -4,16 +4,13 @@ import * as cors from "cors"; admin.initializeApp(); -const corsHandler = cors({origin: true}); +const corsHandler = cors({ origin: true }); export const getLecture = functions.https.onRequest((request, response) => { corsHandler(request, response, async () => { const lectureId = request.query.lectureId as string; try { - const lectureRef = admin - .firestore() - .collection("lecture") - .doc(lectureId); + const lectureRef = admin.firestore().collection("lecture").doc(lectureId); const lectureDoc = await lectureRef.get(); if (!lectureDoc.exists) { console.log(`No document exists for lectureId: ${lectureId}`); @@ -26,7 +23,7 @@ export const getLecture = functions.https.onRequest((request, response) => { const videoLink = lectureData?.lectureContent.videoLink; const startDate = new Date(lectureData?.startDate._seconds * 1000); const endDate = new Date(lectureData?.endDate._seconds * 1000); - response.send({title, lectureType, videoLink, startDate, endDate}); + response.send({ title, lectureType, videoLink, startDate, endDate }); } catch (error) { response.status(500).send("DB 에러"); } diff --git a/src/app/classroom/[lectureId]/page.tsx b/src/app/classroom/[lectureId]/page.tsx index ded6759..6404396 100644 --- a/src/app/classroom/[lectureId]/page.tsx +++ b/src/app/classroom/[lectureId]/page.tsx @@ -14,13 +14,19 @@ const LectureHome: FC = () => { if (loading) return
Loading...
; if (error) return
Error: {error}
; - + return (
- +
- {data && } + {data && ( + + )}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e91bd79..7e08d0a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -20,7 +20,7 @@ export default function RootLayout({ {children} - + ); diff --git a/src/components/classroom/Aside.tsx b/src/components/classroom/Aside.tsx index 2ca3799..1aee180 100644 --- a/src/components/classroom/Aside.tsx +++ b/src/components/classroom/Aside.tsx @@ -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 ( - ) -} + ); +}; -export default Aside \ No newline at end of file +export default Aside; diff --git a/src/components/classroom/ContentCard.tsx b/src/components/classroom/ContentCard.tsx index b49b6b7..d87bbcc 100644 --- a/src/components/classroom/ContentCard.tsx +++ b/src/components/classroom/ContentCard.tsx @@ -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 (
-
img section
+
+ img section +
수정|삭제
-
{props.RUN_TIME}
+
+ {props.RUN_TIME} +
{props.TITLE}
[수강기간]
{props.CLASS_DATE}
- +
- ) -} + ); +}; -export default ContentCard \ No newline at end of file +export default ContentCard; diff --git a/src/components/classroom/MOCK_DATA.ts b/src/components/classroom/MOCK_DATA.ts index 87b8297..9fa9a68 100644 --- a/src/components/classroom/MOCK_DATA.ts +++ b/src/components/classroom/MOCK_DATA.ts @@ -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' - } -] \ No newline at end of file + RUN_TIME: "15", + TITLE: "[DAY3] 백엔드 라이브러이", + CLASS_DATE: "2023.05.04~2023.12.27", + }, +]; diff --git a/src/components/index.tsx b/src/components/index.tsx index 9fde10f..398f2b5 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -1,35 +1,38 @@ -'use client' -import React, { useState, ChangeEvent, useEffect, useRef } from 'react'; +"use client"; +import React, { useState, ChangeEvent, useEffect, useRef } from "react"; const ImageUploadModal: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const modalRef = useRef(null); const [selectedImages, setSelectedImages] = useState([]); const [imagePreviews, setImagePreviews] = useState([]); - const [title, setTitle] = useState(''); - const [content, setContent] = useState(''); + const [title, setTitle] = useState(""); + const [content, setContent] = useState(""); const openModal = () => { setIsOpen(true); }; const closeModal = () => { - setTitle('') - setContent('') - setSelectedImages([]) + setTitle(""); + setContent(""); + setSelectedImages([]); setIsOpen(false); }; useEffect(() => { const handleOutsideClick = (event: MouseEvent) => { - if (modalRef.current && !modalRef.current.contains(event.target as Node)) { + if ( + modalRef.current && + !modalRef.current.contains(event.target as Node) + ) { closeModal(); } }; - document.addEventListener('mousedown', handleOutsideClick); + document.addEventListener("mousedown", handleOutsideClick); return () => { - document.removeEventListener('mousedown', handleOutsideClick); + document.removeEventListener("mousedown", handleOutsideClick); }; }, []); @@ -37,7 +40,7 @@ const ImageUploadModal: React.FC = () => { const files = Array.from(event.target.files || []); setSelectedImages(files); - const previewUrls = files.map((file) => URL.createObjectURL(file)); + const previewUrls = files.map(file => URL.createObjectURL(file)); setImagePreviews(previewUrls); }; @@ -53,36 +56,47 @@ const ImageUploadModal: React.FC = () => { const handleUpload = () => { console.log(selectedImages, title, content); - setTitle('') - setContent('') - setSelectedImages([]) + setTitle(""); + setContent(""); + setSelectedImages([]); closeModal(); }; return (
- {isOpen && (
-
+
강의 만들기 - 노트 만들기
- +
setTitle(e.target.value)} + onChange={e => setTitle(e.target.value)} />