Skip to content

Commit

Permalink
Merge pull request #86 from boostcampwm2023/feat/71-diary-create-api
Browse files Browse the repository at this point in the history
[Feat] 일기 생성 API 연동 및 입력 상태에 따른 저장 버튼 활성화
  • Loading branch information
dmson1218 authored Nov 22, 2023
2 parents 3642f51 + ea63104 commit 3a94def
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 23 deletions.
3 changes: 3 additions & 0 deletions FE/src/assets/deleteIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
213 changes: 190 additions & 23 deletions FE/src/components/DiaryModal/DiaryCreateModal.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,83 @@
import React from "react";
import { useRecoilValue, useSetRecoilState } from "recoil";
import { useMutation, useQuery } from "react-query";
import styled from "styled-components";
import { useSetRecoilState } from "recoil";
import userAtom from "../../atoms/userAtom";
import diaryAtom from "../../atoms/diaryAtom";
import ModalWrapper from "../../styles/Modal/ModalWrapper";
import DiaryModalHeader from "../../styles/Modal/DiaryModalHeader";
import stars from "../../assets/stars";
import deleteIcon from "../../assets/deleteIcon.svg";

async function getShapeFn() {
return fetch("http://223.130.129.145:3005/shapes/default", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then((res) => res.json());
}

async function createDiaryFn(data) {
return fetch("http://223.130.129.145:3005/diaries", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${data.accessToken}`,
},
body: JSON.stringify(data.diaryData),
}).then((res) => res.json());
}

// TODO: 일기 데이터 수정 API 연결
function DiaryCreateModal() {
const [isInput, setIsInput] = React.useState(false);
const [diaryData, setDiaryData] = React.useState({
title: "test",
content: "test",
date: "2023-11-20",
point: "0,0,0",
tags: ["test"],
shapeUuid: "6900001c-adee-4895-a283-c90f248be819",
});
const userState = useRecoilValue(userAtom);
const setDiaryState = useSetRecoilState(diaryAtom);

const closeModal = () => {
setDiaryState((prev) => ({ ...prev, isCreate: false }));
};

const addTag = (e) => {
if (e.target.value.length > 0 && !diaryData.tags.includes(e.target.value)) {
setDiaryData({
...diaryData,
tags: [...diaryData.tags, e.target.value],
});
}
e.target.value = "";
};

const deleteTag = (e) => {
setDiaryData({
...diaryData,
tags: diaryData.tags.filter((tag) => tag !== e.target.innerText),
});
};

const deleteLastTag = () => {
setDiaryData({ ...diaryData, tags: diaryData.tags.slice(0, -1) });
};

const {
data: shapeData,
// isLoading: shapeIsLoading,
// isError: shapeIsError,
} = useQuery("shape", getShapeFn);
const {
mutate: createDiary,
// isLoading: diaryIsLoading,
// isError: diaryIsError,
} = useMutation(createDiaryFn);

return (
<ModalWrapper left='60%' width='40vw' height='65vh' opacity='0.3'>
<DiaryModalHeader>
Expand All @@ -23,40 +93,83 @@ function DiaryCreateModal() {
<DiaryModalInputBox
fontSize='1.1rem'
placeholder='제목을 입력해주세요.'
onChange={(e) => {
if (e.target.value.length > 0) {
setDiaryData({ ...diaryData, title: e.target.value });
setIsInput(true);
} else {
setIsInput(false);
}
}}
/>
<DiaryModalContentInputBox placeholder='내용을 입력해주세요.' />
<DiaryModalInputBox fontSize='1rem' placeholder='태그를 입력해주세요.' />
<DiaryModalShapeSelectBox />
<ModalSideButtonWrapper>
<ModalSideButton
onClick={() => {
setDiaryState({
isCreate: false,
isRead: false,
isDelete: false,
});
<DiaryModalContentInputBox
placeholder='내용을 입력해주세요.'
onChange={(e) =>
setDiaryData({ ...diaryData, content: e.target.value })
}
/>
<DiaryModalTagWrapper>
{diaryData.tags.map((tag) => (
<DiaryModalTagBox
key={tag}
onClick={(e) => {
deleteTag(e);
}}
>
{tag}
</DiaryModalTagBox>
))}
<DiaryModalTagInputBox
fontSize='1rem'
placeholder='태그를 입력해주세요.'
onBlur={(e) => addTag(e)}
onKeyPress={(e) => {
if (e.key === "Enter") {
addTag(e);
}
}}
>
X
</ModalSideButton>
<ModalSideButton width='5rem' borderRadius='2rem'>
저장
onKeyDown={(e) => {
if (e.key === "Backspace" && e.target.value.length === 0) {
deleteLastTag();
}
}}
/>
</DiaryModalTagWrapper>
<DiaryModalShapeSelectBox shapeData={shapeData} />
<ModalSideButtonWrapper>
<ModalSideButton onClick={closeModal}>
<img src={deleteIcon} alt='delete' />
</ModalSideButton>
{isInput ? (
<ModalSideButton
width='5rem'
onClick={() => {
createDiary({ diaryData, accessToken: userState.accessToken });
closeModal();
}}
>
생성
</ModalSideButton>
) : null}
</ModalSideButtonWrapper>
</ModalWrapper>
);
}

function DiaryModalShapeSelectBox() {
function DiaryModalShapeSelectBox(props) {
const { shapeData } = props;

return (
<ShapeSelectBoxWrapper>
<ShapeSelectTextWrapper>
<DiaryModalTitle>모양</DiaryModalTitle>
<ShapeSelectText>직접 그리기</ShapeSelectText>
</ShapeSelectTextWrapper>
<ShapeSelectItemWrapper>
{stars.map((star) => (
<ShapeSelectBoxItem>{star}</ShapeSelectBoxItem>
{shapeData?.map((shape) => (
<ShapeSelectBoxItem key={shape.uuid}>
{shape.shapePath}
</ShapeSelectBoxItem>
))}
</ShapeSelectItemWrapper>
</ShapeSelectBoxWrapper>
Expand Down Expand Up @@ -115,6 +228,7 @@ const ShapeSelectBoxItem = styled.div`
`;

const ModalSideButtonWrapper = styled.div`
width: 5rem;
height: 100%;
position: absolute;
Expand All @@ -130,14 +244,14 @@ const ModalSideButton = styled.div`
width: ${(props) => props.width || "2.5rem"};
height: 2.5rem;
background-color: rgba(255, 255, 255, 0.3);
border-radius: ${(props) => props.borderRadius || "100%"};
border-radius: 2rem;
z-index: 1001;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: 1.3rem;
font-size: 1.2rem;
cursor: pointer;
`;

Expand Down Expand Up @@ -195,4 +309,57 @@ const DiaryModalContentInputBox = styled.textarea`
}
`;

const DiaryModalTagWrapper = styled.div`
width: 100%;
border-radius: 0.2rem;
border: 1px solid #ffffff;
background-color: transparent;
padding: 0.5rem 1rem;
box-sizing: border-box;
color: #ffffff;
outline: none;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
`;

const DiaryModalTagInputBox = styled.input`
width: 8.5rem;
padding: 0.5rem 0;
border: none;
background-color: transparent;
color: #ffffff;
outline: none;
flex-grow: 1;
font-family: "Pretendard-Medium";
font-size: 1rem;
&::placeholder {
color: #ffffff;
}
`;

const DiaryModalTagBox = styled.div`
padding: 0.5rem 1rem;
border-radius: 1.5rem;
border: 1px solid #ffffff;
background-color: rgba(255, 255, 255, 0.3);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
`;

export default DiaryCreateModal;

0 comments on commit 3a94def

Please sign in to comment.