Skip to content

Commit

Permalink
feat :: presigned_url & 공지사항 퍼블리싱
Browse files Browse the repository at this point in the history
  • Loading branch information
eejx0 committed Mar 11, 2024
1 parent 78286d5 commit 4331c5e
Show file tree
Hide file tree
Showing 15 changed files with 861 additions and 0 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,8 @@
"@types/styled-components": "^5.1.26",
"prettier": "2.8.8",
"typescript": "4.5"
},
"compilerOptions": {
"target": "es6"
}
}
15 changes: 15 additions & 0 deletions src/Apis/File/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,18 @@ export const useFileUpload = (file: File, options: MutationOptions) => {
}
);
};


/** 선생님 모집의뢰 상태 변경 */
export const useUpload = (files: File[], options: MutationOptions) => {
const formData = new FormData();
files.forEach((file) => {
formData.append('file', file);
})
return useMutation(
async () => instance.post(`${router}?type=EXTENSION_FILE`, formData),
{
...options,
}
);
};
59 changes: 59 additions & 0 deletions src/Apis/Files/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useMutation } from "react-query"
import { PresignedUrlRequest } from "./request"
import { PresignedUrlResponse } from "./response"
import { instance } from "../axios"
import axios from "axios"

// export const usePresignedUrl = () => {
// return useMutation(
// async (attachments: File[]) => {
// const files = attachments.map((item) => ({
// type: 'EXTENSION_FILE',
// file_name: item.name,
// }));

// const data = await instance.post(`${process.env.REACT_APP_BASE_URL}/files/pre-signed`, {files});

// return data;
// }, {
// onSuccess: ({data}) => {
// console.log(data);
// }
// }
// )
// }
// propsData: PresignedUrlRequest/

export const usePresignedUrl = () => {
return useMutation(
async (attachments: File[]) => {
const files = attachments.map((item) => ({
type: 'EXTENSION_FILE',
file_name: item.name,
}));

const { data: presignedUrls } = await instance.post<PresignedUrlResponse>(`${process.env.REACT_APP_BASE_URL}/files/pre-signed`, { files });
return {presignedUrls, attachments};
}, {
onSuccess: async ({ presignedUrls, attachments }) => {

const uploadPromises = presignedUrls.urls.map(({pre_signed_url}, idx) => {
(async () => await axios.put(pre_signed_url, attachments[idx]))();
});
await Promise.all(uploadPromises);
}
}
)
}

// const readFileAsBinaryString = (file: File): Promise<string> => {
// return new Promise((resolve, reject) => {
// const reader = new FileReader();
// reader.onload = () => {
// const result = reader.result as string;
// resolve(result);
// };
// reader.onerror = reject;
// reader.readAsBinaryString(file);
// });
// }
6 changes: 6 additions & 0 deletions src/Apis/Files/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface PresignedUrlRequest {
files: {
type: string
file_name: string
}[]
}
8 changes: 8 additions & 0 deletions src/Apis/Files/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface PresignedUrlResponse {
urls: [
{
file_path: string,
pre_signed_url: string
}
]
}
21 changes: 21 additions & 0 deletions src/Apis/Notices/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NoticeWrite } from "./request";
import { useMutation } from "react-query";
import { instance } from "../axios";

export const useNoticeWriteData = (noticeData: NoticeWrite) => {
const formData = new FormData()
noticeData.attachments.forEach((attachment) => { formData.append('file', attachment) })

return useMutation(
async () => {
const { data } = await instance.post(`${process.env.REACT_APP_BASE_URL}/notices`, {...noticeData, attachments: formData});
return data;
},
{
onError: (error: Error) => {
console.error("공지 작성에 실패하였습니다:", error.message);
}
}
)
}

