Skip to content

Commit

Permalink
Merge pull request #107 from Team-Lecue/CreateNote/#39-data-fetching
Browse files Browse the repository at this point in the history
[ CreateNote ] 레큐노트 생성 api 붙이기
  • Loading branch information
Arooming committed Jan 15, 2024
2 parents 3c95472 + 988de27 commit f6522f8
Show file tree
Hide file tree
Showing 13 changed files with 467 additions and 251 deletions.
8 changes: 8 additions & 0 deletions src/LecueNote/api/getPresignedUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { api } from '../../libs/api';

const getPresignedUrl = async () => {
const { data } = await api.get('/api/images/note');
return data;
};

export default getPresignedUrl;
38 changes: 38 additions & 0 deletions src/LecueNote/api/postLecueNote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// import { useNavigate } from 'react-router-dom';

import { api } from '../../libs/api';
import { postLecueNoteProps } from '../type/lecueNoteType';

const postLecueNote = ({
contents,
color,
fileName,
bgColor,
}: postLecueNoteProps) => {
// const navigate = useNavigate();

const response = api
.post(
'/api/notes',
{
bookId: 1,
content: contents,
textColor: color,
background: fileName ? fileName : bgColor,
},
{
headers: {
Authorization: `Bearer ${import.meta.env.VITE_APP_TOKEN}`,
},
},
)
.then((res) => {
console.log(res);
// 나중에 주석코드를 활성화시킬 예정!
// navigate(`lecue-book/${res.data.data.bookUuid}`);
});

return response;
};

export default postLecueNote;
18 changes: 18 additions & 0 deletions src/LecueNote/api/putPresignedUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { api } from '../../libs/api';
import { putPresignedUrlProps } from '../type/lecueNoteType';

const putPresignedUrl = ({
presignedUrl,
binaryFile,
fileType,
}: putPresignedUrlProps) => {
const response = api.put(presignedUrl, binaryFile, {
headers: {
'Content-Type': fileType,
},
});

return response;
};

export default putPresignedUrl;
42 changes: 9 additions & 33 deletions src/LecueNote/components/CreateNote/index.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,22 @@
import { useState } from 'react';

import {
BG_COLOR_CHART,
CATEGORY,
TEXT_COLOR_CHART,
} from '../../constants/colorChart';
import { CreateNoteProps } from '../../type/lecueNoteType';
import SelectColor from '../SelectColor';
import WriteNote from '../WriteNote';
import * as S from './CreateNote.style';

function CreateNote({
clickedCategory,
clickedBgColor,
clickedTextColor,
isIconClicked,
contents,
setFileName,
handleChangeFn,
handleClickCategory,
handleClickedColorBtn,
handleClickedIcon,
imgFile,
uploadImage,
}: CreateNoteProps) {
const [clickedCategory, setclickedCategory] = useState(CATEGORY[0]);
const [clickedTextColor, setClickedTextColor] = useState(TEXT_COLOR_CHART[0]);
const [clickedBgColor, setclickedBgColor] = useState(BG_COLOR_CHART[0]);
const [isIconClicked, setIsIconClicked] = useState(false);

const handleClickCategory = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
) => {
setclickedCategory(e.currentTarget.innerHTML);
};

const handleClickedColorBtn = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
) => {
if (clickedCategory === '텍스트색') {
setClickedTextColor(e.currentTarget.id);
} else {
setclickedBgColor(e.currentTarget.id);
setIsIconClicked(false);
}
};

const handleClickedIcon = () => {
setIsIconClicked(true);
};

