From 36cc98b1628a92bc7e7794c3fe2bc527ec556a4e Mon Sep 17 00:00:00 2001 From: Ki Tae Park Date: Sun, 22 Nov 2020 23:48:17 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=A7=88=EB=AC=B8=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=EC=B6=94=EA=B0=80=20(#66)=20TODO?= =?UTF-8?q?=20=20-=20redux=20dispatch=20=EB=B9=84=EB=8F=99=EA=B8=B0?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=20-=20input=20bar=20conflict=EC=9E=A1?= =?UTF-8?q?=EA=B8=B0=20=20-=20=EC=A7=88=EB=AC=B8=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=82=AD=EC=A0=9C=20=20-=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=20-=20=EC=9D=B4=EB=8F=99=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=88=9C=EC=84=9C=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Icon/Icon.js | 5 +- src/components/InputBar/InputBar.js | 4 +- src/components/Modal/Modal.js | 10 +- src/components/Modal/Modal.stories.js | 56 ++++++++ .../Modal/ModalWrapper/ModalWrapper.js | 68 ++++++++++ src/components/Modal/ModalWrapper/index.js | 1 + .../QuestionListSaveModal.js | 125 ++++++++---------- .../SelfTrainStartModal.js | 76 +++++++++++ .../Modal/SelfTrainStartModal/index.js | 1 + .../Question/QuestionItem/QuestionItem.js | 10 +- .../Question/QuestionList/QuestionList.js | 18 +++ src/context/serverContext.js | 2 +- .../IsQuestionList/IsQuestionList.js | 2 + .../QuestionListPage/QuestionListPage.js | 2 - src/pages/QuestionPage/QuestionPage.js | 62 ++++++--- src/repository/questionListRepository.js | 12 ++ src/store/Modal/modal.js | 1 + src/store/Question/question.js | 31 +++++ src/store/index.js | 2 + src/utils/constant.js | 1 + 20 files changed, 391 insertions(+), 98 deletions(-) create mode 100644 src/components/Modal/Modal.stories.js create mode 100644 src/components/Modal/ModalWrapper/ModalWrapper.js create mode 100644 src/components/Modal/ModalWrapper/index.js create mode 100644 src/components/Modal/SelfTrainStartModal/SelfTrainStartModal.js create mode 100644 src/components/Modal/SelfTrainStartModal/index.js create mode 100644 src/store/Question/question.js diff --git a/src/components/Icon/Icon.js b/src/components/Icon/Icon.js index 35988a4..7e3c5b2 100644 --- a/src/components/Icon/Icon.js +++ b/src/components/Icon/Icon.js @@ -98,7 +98,7 @@ background-position: ${({ type }) => (type === 'bubble_white' ? '-44px -36px' `; export default function Icon({ - type, alt, style, src, + type, alt, style, src, func, }) { const [size, setSize] = useState('md'); useEffect(() => { @@ -146,12 +146,14 @@ export default function Icon({ src={src} alt={alt} style={style} + onClick={func} /> ) : ( ); } @@ -220,6 +222,7 @@ Icon.propTypes = { alt: PropTypes.string.isRequired, src: PropTypes.string, style: PropTypes.string, + func: PropTypes.func, }; Icon.defaultProp = { type: 'test', diff --git a/src/components/InputBar/InputBar.js b/src/components/InputBar/InputBar.js index 0100e8d..7f4ee85 100644 --- a/src/components/InputBar/InputBar.js +++ b/src/components/InputBar/InputBar.js @@ -21,10 +21,10 @@ const Wrapper = styled.input` `; export default function InputBar({ - className, + className, placeholder, value, onchange, }) { return ( - + ); } diff --git a/src/components/Modal/Modal.js b/src/components/Modal/Modal.js index ef6945a..a4bda6f 100644 --- a/src/components/Modal/Modal.js +++ b/src/components/Modal/Modal.js @@ -3,6 +3,8 @@ import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import QuestionListSaveModal from './QuestionListSaveModal'; import { MODALS } from '../../utils/constant'; +import SelfTrainStartModal from './SelfTrainStartModal'; +import ModalWrapper from './ModalWrapper'; export default function Modal({ modalName, @@ -10,10 +12,16 @@ export default function Modal({ const isShow = useSelector((state) => state.modal[modalName]); const modalList = { [MODALS.QUESTIONLIST_SAVE_MODAL]: , + [MODALS.SELF_TRAIN_START_MODAL]: , }; return ( <> - { isShow && modalList[modalName] } + { isShow + && ( + + {modalList[modalName]} + + )} ); } diff --git a/src/components/Modal/Modal.stories.js b/src/components/Modal/Modal.stories.js new file mode 100644 index 0000000..70aa4a2 --- /dev/null +++ b/src/components/Modal/Modal.stories.js @@ -0,0 +1,56 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import React from 'react'; +import { Provider } from 'react-redux'; +import { configureStore, combineReducers, createSlice } from '@reduxjs/toolkit'; +import Modal from './Modal'; +import { MODALS } from '../../utils/constant'; + +const modalReducer = createSlice({ + name: 'modal', + initialState: { + [MODALS.QUESTIONLIST_SAVE_MODAL]: true, + [MODALS.SELF_TRAIN_START_MODAL]: true, + }, + reducers: { + displayModal(state, { payload: { modalName } }) { + return { + ...state, + [modalName]: true, + }; + }, + removeModal(state, { payload: { modalName } }) { + return { + ...state, + [modalName]: false, + }; + }, + }, +}); + +const reducers = combineReducers({ + modal: modalReducer.reducer, +}); + +const store = configureStore({ reducer: reducers }); + +const withReduxMockStore = (story) => ( + {story()} +); + +export default { + title: 'Modal', + description: 'modals', + decorators: [withReduxMockStore], +}; + +const modals = (args) => ; +export const QuestionListSaveModal = modals.bind({}); +export const SelfTrainStartModal = modals.bind({}); + +QuestionListSaveModal.args = { + modalName: MODALS.QUESTIONLIST_SAVE_MODAL, +}; + +SelfTrainStartModal.args = { + modalName: MODALS.SELF_TRAIN_START_MODAL, +}; diff --git a/src/components/Modal/ModalWrapper/ModalWrapper.js b/src/components/Modal/ModalWrapper/ModalWrapper.js new file mode 100644 index 0000000..14683a4 --- /dev/null +++ b/src/components/Modal/ModalWrapper/ModalWrapper.js @@ -0,0 +1,68 @@ +import React from 'react'; +import styled from 'styled-components'; +import PropTypes from 'prop-types'; +import { useDispatch } from 'react-redux'; +import { hideModal } from '../../../store/Modal/modal'; + +const Background = styled.div` + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0,0,0,0.4); + z-index: 999; +`; + +const Wrapper = styled.div` + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: auto; + outline: none; + z-index: 1000; +`; + +const Content = styled.div` + display: inline-block; + border-radius: 10px; + box-shadow: 0 6px 12px 0 rgba(4, 4, 161, 0.04); + background-color: #ffffff; + margin: 0 auto; + outline: none; +`; + +export default function ModalWrapper({ modalName, children }) { + const dispatch = useDispatch(); + const handleCloseModal = (e) => { + if (e.target === e.currentTarget) { + dispatch(hideModal(modalName)); + } + }; + + return ( + <> + + + + {children} + + + + ); +} + +ModalWrapper.propTypes = { + modalName: PropTypes.string, + children: PropTypes.element, +}; + +ModalWrapper.defaultProp = { + modalName: '', +}; diff --git a/src/components/Modal/ModalWrapper/index.js b/src/components/Modal/ModalWrapper/index.js new file mode 100644 index 0000000..0499843 --- /dev/null +++ b/src/components/Modal/ModalWrapper/index.js @@ -0,0 +1 @@ +export { default } from './ModalWrapper'; diff --git a/src/components/Modal/QuestionListSaveModal/QuestionListSaveModal.js b/src/components/Modal/QuestionListSaveModal/QuestionListSaveModal.js index 4af4609..2c9331f 100644 --- a/src/components/Modal/QuestionListSaveModal/QuestionListSaveModal.js +++ b/src/components/Modal/QuestionListSaveModal/QuestionListSaveModal.js @@ -1,49 +1,19 @@ -import React from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; -import { useDispatch } from 'react-redux'; -import { hideModal } from '../../../store/Modal/modal'; +import { useDispatch, useSelector } from 'react-redux'; +import { hideModal, showModal } from '../../../store/Modal/modal'; import InputBar from '../../InputBar'; import Button from '../../Button'; - -const Background = styled.div` - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - overflow: auto; - background-color: rgba(0,0,0,0.4); - z-index: 1; -`; +import { postQuestionListAPI, postQuestionItemAPI } from '../../../repository/questionListRepository'; +import { get } from '../../../utils/snippet'; +import { MODALS } from '../../../utils/constant'; const Wrapper = styled.div` - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - overflow: auto; - outline: none; - z-index: 2; -`; - -const Content = styled.div` - position: relative; - top: 50%; - transform: translateY(-50%); - width: 660px; - height: 876px; - border-radius: 10px; - box-shadow: 0 6px 12px 0 rgba(4, 4, 161, 0.04); - background-color: #ffffff; - margin: 0 auto; - outline: none; -`; - -const ModalWrapper = styled.div` display: flex; flex-direction: column; align-items: center; + width: 660px; + height: 876px; `; const Text = styled.div` @@ -81,43 +51,54 @@ const ButtonWrapper = styled.div` const QuestionListSaveModal = () => { const dispatch = useDispatch(); - const handleCloseModal = (e) => { - if (e.target === e.currentTarget) { - dispatch(hideModal('questionListSaveModal')); - } + const qeustionSelector = useSelector(get('question')); + const [title, setTitle] = useState(); + const [enterprise, setEnterprise] = useState(); + const [job, setJob] = useState(); + + const handleListMake = () => { + postQuestionListAPI({ title, enterprise, job }).then((response) => { + postQuestionItemAPI({ + listId: response.data.id, + questions: qeustionSelector.questions, + }).then(() => { + dispatch(hideModal(MODALS.QUESTIONLIST_SAVE_MODAL)); + dispatch(showModal(MODALS.SELF_TRAIN_START_MODAL)); + }); + }); }; + + const handleInputChange = (e, setState) => { + setState(e.target.value); + }; + return ( <> - - - - - - 질문 리스트 저장 - - - - 질문 리스트 제목 - - - - - - 기업 이름 - - - - - - 직무 이름 - - - - -