5 changes: 5 additions & 0 deletions src/Apis/Notices/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface NoticeWrite {
title: string;
content: string;
attachments: string[];
}
3 changes: 3 additions & 0 deletions src/Components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export function Header() {
지원서
</_.NavBtn>
</Link>
<Link to="/Notice">
<_.NavBtn clicked={clickedStatus('Notice')} width={68}>
공지
<Link to="/Banner">
<_.NavBtn clicked={clickedStatus('Banner')} width={68}>
배너
Expand Down
151 changes: 151 additions & 0 deletions src/Pages/NoticePage/NoticeEditPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { Header } from '../../../Components/Header';
import * as _ from './style';
import { ChangeEvent, useEffect, useRef, useState } from 'react';
import { Button } from '@team-return/design-system';
import { useNoticeWriteData } from '../../../Apis/Notices';
import axios from 'axios';
import { usePresignedUrl } from '../../../Apis/Files';
import { PresignedUrlRequest } from '../../../Apis/Files/request';
import { Link } from 'react-router-dom';

export function NoticeEditPage() {
const fileInputRef = useRef<HTMLInputElement>(null);
const [inputCount, setInputCount] = useState<number>(0);
const [title, setTitle] = useState<string>('');
const [content, setContent] = useState<string>('');
const [attachments, setAttachments] = useState<File[]>([]);
const [presignedUrls, setPresignedUrls] = useState<string[]>([]);

const { mutate: writeNotice } = useNoticeWriteData({
title,
content,
attachments: presignedUrls,
});

// const fileName = jsonData.files[0].file_name;

const { mutate: getPresignedUrl } = usePresignedUrl();
// const { mutate } = useUpload(attachments, { onSuccess: (e) => {} });

const getTodayDate = (): string => {
const today = new Date();
const year = today.getFullYear();
let month = (today.getMonth() + 1).toString();
let day = today.getDate().toString();

if (month.length === 1) {
month = '0' + month;
}
if (day.length === 1) {
day = '0' + day;
}

return `${year}-${month}-${day}`;
};

const handleAddFileClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};

const onInputHandler = (e: any) => {
setInputCount(e.target.value.length);
};

const handleTitleChange = (e: ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
console.log('제목:', e.target.value);
};

const handleContentChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setContent(e.target.value);
console.log('내용:', e.target.value);
};

let files_: any;

const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.files) {
const newAttachments = Array.from(e.target.files);
setAttachments((prevAttachments) => [
...prevAttachments,
...newAttachments,
]);

files_ = attachments.map((item) => ({
type: 'EXTENSION_FILE',
file_name: item.name,
}));

// const presignedUrls = await Promise.all(promises);

// // setPresignedUrls((prevPresignedUrls) => [
// // ...prevPresignedUrls,
// // ...presignedUrls,
// // ]);

// console.log('첨부파일: ', attachments, newAttachments);
}
};

const handleNoticeSubmit = () => {
// console.log(data);
// writeNotice();
getPresignedUrl(attachments);
};

return (
<>
<Header />
<_.Wrapper>
<_.Box>
<_.Title>공지 작성하기</_.Title>
<_.ContentWrap>
<_.WriteDateWrap>
<_.Text>작성일</_.Text>
<_.Text>{getTodayDate()}</_.Text>
</_.WriteDateWrap>
<_.TitleWrap>
<_.Text>제목</_.Text>
<_.Input placeholder="공지 제목을 입력하세요" />
</_.TitleWrap>
<_.TextWrap>
<_.Text>내용</_.Text>
<_.InputWrapper>
<_.TextInput
placeholder="공지 내용을 입력하세요"
maxLength={999}
value={content}
onChange={handleContentChange}
onInput={onInputHandler}
/>
<_.InputCount>{inputCount}자/1000</_.InputCount>
</_.InputWrapper>
</_.TextWrap>
<_.FileWrap>
<_.Text>첨부파일</_.Text>
<_.AddFile onClick={handleAddFileClick}>
파일 추가하기
</_.AddFile>
<input
type="file"
style={{ display: 'none' }}
ref={fileInputRef}
onChange={handleFileChange}
multiple={true}
/>
</_.FileWrap>
<_.ButtonWrap>
<Link to={'/Notice'}>
<Button onClick={handleNoticeSubmit}>
공지 등록하기
</Button>
</Link>
</_.ButtonWrap>
</_.ContentWrap>
</_.Box>
</_.Wrapper>
</>
);
}
Loading

0 comments on commit 4331c5e

Please sign in to comment.