From 6aac93770af08842e072791d985c696f07349ef3 Mon Sep 17 00:00:00 2001 From: akjfal Date: Tue, 13 Apr 2021 22:30:10 +0900 Subject: [PATCH] project fin --- src/App.js | 3 +- src/hook/projectTs/index.ts | 3 + src/hook/projectTs/useProjectApplyTs.ts | 2 +- src/hook/projectTs/useProjectDetailTs.ts | 8 - src/hook/projectTs/useProjectListTs.ts | 2 +- src/hook/projectTs/useProjectUpdateTs.ts | 269 +++++++++++++++++++++++ src/hook/useImage.tsx | 1 - src/pages/index.js | 2 +- src/pages/project/createProjectTs.tsx | 206 +++++++++-------- src/pages/project/projectDetail.css | 14 +- src/pages/project/projectDetailTs.tsx | 2 +- src/pages/project/updateProjectTs.tsx | 218 ++++++++++++++++++ tsconfig.json | 3 +- 13 files changed, 606 insertions(+), 127 deletions(-) create mode 100644 src/hook/projectTs/useProjectUpdateTs.ts create mode 100644 src/pages/project/updateProjectTs.tsx diff --git a/src/App.js b/src/App.js index 0c3141a8..1f22e35e 100644 --- a/src/App.js +++ b/src/App.js @@ -4,8 +4,6 @@ import { Root, ProjectList, Profile, - Register, - Login, ProjectDetail, ProjectCreate, ProjectUpdate, @@ -28,6 +26,7 @@ function App() { + {/* diff --git a/src/hook/projectTs/index.ts b/src/hook/projectTs/index.ts index 5f0c4dcd..8038f78e 100644 --- a/src/hook/projectTs/index.ts +++ b/src/hook/projectTs/index.ts @@ -13,3 +13,6 @@ export { useViewProjectApplyStateTs, useViewProjectApplyEffectTs, } from "./useProjectApplyTs"; +export { useProjectUpdateStateTs, useProjectUpdateEffectTs } from "./useProjectUpdateTs"; +export {useProjectCreateEffectTs, + useProjectCreateStateTS} from "./useProjectCreateTs"; \ No newline at end of file diff --git a/src/hook/projectTs/useProjectApplyTs.ts b/src/hook/projectTs/useProjectApplyTs.ts index 99a13d75..27f849c8 100644 --- a/src/hook/projectTs/useProjectApplyTs.ts +++ b/src/hook/projectTs/useProjectApplyTs.ts @@ -1,7 +1,7 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import { useHistory } from "react-router-dom"; -import { useRequest } from ".."; +import { useRequest } from "../"; import { loginApi } from "../api"; import { RequestState } from "../useRequest"; diff --git a/src/hook/projectTs/useProjectDetailTs.ts b/src/hook/projectTs/useProjectDetailTs.ts index 6c918e03..d366fdda 100644 --- a/src/hook/projectTs/useProjectDetailTs.ts +++ b/src/hook/projectTs/useProjectDetailTs.ts @@ -64,14 +64,6 @@ type checkType = { applyDetail: boolean; }; -// type ApplyTypeTmp = { -// res: Promise; -// resApply: { -// apply: object; -// recruit: object; -// } -// } - type pagenationType = { apply: number, recruit: number, diff --git a/src/hook/projectTs/useProjectListTs.ts b/src/hook/projectTs/useProjectListTs.ts index 2cadfd97..5e9fe2b6 100644 --- a/src/hook/projectTs/useProjectListTs.ts +++ b/src/hook/projectTs/useProjectListTs.ts @@ -1,6 +1,6 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; -import { useRequest } from ".."; +import { useRequest } from "../"; import { setTemporary } from "../../reducers/temporary"; import { loginApi } from "../api"; import { RequestState } from "../useRequest"; diff --git a/src/hook/projectTs/useProjectUpdateTs.ts b/src/hook/projectTs/useProjectUpdateTs.ts new file mode 100644 index 00000000..6588e2f0 --- /dev/null +++ b/src/hook/projectTs/useProjectUpdateTs.ts @@ -0,0 +1,269 @@ +import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { useHistory } from "react-router-dom"; +import { loginApi } from "../api"; +import { useAlert, useRequest } from "../"; +import { AxiosError } from "axios"; +import { RequestState } from "../useRequest"; + +const axios = require("axios"); + +type CreateProject = { + projectName: string; + teamName: string; + endDate: string; + introduction: string; + state: any; + projectField: string; + applyCanFile: boolean; + questions: string[]; + needMember: { + developer: number; + designer: number; + planner: number; + etc: number; + }; +}; + +type updateStateType = { + project: CreateProject; + img: any; + updateProject: RequestState; + updateImg: RequestState; + } + +type updateActionType = { + UpdateProjectApi: (projectId: string, data: any) => Promise; + UpdateImgApi: (projectId: string, data: any) => Promise; + inputProject: (e: React.ChangeEvent) => void; + setImg: Dispatch>; + inputProjectMember: (e: React.ChangeEvent) => void; + inputDate: (date: any) => void; + inputQuestion: (data: string, index: number) => void; + addQuestion: () => void; + deleteQuestion: (index: number) => void; + inputField: (data: string) => void; + } + +type UpdateType = { + updateState: updateStateType; + updateAction: updateActionType; +}; + +const useProjectUpdateStateTs = (): UpdateType => { + const projectDetail = useSelector( + (state: any) => state.project.projectDetail, + ); + const [project, setProject] = useState(projectDetail); + const [img, setImg] = useState(projectDetail.img); + + const fetchPutUpdate = async ( + projectId: string, + data: any, + ): Promise => { + let token = window.sessionStorage.getItem("accessToken"); + let res = await axios + .put(`${process.env.REACT_APP_BASE_URL}projects/${projectId}`, data, { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json;charset=UTF-8", + Accept: "application/hal+json", + }, + }) + .catch(async (error: any) => { + if (error.response.data.error === "007") { + token = await loginApi().refreshToken(); + + res = await axios + .put( + `${process.env.REACT_APP_BASE_URL}projects/${projectId}`, + data, + { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json;charset=UTF-8", + Accept: "application/hal+json", + }, + }, + ) + .catch((error: any) => { + throw error; + }); + } else { + throw error; + } + }); + return res.data; + }; + + const fetchImg = async (projectId: string, data: any): Promise => { + let token = window.sessionStorage.getItem("accessToken"); + const imgData = new FormData(); + imgData.append("image", data); + imgData.append("type", "image/jpeg"); + let res = await axios + .post( + `${process.env.REACT_APP_BASE_URL}projects/image/${projectId}`, + imgData, + { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "multipart/form-data;charset=UTF-8", + Accept: "application/hal+json", + }, + }, + ) + .catch(async (error: any) => { + if (error.response.data.error === "007") { + token = await loginApi().refreshToken(); + + res = await axios + .post( + `${process.env.REACT_APP_BASE_URL}projects/image/${projectId}`, + imgData, + { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "multipart/form-data;charset=UTF-8", + Accept: "application/hal+json", + }, + }, + ) + .catch((error: any) => { + throw error; + }); + } else { + throw error; + } + }); + return res.data; + }; + + const [updateProject, { run: UpdateProjectApi }] = useRequest(fetchPutUpdate); + const [updateImg, { run: UpdateImgApi }] = useRequest(fetchImg); + + const inputProject = (e: React.ChangeEvent) => { + const name = e.target.name; + const targetValue = e.target.value; + + setProject((value) => { + return { + ...value, + [name]: targetValue, + }; + }); + }; + + const inputDate = (date: string) => { + setProject((value) => { + return { + ...value, + endDate: date, + }; + }); + }; + + const inputQuestion = (data: string, index: number) => { + setProject((value) => { + const questions = value.questions.map((q, i) => { + if (index === i) { + return data; + } else { + return q; + } + }); + return { + ...value, + questions: questions, + }; + }); + }; + + const addQuestion = () => { + setProject((value) => { + const questions = value.questions.concat(""); + return { + ...value, + questions: questions, + }; + }); + }; + const deleteQuestion = (index: number) => { + setProject((value) => { + const questions = value.questions.filter((q, i) => i !== index); + return { + ...value, + questions: questions, + }; + }); + }; + + const inputProjectMember = (e: React.ChangeEvent) => { + const name = e.target.name; + const memberValue = e.target.value; + setProject((value) => { + return { + ...value, + needMember: { + ...value.needMember, + [name]: memberValue, + }, + }; + }); + }; + + const inputField = (data: string) => { + setProject((value) => { + return { + ...value, + projectField: data, + }; + }); + }; + + return { + updateState: { project, img, updateProject, updateImg }, + updateAction: { + UpdateProjectApi, + UpdateImgApi, + inputProject, + setImg, + inputProjectMember, + inputDate, + inputQuestion, + addQuestion, + deleteQuestion, + inputField, + }, + }; +}; + +const useProjectUpdateEffectTs = ( + updateState: updateStateType, + updateAction: updateActionType, + projectId: string, +) => { + const history = useHistory(); +// const [alertData, alertAction] = useAlert(); + const originImg = useSelector( + (state: any) => state.project.projectDetail.img, + ); + useEffect(() => { + if (updateState.updateProject.fulfilled) { + console.log(typeof updateState.img); + console.log(updateState.img); + if (updateState.img.length === originImg) + updateAction.UpdateImgApi(projectId, updateState.img); + else history.push(`/projectDetail/${projectId}`); + } + }, [updateState.updateProject.fulfilled]); + + useEffect(() => { + if (updateState.updateProject.rejected) { + // alertAction.open(updateState.updateProject.error.response.data.message); + console.log(updateState.updateProject.error); + } + }, [updateState.updateProject.rejected]); +}; + +export { useProjectUpdateStateTs, useProjectUpdateEffectTs }; diff --git a/src/hook/useImage.tsx b/src/hook/useImage.tsx index 70fc3cfc..02b26eaf 100644 --- a/src/hook/useImage.tsx +++ b/src/hook/useImage.tsx @@ -12,7 +12,6 @@ export const useImageSave = ( useEffect(() => { if (postImg.fulfilled) { - console.log(postImg.data); const projectId = postImg.data.fileName.split("."); history.push(`${nextUrl}/${projectId[0]}`); } diff --git a/src/pages/index.js b/src/pages/index.js index 14319979..ce142bc2 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -3,7 +3,7 @@ export { default as Root } from "./rootTs"; export { default as ProjectList } from "./project/projectListTs"; export { default as ProjectDetail } from "./project/projectDetailTs"; export { default as ProjectCreate } from "./project/createProjectTs"; -export { default as ProjectUpdate } from "./project/updateProject"; +export { default as ProjectUpdate } from "./project/updateProjectTs"; export { default as Register } from "./auth/Register"; export { default as RegisterPage } from "./auth/RegisterTs"; export { default as Profile } from "./Profile"; diff --git a/src/pages/project/createProjectTs.tsx b/src/pages/project/createProjectTs.tsx index a9258c06..e885b819 100644 --- a/src/pages/project/createProjectTs.tsx +++ b/src/pages/project/createProjectTs.tsx @@ -12,7 +12,10 @@ import { } from "@material-ui/pickers"; import DateFnsUtils from "@date-io/date-fns"; import { ko } from "date-fns/locale"; -import { useProjectCreateEffectTs, useProjectCreateStateTS } from "../../hook/projectTs/useProjectCreateTs"; +import { + useProjectCreateEffectTs, + useProjectCreateStateTS, +} from "../../hook/projectTs"; import { Button, Input } from "antd"; import { useImageSave } from "../../hook/useImage"; @@ -37,120 +40,116 @@ export default function ProjectCreate() { -
-
- -
-
-
- - ) => - createAction.inputProject(e.target.name, e.target.value) - } - /> - - ) => - createAction.inputProject(e.target.name, e.target.value) - } - value={createState.project.teamName} - /> +
- -
- ) => - createAction.inputProjectMember(e.target.name, e.target.value) - } - value={createState.project.needMember.developer} - /> - ) => - createAction.inputProjectMember(e.target.name, e.target.value) - } - value={createState.project.needMember.designer} - /> -
+
+ +
+
+
+ ) => - createAction.inputProjectMember(e.target.name, e.target.value) + createAction.inputProject(e.target.name, e.target.value) } - value={createState.project.needMember.planner} /> -
+ ) => - createAction.inputProjectMember(e.target.name, e.target.value) + createAction.inputProject(e.target.name, e.target.value) } - value={createState.project.needMember.etc} + value={createState.project.teamName} /> -
-
- - - createAction.inputDate(date)} - format="yy.MM.dd HH:mm" - placeholder="종료일" - variant="dialog" - // disableUnderline - disableToolbar={false} - hideTabs - clearable - ampm +
+ + Developer
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="developer" + onChange={(e: React.ChangeEvent) => + createAction.inputProjectMember(e.target.name, e.target.value) + } + value={createState.project.needMember.developer} /> -
-
-
-
- - + Designer
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="designer" + onChange={(e: React.ChangeEvent) => + createAction.inputProjectMember(e.target.name, e.target.value) + } + value={createState.project.needMember.designer} + /> + Planner
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="planner" + onChange={(e: React.ChangeEvent) => + createAction.inputProjectMember(e.target.name, e.target.value) + } + value={createState.project.needMember.planner} + /> + Etc
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="etc" + onChange={(e: React.ChangeEvent) => + createAction.inputProjectMember(e.target.name, e.target.value) + } + value={createState.project.needMember.etc} + /> +
+
+ + + createAction.inputDate(date)} + format="yy.MM.dd HH:mm" + placeholder="종료일" + variant="dialog" + disableToolbar={false} + hideTabs + clearable + ampm + /> + + + + +
-
+
Add Questions
-
); diff --git a/src/pages/project/projectDetail.css b/src/pages/project/projectDetail.css index f44c9401..557c0444 100644 --- a/src/pages/project/projectDetail.css +++ b/src/pages/project/projectDetail.css @@ -2,19 +2,13 @@ padding: 10px; } -#root::after { - clear: both; - content: ''; - display: block; -} - .full_div { width: 100%; min-height: 36px; } .half_div_left { - padding: 10px; + padding: 10px 10px 10px 0; float: left; width: 50%; } @@ -28,6 +22,12 @@ .half_div_right > h1 { } +.input_grid::after { + clear: both; + content: ''; + display: block; +} + .half_div_right > h4 { color: gray; margin: 0px 0px 30px 0px; diff --git a/src/pages/project/projectDetailTs.tsx b/src/pages/project/projectDetailTs.tsx index f2c66f7c..58357552 100644 --- a/src/pages/project/projectDetailTs.tsx +++ b/src/pages/project/projectDetailTs.tsx @@ -144,7 +144,7 @@ export default function ProjectDetail() { )} -
+
{ + const updateData = { + projectName: updateState.project.projectName, + teamName: updateState.project.teamName, + endDate: updateState.project.endDate, + introduction: updateState.project.introduction, + state: updateState.project.state, + projectField: updateState.project.projectField, + applyCanFile: updateState.project.applyCanFile, + needMember: { + developer: updateState.project.needMember.developer, + designer: updateState.project.needMember.designer, + planner: updateState.project.needMember.planner, + etc: updateState.project.needMember.etc, + }, + questions: updateState.project.questions, + }; + updateAction.UpdateProjectApi(projectId, updateData); + }; + + return ( + +
+
+
+ +
+
+
+
+
+ +
+
+
+ + + + +
+ + Developer
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="developer" + onChange={(e: React.ChangeEvent) => + updateAction.inputProjectMember(e) + } + value={updateState.project.needMember.developer} + /> + Designer
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="designer" + onChange={(e: React.ChangeEvent) => + updateAction.inputProjectMember(e) + } + value={updateState.project.needMember.designer} + /> + Planner
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="planner" + onChange={(e: React.ChangeEvent) => + updateAction.inputProjectMember(e) + } + value={updateState.project.needMember.planner} + /> + Etc
} + placeholder="0" + min={0} + max={100} + type="number" + step="1" + name="etc" + onChange={(e: React.ChangeEvent) => + updateAction.inputProjectMember(e) + } + value={updateState.project.needMember.etc} + /> +
+
+ + + updateAction.inputDate(date)} + format="yy.MM.dd HH:mm" + placeholder="종료일" + variant="dialog" + disableToolbar={false} + hideTabs + clearable + ampm + /> + + + +
+
+
+
+
+ + +
+ + {updateState.project.questions.map((value: string, index: number) => { + const questionString = `Question ${index + 1}`; + return ( +
+ updateAction.deleteQuestion(index)} + > + delete + + } + placeholder="question" + name="questions" + onChange={(e) => + updateAction.inputQuestion(e.target.value, index) + } + value={value} + /> +
+ ); + })} +
+
+
+ +
+
+ + + ); +} diff --git a/tsconfig.json b/tsconfig.json index 22544462..46af96a6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "lib": [ "dom", "dom.iterable", - "esnext" + "esnext", + "WebWorker" ], "allowJs": true, "skipLibCheck": true,