return (
<S.Wrapper>
<WriteNote
Expand All @@ -57,6 +32,7 @@ function CreateNote({
clickedCategory={clickedCategory}
clickedTextColor={clickedTextColor}
clickedBgColor={clickedBgColor}
setFileName={setFileName}
handleCategoryFn={handleClickCategory}
handleColorFn={handleClickedColorBtn}
handleIconFn={handleClickedIcon}
Expand Down
20 changes: 18 additions & 2 deletions src/LecueNote/components/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import Button from '../../../components/common/Button';
import usePostLecueNote from '../../hooks/usePostLecueNote';
import { FooterProps } from '../../type/lecueNoteType';
import * as S from './Footer.style';

function Footer({ contents }: FooterProps) {
function Footer({ contents, fileName, textColor, bgColor }: FooterProps) {
const postMutation = usePostLecueNote();

const handleClickBtn = () => {
postMutation.mutate({
contents: contents,
color: textColor,
fileName: fileName,
bgColor: bgColor,
});
};

return (
<S.Wrapper>
<Button variant="complete" disabled={contents.length === 0}>
<Button
variant="complete"
disabled={contents.length === 0}
onClick={handleClickBtn}
>
작성 완료
</Button>
</S.Wrapper>
Expand Down
3 changes: 3 additions & 0 deletions src/LecueNote/components/SelectColor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function SelectColor({
clickedCategory,
clickedTextColor,
clickedBgColor,
setFileName,
handleCategoryFn,
handleColorFn,
handleIconFn,
Expand Down Expand Up @@ -39,6 +40,7 @@ function SelectColor({
isIconClicked={isIconClicked}
colorChart={TEXT_COLOR_CHART}
state={clickedTextColor}
setFileName={setFileName}
uploadImage={uploadImage}
handleFn={handleColorFn}
handleIconFn={handleIconFn}
Expand All @@ -48,6 +50,7 @@ function SelectColor({
isIconClicked={isIconClicked}
colorChart={BG_COLOR_CHART}
state={clickedBgColor}
setFileName={setFileName}
uploadImage={uploadImage}
handleFn={handleColorFn}
handleIconFn={handleIconFn}
Expand Down
39 changes: 33 additions & 6 deletions src/LecueNote/components/ShowColorChart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,64 @@
import { useRef } from 'react';
import { useEffect, useRef, useState } from 'react';

import { IcCameraSmall } from '../../../assets';
import { BG_COLOR_CHART } from '../../constants/colorChart';
import useGetPresignedUrl from '../../hooks/useGetPresignedUrl';
import usePutPresignedUrl from '../../hooks/usePutPresignedUrl';
import { ShowColorChartProps } from '../../type/lecueNoteType';
import * as S from './ShowColorChart.style';

function ShowColorChart({
isIconClicked,
colorChart,
state,
setFileName,
uploadImage,
handleFn,
handleIconFn,
}: ShowColorChartProps) {
const imgRef = useRef<HTMLInputElement | null>(null);
const [presignedUrl, setPresignedUrl] = useState('');
const { data } = useGetPresignedUrl();
// 함수 컴포넌트 내에서 커스텀 훅 호출 시, 에러발생
const putMutation = usePutPresignedUrl();

const handleImageUpload = () => {
const fileInput = imgRef.current;

if (fileInput && fileInput.files && fileInput.files.length > 0) {
const file = fileInput.files[0];

const reader = new FileReader();
reader.readAsDataURL(file);
// reader1: 파일을 base64로 읽어서 업로드
const reader1 = new FileReader();
reader1.readAsDataURL(file);
reader1.onloadend = () => {
if (reader1.result !== null) {
uploadImage(reader1.result as string);
}
};

reader.onloadend = () => {
if (reader.result !== null) {
uploadImage(reader.result as string);
// reader2: 파일을 ArrayBuffer로 읽어서 PUT 요청 수행
const reader2 = new FileReader();
reader2.readAsArrayBuffer(file);
reader2.onloadend = () => {
if (reader2.result !== null && presignedUrl) {
putMutation.mutate({
presignedUrl: presignedUrl,
binaryFile: reader2.result,
fileType: file.type,
});
}
};
}
};

useEffect(() => {
if (data !== undefined) {
setPresignedUrl(data.data.url);
setFileName(data.data.fileName);
}
}, [data]);

return (
<S.Wrapper>
{colorChart === BG_COLOR_CHART && (
Expand Down
14 changes: 14 additions & 0 deletions src/LecueNote/hooks/useGetPresignedUrl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useQuery } from 'react-query';

import getPresignedUrl from '../api/getPresignedUrl';

const useGetPresignedUrl = () => {
const { isLoading, error, data } = useQuery({
queryKey: ['get-presigned-url'],
queryFn: () => getPresignedUrl(),
});

return { isLoading, error, data };
};

export default useGetPresignedUrl;
22 changes: 22 additions & 0 deletions src/LecueNote/hooks/usePostLecueNote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AxiosError } from 'axios';
import { useMutation } from 'react-query';

import postLecueNote from '../api/postLecueNote';
import { postLecueNoteProps } from '../type/lecueNoteType';

const usePostLecueNote = () => {
const mutation = useMutation({
mutationFn: ({
contents,
color,
fileName,
bgColor,
}: postLecueNoteProps) => {
return postLecueNote({ contents, color, fileName, bgColor });
},
onError: (err: AxiosError) => console.log(err),
});
return mutation;
};

export default usePostLecueNote;
21 changes: 21 additions & 0 deletions src/LecueNote/hooks/usePutPresignedUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AxiosError } from 'axios';
import { useMutation } from 'react-query';

import putPresignedUrl from '../api/putPresignedUrl';
import { putPresignedUrlProps } from './../type/lecueNoteType';

const usePutPresignedUrl = () => {
const mutation = useMutation({
mutationFn: ({
presignedUrl,
binaryFile,
fileType,
}: putPresignedUrlProps) => {
return putPresignedUrl({ presignedUrl, binaryFile, fileType });
},
onError: (err: AxiosError) => console.log(err),
});
return mutation;
};

export default usePutPresignedUrl;
48 changes: 46 additions & 2 deletions src/LecueNote/page/LeceuNotePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,28 @@ import { useState } from 'react';
import Header from '../../../components/common/Header';
import CreateNote from '../../components/CreateNote';
import Footer from '../../components/Footer';
import {
BG_COLOR_CHART,
CATEGORY,
TEXT_COLOR_CHART,
} from '../../constants/colorChart';
import * as S from './LecueNotePage.style';

function LecueNotePage() {
const MAX_LENGTH = 1000;
const [contents, setContents] = useState('');
const [imgFile, setImgFile] = useState('');
const [clickedCategory, setclickedCategory] = useState(CATEGORY[0]);
const [clickedTextColor, setClickedTextColor] = useState(TEXT_COLOR_CHART[0]);
const [clickedBgColor, setclickedBgColor] = useState(BG_COLOR_CHART[0]);
const [isIconClicked, setIsIconClicked] = useState(false);
const [fileName, setFileName] = useState('');

const handleClickCategory = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
) => {
setclickedCategory(e.currentTarget.innerHTML);
};

const handleChangeContents = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setContents(e.target.value);
Expand All @@ -18,16 +34,44 @@ function LecueNotePage() {
}
};

const handleClickedColorBtn = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
) => {
if (clickedCategory === '텍스트색') {
setClickedTextColor(e.currentTarget.id);
} else {
setclickedBgColor(e.currentTarget.id);
setIsIconClicked(false);
}
};

const handleClickedIcon = () => {
setIsIconClicked(true);
};

return (
<S.Wrapper>
<Header headerTitle="레큐노트 작성" />
<CreateNote
clickedCategory={clickedCategory}
clickedTextColor={clickedTextColor}
clickedBgColor={clickedBgColor}
isIconClicked={isIconClicked}
contents={contents}
handleChangeFn={handleChangeContents}
imgFile={imgFile}
uploadImage={(file) => setImgFile(file)}
setFileName={setFileName}
handleChangeFn={handleChangeContents}
handleClickCategory={handleClickCategory}
handleClickedColorBtn={handleClickedColorBtn}
handleClickedIcon={handleClickedIcon}
/>
<Footer
contents={contents}
fileName={fileName}
textColor={clickedTextColor}
bgColor={clickedBgColor}
/>
<Footer contents={contents} />
</S.Wrapper>
);
}
Expand Down
Loading

0 comments on commit f6522f8

Please sign in to comment.