-
{noticeText}
+
diff --git a/src/pages/Admin/RollingPaper.tsx b/src/pages/Admin/RollingPaper.tsx
index a855c2b..6feb8ff 100644
--- a/src/pages/Admin/RollingPaper.tsx
+++ b/src/pages/Admin/RollingPaper.tsx
@@ -1,14 +1,21 @@
+import { useQuery } from '@tanstack/react-query';
import { useState } from 'react';
-import { AddIcon, AlarmIcon, DeleteIcon } from '@/assets/icons';
+import { getRollingPaperList } from '@/apis/rolling';
+import { AddIcon, AlarmIcon } from '@/assets/icons';
import AddRollingPaperModal from './components/AddRollingPaperModal';
import PageTitle from './components/AdminPageTitle';
+import RollingPaperItem from './components/RollingPaperItem';
import WrapperFrame from './components/WrapperFrame';
import WrapperTitle from './components/WrapperTitle';
export default function AdminRollingPaper() {
const [activeModal, setActiveModal] = useState(false);
+ const { data, isLoading, isSuccess } = useQuery({
+ queryKey: ['admin-rolling-paper'],
+ queryFn: getRollingPaperList,
+ });
return (
<>
@@ -26,55 +33,32 @@ export default function AdminRollingPaper() {
롤링페이퍼 생성
-
-
-
- | ID |
- 제목 |
- 쌓인 편지 수 |
- 상태 |
- |
-
-
-
-
- | 1 |
-
- 침수 피해를 복구중인 포스코 임직원 분들에게 응원의 메시지를 보내주세요!
- |
- 12 |
-
-
- 진행 중
-
- |
- |
-
-
- | 2 |
-
- 침수 피해를 복구중인 포스코 임직원 분들에게 응원의 메시지를 보내주세요!
- |
- 12 |
-
-
- |
-
-
- |
-
-
-
+ {isLoading &&
Loading...
}
+ {isSuccess && (
+ <>
+
+
+
+ | ID |
+ 제목 |
+ 상태 |
+ |
+
+
+
+ {data.content.map((rollingPaper) => (
+
+ ))}
+
+
+ {data.content.length === 0 && (
+
+ 아직 생성된 롤링페이퍼가 없어요
+
+ )}
+ >
+ )}
+ {/* TODO: 페이지네이션 적용 */}
>
);
diff --git a/src/pages/Admin/components/AddRollingPaperModal.tsx b/src/pages/Admin/components/AddRollingPaperModal.tsx
index 2df17c3..0e336be 100644
--- a/src/pages/Admin/components/AddRollingPaperModal.tsx
+++ b/src/pages/Admin/components/AddRollingPaperModal.tsx
@@ -1,5 +1,7 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ChangeEvent, FormEvent, useState } from 'react';
+import { postNewRollingPaper } from '@/apis/rolling';
import ModalOverlay from '@/components/ModalOverlay';
interface AddRollingPaperModalProps {
@@ -9,6 +11,21 @@ interface AddRollingPaperModalProps {
export default function AddRollingPaperModal({ onClose }: AddRollingPaperModalProps) {
const [title, setTitle] = useState('');
const [error, setError] = useState('');
+ const queryClient = useQueryClient();
+
+ const { mutate } = useMutation({
+ mutationFn: () => postNewRollingPaper(title),
+ onSuccess: () => {
+ setTitle('');
+ setError('');
+ onClose();
+ // TODO: 페이지네이션 적용 후, 현재 page에 대한 캐싱 날리는 방식으로 변경
+ queryClient.invalidateQueries({ queryKey: ['admin-rolling-paper'] });
+ },
+ onError: () => {
+ setError('편지 작성에 실패했어요. 다시 시도해주세요.');
+ },
+ });
const handleChange = (e: ChangeEvent
) => {
setTitle(e.target.value);
@@ -21,7 +38,7 @@ export default function AddRollingPaperModal({ onClose }: AddRollingPaperModalPr
return;
}
- console.log(title);
+ mutate();
};
return (
diff --git a/src/pages/Admin/components/RollingPaperItem.tsx b/src/pages/Admin/components/RollingPaperItem.tsx
new file mode 100644
index 0000000..c4e0a18
--- /dev/null
+++ b/src/pages/Admin/components/RollingPaperItem.tsx
@@ -0,0 +1,76 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { AxiosError } from 'axios';
+
+import { deleteRollingPaper, patchRollingPaper } from '@/apis/rolling';
+import { DeleteIcon } from '@/assets/icons';
+
+interface RollingPaperItemProps {
+ information: AdminRollingPaperInformation;
+}
+
+export default function RollingPaperItem({ information }: RollingPaperItemProps) {
+ const queryClient = useQueryClient();
+
+ const { mutate: deleteMutate } = useMutation({
+ mutationFn: () => deleteRollingPaper(information.eventPostId),
+ onSuccess: () => {
+ // TODO: 페이지네이션 적용 후, 현재 page에 대한 캐싱 날리는 방식으로 변경
+ queryClient.invalidateQueries({ queryKey: ['admin-rolling-paper'] });
+ },
+ onError: (err) => {
+ console.error(err);
+ },
+ });
+
+ const { mutate: toggleStatus } = useMutation({
+ mutationFn: () => patchRollingPaper(information.eventPostId),
+ onSuccess: () => {
+ // TODO: 기존 데이터 수정하는 방식으로 ㄱㄱㄱㄱㄱㄱㄱ
+ // 일단 임시로 캐싱 날리기
+ queryClient.invalidateQueries({ queryKey: ['admin-rolling-paper'] });
+ },
+ onError: (err: AxiosError<{ code: string; message: string }>) => {
+ if (err.response?.data.code === 'EVENT-004') {
+ alert(err.response.data.message);
+ }
+ console.error(err);
+ },
+ });
+
+ // TODO: 진짜 삭제하겠냐고 물어보기
+ return (
+
+ | {information.eventPostId} |
+
+
+ {information.used && (
+
+ 진행 중
+
+ )}
+ {information.title}
+
+ |
+
+
+ |
+
+ {!information.used && (
+
+ )}
+ |
+
+ );
+}
diff --git a/src/pages/RollingPaper/components/CommentDetailModal.tsx b/src/pages/RollingPaper/components/CommentDetailModal.tsx
index 4769892..cbabb52 100644
--- a/src/pages/RollingPaper/components/CommentDetailModal.tsx
+++ b/src/pages/RollingPaper/components/CommentDetailModal.tsx
@@ -20,7 +20,7 @@ const CommentDetailModal = ({ comment, isWriter, onClose, onDelete }: CommentDet
-
{comment.content}
+
{comment.content}
From. {comment.zipCode}
diff --git a/src/pages/RollingPaper/index.tsx b/src/pages/RollingPaper/index.tsx
index 6bcc9e6..71b4d70 100644
--- a/src/pages/RollingPaper/index.tsx
+++ b/src/pages/RollingPaper/index.tsx
@@ -12,19 +12,17 @@ import Header from '@/layouts/Header';
import Comment from './components/Comment';
import CommentDetailModal from './components/CommentDetailModal';
import WriteCommentButton from './components/WriteCommentButton';
-
-// TODO: 로그인 구현 완료 시, 더미 완전히 제거
-const DUMMY_USER_ZIP_CODE = '1DR41';
-const DUMMY_MESSAGE_COUNT = 20;
+import useAuthStore from '@/stores/authStore';
const RollingPaperPage = () => {
const id = useParams().id ?? '';
const [activeComment, setActiveComment] = useState(null);
const [activeDetailModal, setActiveDetailModal] = useState(false);
const [activeDeleteModal, setActiveDeleteModal] = useState(false);
+ const zipCode = useAuthStore((props) => props.zipCode);
const queryClient = useQueryClient();
- const { data } = useQuery({
+ const { data, isSuccess } = useQuery({
queryKey: ['rolling-paper', id],
queryFn: () => getRollingPaperDetail(id),
});
@@ -37,9 +35,11 @@ const RollingPaperPage = () => {
return {
...oldData,
- eventPostComments: oldData.eventPostComments.filter(
- (comment: RollingPaperComment) => comment.commentId !== data.commentId,
- ),
+ eventPostComments: {
+ content: oldData.eventPostComments.content.filter(
+ (comment: RollingPaperComment) => comment.commentId !== data.commentId,
+ ),
+ },
};
});
@@ -56,7 +56,7 @@ const RollingPaperPage = () => {
{activeDetailModal && activeComment && (
{
setActiveDetailModal(false);
setActiveComment(null);
@@ -85,11 +85,13 @@ const RollingPaperPage = () => {
{data?.title}
- 등록된 편지 {DUMMY_MESSAGE_COUNT}
+
+ 등록된 편지 {data ? data.eventPostComments.content.length : 0}
+
- {data &&
- data.eventPostComments.map((comment) => (
+ {isSuccess &&
+ data.eventPostComments.content.map((comment) => (
{
/>
))}
+ {isSuccess && data.eventPostComments.content.length === 0 && (
+
+ 아직 등록된 편지가 없어요.
+
+ 첫번째로 편지를 남겨볼까요?
+
+ )}
diff --git a/src/styles/animations.css b/src/styles/animations.css
index 7217bbd..702eca7 100644
--- a/src/styles/animations.css
+++ b/src/styles/animations.css
@@ -6,7 +6,7 @@
--animate-rotate-show: rotate-show 1s ease-in-out forwards;
--animate-blink: showing 0.3s forwards;
--animate-login-move-up-down: move-up-down 3s ease-in-out infinite;
- --animate-marquee: marquee 10s linear infinite;
+ --animate-marquee: marquee var(--marquee-duration) linear infinite;
@keyframes down {
0% {
@@ -70,7 +70,7 @@
/* SpecialLetterBanner 애니메이션 */
@keyframes marquee {
0% {
- transform: translateX(10%);
+ transform: translateX(100%);
}
100% {
transform: translateX(-100%);
diff --git a/src/styles/preflight.css b/src/styles/preflight.css
index c74f27a..c23d658 100644
--- a/src/styles/preflight.css
+++ b/src/styles/preflight.css
@@ -4,6 +4,7 @@
:root {
--vh: 1vh;
--vw: 1vw;
+ --marquee-duration: 10s;
}
* {
diff --git a/src/types/rolling.d.ts b/src/types/rolling.d.ts
index af75fe6..d72c810 100644
--- a/src/types/rolling.d.ts
+++ b/src/types/rolling.d.ts
@@ -3,12 +3,26 @@ interface RollingPaperInformation {
title: string;
}
+interface AdminRollingPaperInformation extends RollingPaperInformation {
+ used: boolean;
+}
+
interface RollingPaperComment {
commentId: number;
zipCode: string;
content: string;
}
+interface PaginationData {
+ content: T[];
+ currentPage: number;
+ size: number;
+ totalElements: number;
+ totalPages: number;
+}
+
+interface RollingPaperList extends PaginationData {}
+
interface RollingPaper extends RollingPaperInformation {
- eventPostComments: RollingPaperComment[];
+ eventPostComments: PaginationData;
}