Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge :: 공지사항 api 연동 #59

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,712 changes: 1,463 additions & 4,249 deletions .pnp.cjs

Large diffs are not rendered by default.

6,921 changes: 6,921 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@next/font": "^13.5.2",
"@tanstack/react-query": "4.33.0",
"@team-return/design-system": "^1.1.15",
"aws-sdk": "^2.1582.0",
eejx0 marked this conversation as resolved.
Show resolved Hide resolved
"axios": "^1.6.2",
"debug": "^4.3.4",
"next": "13.4.7",
Expand Down
69 changes: 63 additions & 6 deletions src/apis/notice/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,67 @@
import { NoticeListResponse } from "./type";
import { NoticeDetailResponse } from "./type";
import { useState, useEffect } from "react";
import { instance } from "../axios";
import { useQuery } from "@tanstack/react-query";
import { useToastStore } from "@team-return/design-system";

export const useGetNoticeList = () => {
/** 공지사항 리스트를 조회하는 api 입니다 */
export const useGetNoticeListData = () => {
const [notices, setNotices] = useState<NoticeListResponse[]>([]);
const { append } = useToastStore();
useEffect(() => {
const fetchNoticeList = async () => {
try {
const { data } = await instance.get(`${process.env.NEXT_PUBLIC_BASE_URL}/notices`);
const fetchedNotices: NoticeListResponse[] = data.notices.map((notice: any) => ({
id: notice.id,
title: notice.title,
created_at: new Date(notice.created_at).toISOString()
}));
setNotices(fetchedNotices);
} catch (error: any) {
append({
title: "",
message: "공지사항 리스트 조회에 실패하였습니다.",
type: "RED",
});
}
};
Comment on lines +13 to +28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try catch 말고 then catch문으로 통일 합시다

fetchNoticeList();
}, []);

};
return { notices };
}


/** 공지사항 상세보기를 조회하는 api 입니다 */
export const useGetNoticeDetailData = (noticeId: string) => {
const { append } = useToastStore();
const fetchNoticeDetail = async () => {
const {data} = await instance.get(`${process.env.NEXT_PUBLIC_BASE_URL}/notices/${noticeId}`);

export const useGetNoticeDetail = () => {

};
return {
title: data.title,
content: data.content,
created_at: new Date(data.created_at).toISOString(),
attachments: data.attachments.map((attachment: any) => ({
url: attachment.url,
type: attachment.type
Comment on lines +42 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 그냥 data를 반환하면 안되나요? object로 한번 더 감싸는 이유가 무엇인가요?

}))
};
};

const { data: noticeDetail } = useQuery(['noticeDetail', noticeId], fetchNoticeDetail, {
onSuccess: () => {
console.log('공지사항 상세보기 성공');
},
onError: () => {
append({
title: "",
message: "공지사항 상세보기 조회에 실패하였습니다.",
type: "RED",
});
},
});

return { noticeDetail };
};
24 changes: 16 additions & 8 deletions src/apis/notice/type.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
export interface NoticeListResponse {
notices: {
notice_id: number;
title: string;
createAt: string;
}[];
};
id: number
title: string
created_at: string
}

export interface NoticeDetailResponse {
title: string;
content: string;
createAt: string;
attachments: string[];
created_at: string;
attachments: AttachmentResponse[];
}

type AttachmentType =
| "FILE"
| "URL"

export interface AttachmentResponse {
url: string;
type: AttachmentType;
id: string;
}
28 changes: 28 additions & 0 deletions src/app/mypage/notice/detail/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use client'

import { useGetNoticeDetailData, useGetNoticeListData } from "@/apis/notice";
import { useEffect, useState } from "react";
import AttachedBox from "@/components/notice/AttachedBox";

export default function NoticeDetailPage(props:any) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any 타입은 최대한 피해야 합니다. ts를 쓰는 이유가 없어져요.

const noticeId = props.params.id
const {noticeDetail} = useGetNoticeDetailData(noticeId);
// const items = [noticeDetail]

return (
<div className="flex justify-cent4er items-center mt-[100px]">
<div className="flex flex-col gap-[40px]">
<h1 className="text-[28px] font-[500] text-left">공지사항</h1>
<div className="w-[1151px] h-[494px] overflow-y-auto">
<div className="bg-white border-[1px] border-gray rounded-[12px] p-[40px]">
<h1 className="font-[700] text-[28px]">{noticeDetail?.title}</h1>
<h2 className="font-[500] text-[20px] mt-[20px]">{noticeDetail?.created_at.substring(0, 10)}</h2>
<p className="font-[400] text-[16px] mt-[28px] whitespace-pre-line">{noticeDetail?.content}</p>
<AttachedBox props={noticeDetail?.attachments || []} />
Copy link
Member

@KANGYONGSU23 KANGYONGSU23 Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticeDetail 비구조화 할당 합시다.

</div>
</div>
</div>
</div>
);
}

