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

feat: postFinalContent GET api 연결 및 조회 Modal 구현 #2

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
71 changes: 48 additions & 23 deletions src/containers/myPage/myPage.presenter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,37 @@ import React, { useEffect, useState } from 'react';
import * as S from "./myPage.style";
import * as C from "../createText/createText.style";
import useStore from "../../store/useStore";
import TextDetail from './textDetail.component';

const MyPageUI = () => {
import axios from 'axios';
const MyPageUI = ({ closeModal }) => {
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL;
const { goToHome } = useStore();
const userData = JSON.parse(localStorage.getItem('userdata')) || {};

const [posts, setPosts] = useState([]);
const [page, setPage] = useState(0);
const [totalPages, setTotalPages] = useState(1);
const [selectedPostId, setSelectedPostId] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);

// 날짜 형식 파싱
const formatDate = (dateString) => {
const date = new Date(dateString);
return `${date.getMonth() + 1}월 ${date.getDate()}일 (${date.toLocaleDateString('ko-KR', { weekday: 'short' })}) ${date.getHours()}시 ${date.getMinutes()}분`;
};
const [page, setPage] = useState(0); // 현재 페이지 상태
const [totalPages, setTotalPages] = useState(1); // 전체 페이지 수

// useState로 초기 상태 설정
const [businessName, setBusinessName] = useState("");
const [location, setLocation] = useState("");
const [address, setAddress] = useState("");
const [businessName, setBusinessName] = useState(userData.businessName || "");
const [location, setLocation] = useState(userData.location || "");
const [address, setAddress] = useState(userData.address || "");
useEffect(() => {
const fetchPosts = async () => {
try {
const accessToken = localStorage.getItem('accessToken');
if (!accessToken) {
console.error("accessToken 오류 발생");
return;
}

const response = await fetch(`${BACKEND_URL}/post/findAll?page=${page}&size=3`, {
method: "GET",
headers: {
Expand All @@ -48,19 +56,30 @@ const MyPageUI = ({ closeModal }) => {

fetchPosts();
}, [BACKEND_URL, page]);

// 날짜 형식 파싱
const formatDate = (dateString) => {
const date = new Date(dateString);
const options = { month: 'numeric', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' };
return `${date.getMonth() + 1}월 ${date.getDate()}일 (${date.toLocaleDateString('ko-KR', { weekday: 'short' })}) ${date.getHours()}시 ${date.getMinutes()}분`;
// 모달
const openModal = (postId) => {
setSelectedPostId(postId);
setIsModalOpen(true);
};

const handlePageChange = (newPage) => {
if (newPage >= 0 && newPage < totalPages) {
setPage(newPage);
}
const closeModal = () => {
setIsModalOpen(false);
setSelectedPostId(null);
};

// 날짜 형식 파싱
const formatDate = (dateString) => {
const date = new Date(dateString);
const options = { month: 'numeric', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' };
return `${date.getMonth() + 1}월 ${date.getDate()}일 (${date.toLocaleDateString('ko-KR', { weekday: 'short' })}) ${date.getHours()}시 ${date.getMinutes()}분`;
};

const handlePageChange = (newPage) => {
if (newPage >= 0 && newPage < totalPages) {
setPage(newPage);
}
};

const handleSubmit = () => {
// 페이지 변경 함수
const postData = async () => {
Expand Down Expand Up @@ -135,27 +154,33 @@ const MyPageUI = ({ closeModal }) => {
{posts.map((post) => (
<S.BeforeContent
key={post.postId}
onClick={() => console.log(`홍보글 ID: ${post.postId} 클릭됨`)}
onClick={() => openModal(post.postId)} // postId로 모달 열기
>
{formatDate(post.postDate)}
</S.BeforeContent>
))}
</S.TextGroup>
{/* 페이지네이션 */}
<S.Pagination>
{page > 0 && (
<S.PaginationBtn onClick={() => handlePageChange(page - 1)}>
<i className="bi bi-caret-left-fill" style={{ fontSize: "15px" }}></i>
<S.PaginationBtn onClick={() => setPage(page - 1)}>
이전
</S.PaginationBtn>
)}
<span>{page + 1} / {totalPages}</span>
{page < totalPages - 1 && (
<S.PaginationBtn onClick={() => handlePageChange(page + 1)}>
<i className="bi bi-caret-right-fill" style={{ fontSize: "15px" }}></i>
<S.PaginationBtn onClick={() => setPage(page + 1)}>
다음
</S.PaginationBtn>
)}
</S.Pagination>
</S.SubGroup>
</S.MainSection>
<TextDetail
isOpen={isModalOpen}
postId={selectedPostId}
closeModal={closeModal}
/>
</C.Wrapper>
);
};
Expand Down
17 changes: 17 additions & 0 deletions src/containers/myPage/myPage.style.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,21 @@ export const PaginationBtn = styled.button`
background: none;
`

// textDetail
export const IconGroup = styled.div`
display: flex;
gap: 15px;
font-size: 18px;
`

export const ViewText = styled.div`
background: gray;
width: 100%;
min-height: 50%;
margin-top: 10%;
padding: 5%;
font-size: 16px;
color: black;
font-weight: 500;
font-family: "Pretendard";
`
95 changes: 95 additions & 0 deletions src/containers/myPage/textDetail.component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useEffect, useState } from 'react';
import Modal from 'react-modal';
import * as S from "./myPage.style";

Modal.setAppElement('#root');

const TextDetail = ({ isOpen, postId, closeModal }) => {
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL;
const [postContent, setPostContent] = useState("");
const [copied, setCopied] = useState(false);

useEffect(() => {
if (postId && isOpen) {
const fetchPostContent = async () => {
try {
const accessToken = localStorage.getItem('accessToken');
const response = await fetch(`${BACKEND_URL}/post/findOne/${postId}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${accessToken}`,
},
});

if (response.ok) {
const data = await response.json();
setPostContent(data.postFinalContent); // 불러온 콘텐츠 설정
} else {
console.error("조회 실패 오류");
}
} catch (error) {
console.error("요청 오류:", error);
}
};
fetchPostContent();
}
}, [postId, isOpen, BACKEND_URL]);

// 클립보드 복사
const copyToClipboard = () => {
navigator.clipboard.writeText(postContent)
.then(() => {
setCopied(true);
setTimeout(() => setCopied(false), 2000); // 2초 후 원래 아이콘으로
})
.catch((error) => console.error("복사 실패:", error));
};

return (
<Modal
isOpen={isOpen}
onRequestClose={closeModal}
style={{
content: {
width: '100%',
height: '60vh',
position: 'fixed',
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-end',
top: '70%',
left: '50%',
transform: 'translate(-50%, -50%)',
background: '#ffffff',
borderTopLeftRadius: '20px',
borderTopRightRadius: '20px',
padding: '20px',
overflow: 'auto',
},
overlay: {
zIndex: '10',
backgroundColor: 'rgba(0, 0, 0, 0.6)',
},
}}
>
<S.IconGroup>
<i
className={copied ? "bi bi-clipboard-check-fill" : "bi bi-clipboard"}
onClick={copyToClipboard}
style={{ fontSize: "22px", cursor: "pointer" }}
></i>
<i
className="bi bi-x-lg"
onClick={closeModal}
style={{ fontSize: "22px", cursor: "pointer" }}
></i>
</S.IconGroup>
<S.ViewText style={{ whiteSpace: 'pre-wrap' }}>
{postContent}
</S.ViewText>
</Modal>
);
}

export default TextDetail;