52 changes: 0 additions & 52 deletions src/app/mypage/notice/detail/page.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/app/mypage/notice/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Logo from "@/components/common/Logo"
import NoticeLists from "@/components/notice/NoticeLists"

export default function Notice () {
Expand Down
51 changes: 43 additions & 8 deletions src/components/notice/AttachedBox.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
export default function AttachedBox () {
'use client'

import { Icon } from "@team-return/design-system"
import { AttachmentResponse } from "@/apis/notice/type"
import { file_name_regex } from "@/util/regex";
import axios from "axios";

interface PropsType {
props: AttachmentResponse[]
}

export default function AttachedBox ({props}: PropsType) {
const downLoadFile = async (attachment: AttachmentResponse) => {
eejx0 marked this conversation as resolved.
Show resolved Hide resolved
try {
const response = await axios.get(`${process.env.NEXT_PUBLIC_IMAGE_URL}/${attachment.url}`, {
responseType: 'blob'
});

const url = window.URL.createObjectURL(new Blob([response.data]));
const a = document.createElement("a");
a.href = url;
a.download = file_name_regex(attachment.url);
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
} catch (error) {
console.error('파일 다운로드 에러: ', error);
}
}
Comment on lines +14 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 then catch


return (
<div className="flex flex-row w-full h-[108px] mt-[32px] border-t-[2px] border-b-[1px] border-[#135C9D] p-[16px] gap-[20px]">
<div className="font-[500] text-[18px] ">첨부자료</div>
<div className="flex flex-col gap-[4px] justify-center">
<div>2024학년도 신입생 과제.hwp</div>
<div>2024학년도 신입생 과제.hwp</div>
<div>2024학년도 신입생 과제.hwp</div>
<>
<div className="flex flex-row w-full h-auto mt-[32px] border-t-[2px] border-b-[1px] border-[#135C9D] p-[16px] gap-[20px]">
<div className="font-[500] text-[18px] ">첨부자료</div>
<div className="flex flex-col gap-[4px] justify-center ">
{props.map((attachment) => (
<div key={attachment.id} className="flex gap-[7px] items-center">
<div>{file_name_regex(attachment.url)}</div>
<Icon icon="Download" size={15} color="liteBlue" cursor="pointer" onClick={() => downLoadFile(attachment)} />
</div>
))}
</div>
</div>
</div>
</>
)
}
23 changes: 15 additions & 8 deletions src/components/notice/NoticeListTable.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
'use client'

import Link from "next/link"
import { useGetNoticeListData } from "@/apis/notice";

export default function NoticeListTable () {
const {notices} = useGetNoticeListData();

return (
<>
<Link href={"/mypage/notice/detail"}>
<tbody className="flex justify-center items-center border-collapse">
{notices.map((notice, index) => (
eejx0 marked this conversation as resolved.
Show resolved Hide resolved
<Link key={notice.id} href={`detail/${notice.id}`}>
<tbody className="flex justify-center items-center border-collapse">
<tr className="h-[60px] border-b-[0.5px] border-[#7F7F7F]">
<td className="border-none w-[192px] text-[16px] text-[#135C9D] flex justify-center">12</td>
<td className="border-none w-[735px] text-[16px] flex justify-center">[중요] 오리엔테이션날 일정 안내</td>
<td className="border-none w-[192px] text-[16px] flex justify-center">2024-01-16</td>
</tr>
</tbody>
</Link>
<td className="border-none w-[192px] text-[16px] text-[#135C9D] flex justify-center">{index+1}</td>
<td className="border-none w-[735px] text-[16px] flex justify-center">{notice.title}</td>
<td className="border-none w-[192px] text-[16px] flex justify-center">{notice.created_at.substring(0, 10)}</td>
</tr>
</tbody>
</Link>
))}
</>
)
}
6 changes: 2 additions & 4 deletions src/components/notice/NoticeLists.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use client'

import Pagination from "../common/Pagination"
import Link from "next/link";
import NoticeListTable from "./NoticeListTable";
import { useGetNoticeList } from "@/apis/notice";

export default function NoticeLists() {
return (
Expand All @@ -16,9 +17,6 @@ export default function NoticeLists() {
</thead>
<NoticeListTable />
</table>
<div className="mb-[98px]">
<Pagination />
</div>
</div>
)
}
Loading
Loading