From 9a23430481eec2d6832c50e73ab484cc6e00ddf0 Mon Sep 17 00:00:00 2001 From: aha-rin Date: Mon, 3 Feb 2025 00:25:28 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AC=B8=EC=9D=98=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Router.js | 5 +- src/components/common/Accordion.jsx | 57 ++++++++ src/components/common/AccordionTable.jsx | 94 +++++++++++++ src/components/common/ReviewForm.jsx | 5 +- src/components/common/StarRating.jsx | 1 - src/pages/MyPage/MyReviewPage.jsx | 6 +- .../InquiryPage.jsx} | 9 +- src/pages/Support/MyInquiryPage.jsx | 64 +++++++++ src/pages/Support/QnA.jsx | 127 ++++++++++++++++++ src/pages/Support/SupportPage.jsx | 59 ++++++++ 10 files changed, 413 insertions(+), 14 deletions(-) create mode 100644 src/components/common/Accordion.jsx create mode 100644 src/components/common/AccordionTable.jsx rename src/pages/{SupportPage.jsx => Support/InquiryPage.jsx} (96%) create mode 100644 src/pages/Support/MyInquiryPage.jsx create mode 100644 src/pages/Support/QnA.jsx create mode 100644 src/pages/Support/SupportPage.jsx diff --git a/src/Router.js b/src/Router.js index 1009a7d..01111f2 100644 --- a/src/Router.js +++ b/src/Router.js @@ -9,7 +9,8 @@ import React from 'react'; import MyStatusPage from './pages/MyPage/MyStatusPage'; import MyResume from './pages/MyResume/MyResume'; import SignUpPage from './pages/SignUpPage'; -import SupportPage from "./pages/SupportPage"; +import MyReviewPage from "./pages/MyPage/MyReviewPage"; +import SupportPage from './pages/Support/SupportPage'; const AppRouter = () => { return ( @@ -24,6 +25,8 @@ const AppRouter = () => { } /> } /> } /> + } /> + } /> ); }; diff --git a/src/components/common/Accordion.jsx b/src/components/common/Accordion.jsx new file mode 100644 index 0000000..59b3c9b --- /dev/null +++ b/src/components/common/Accordion.jsx @@ -0,0 +1,57 @@ +import React from "react"; +import styled from "styled-components"; +import { IoIosArrowDown } from "react-icons/io"; + +const Accordion = ({ title, children, isOpen, onToggle }) => { + return ( + + +
Q.

{title}

+ +
+ {isOpen && {children}} +
+ ); +}; + +export default Accordion; + +const AccordionContainer = styled.div` + border-bottom: 1px solid #ddd; + font-size: 16px; + + &:first-of-type { + border-top: 1px solid #ddd; /* 첫 번째 박스만 위쪽 선 표시 */ + } +`; + +const AccordionHeader = styled.div` + background-color: #ffffff; + padding: 22px 15px; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + color: #000000; + + div { + display: flex; + gap: 8px; + } + + span { + font-weight: 600; + color: ${(props) => (props.isOpen ? "#D90000" : "#000000")}; + } +`; + +const Arrow = styled.span` + transform: rotate(${(props) => (props.isOpen ? "180deg" : "0deg")}); + transition: transform 0.3s ease; +`; + +const AccordionContent = styled.div` + padding: 22px 42px; + background-color: #f9f9f9; + border-top: 1px solid #ddd; +`; \ No newline at end of file diff --git a/src/components/common/AccordionTable.jsx b/src/components/common/AccordionTable.jsx new file mode 100644 index 0000000..28888a6 --- /dev/null +++ b/src/components/common/AccordionTable.jsx @@ -0,0 +1,94 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; + +const AccordionTable = ({ data }) => { + const [openIndex, setOpenIndex] = useState(null); // 열려 있는 행의 인덱스 + + const toggleAccordion = (index) => { + const selectedItem = data[index]; + if (!selectedItem.response) { + // 답변이 없는 경우 alert 창 표시 + alert('문의 답변은 2-3일 정도 소요됩니다. 조금만 기다려 주세요!'); + return; + } + // 답변이 있는 경우 아코디언 열기 + setOpenIndex(openIndex === index ? null : index); + }; + + return ( + + + + + + + + + + + + + {data.map((item, index) => ( + + toggleAccordion(index)}> + + + + + + + {openIndex === index && ( + + + + )} + + ))} + +
문의일문의 유형문의 제목처리 상태답변일
{item.date}{item.type}{item.title}{item.status}{item.answerDate !== '-' ? item.answerDate : '-'}
+ {item.response} +
+
+ ); +}; + + +export default AccordionTable; + +const TableContainer = styled.div` + width: 100%; + overflow-x: auto; +`; + +const Table = styled.table` + width: 100%; + border-collapse: collapse; + margin: 5px 0; + font-size: 16px; + + th, + td { + border: 1px solid #ddd; + text-align: left; + padding: 8px; + } + + th { + background-color: #f4f4f4; + } + + tr { + cursor: pointer; + } + + tr:hover { + background-color: #f9f9f9; + } +`; + +const AccordionContent = styled.div` + padding: 10px; + background-color: #f9f9f9; + border: 1px solid #ddd; + border-radius: 5px; +`; \ No newline at end of file diff --git a/src/components/common/ReviewForm.jsx b/src/components/common/ReviewForm.jsx index b818703..9e20f4e 100644 --- a/src/components/common/ReviewForm.jsx +++ b/src/components/common/ReviewForm.jsx @@ -1,11 +1,9 @@ -/* eslint-disable */ import React, { useState, useEffect } from "react"; import styled from "styled-components"; import StarRating from "./StarRating"; import { useReviewInfo } from "../../contexts/useReviewInfo"; const ReviewForm = ({ onClose, initialData }) => { - const [review, setReview] = useState(initialData || {}); const [starPoint, setStarPoint] = useState(0); const [content, setContent] = useState(""); const [reviewCount,setReviewCount]=useState(1); @@ -13,7 +11,7 @@ const ReviewForm = ({ onClose, initialData }) => { const [selectedStore, setSelectedStore] = useState(""); const [selectedAlba, setSelectedAlba] = useState(""); const [selectedTag, setSelectedTag] = useState([]); - const [reviewTag, setReviewTag] = useState([ + const reviewTag = useState([ "일을 잘해요", "시간 엄수를 잘해요", "일이 서툴러요", @@ -35,7 +33,6 @@ const ReviewForm = ({ onClose, initialData }) => { useEffect(() => { if (initialData) { - setReview(initialData); setStarPoint(initialData.starPoint || 0); setContent(initialData.content || ""); setReviewCount(initialData.reviewCount||1); diff --git a/src/components/common/StarRating.jsx b/src/components/common/StarRating.jsx index a715d1b..2d4189f 100644 --- a/src/components/common/StarRating.jsx +++ b/src/components/common/StarRating.jsx @@ -1,4 +1,3 @@ -/*eslint-disable*/ import React, { useState } from "react"; import styled from "styled-components"; diff --git a/src/pages/MyPage/MyReviewPage.jsx b/src/pages/MyPage/MyReviewPage.jsx index 88bab9d..652fd11 100644 --- a/src/pages/MyPage/MyReviewPage.jsx +++ b/src/pages/MyPage/MyReviewPage.jsx @@ -4,6 +4,7 @@ import { useReviewInfo } from '../../contexts/useReviewInfo'; import styled from "styled-components"; import logo from "../../assets/images/logo.png"; import ReviewForm from '../../components/common/ReviewForm'; +import MypageLayout from '../../components/layout/MypageLayout'; const MyReviewPage = () => { const { reviews,editReview,deleteReview,reportReview,getReviewsByName } = useReviewInfo(); @@ -66,7 +67,7 @@ const MyReviewPage = () => { }; return ( -
+

리뷰 관리

@@ -172,7 +173,7 @@ const MyReviewPage = () => { )} -
+ ); }; @@ -329,6 +330,7 @@ const ButtonContainer = styled.div` `; const CancelButton = styled.button` + color:white; background-color: #5c3a32; padding: 5px 15px; border: none; diff --git a/src/pages/SupportPage.jsx b/src/pages/Support/InquiryPage.jsx similarity index 96% rename from src/pages/SupportPage.jsx rename to src/pages/Support/InquiryPage.jsx index 06a778a..06797a1 100644 --- a/src/pages/SupportPage.jsx +++ b/src/pages/Support/InquiryPage.jsx @@ -1,8 +1,8 @@ import React,{useState} from "react"; import styled from "styled-components"; -import Dropdown from "../components/common/DropDown"; +import Dropdown from "../../components/common/DropDown"; -const SupportPage=()=>{ +const Inquiry=()=>{ const [DDOpen1,setDDOpen1]=useState(false); const [DDOpen2,setDDOpen2]=useState(false); const [inqType1, setInqType1] = useState("선택해주세요"); @@ -115,7 +115,7 @@ const SupportPage=()=>{ ); }; -export default SupportPage; +export default Inquiry; const Container = styled.div` padding: 50px 100px; @@ -131,9 +131,7 @@ const CenterWrapper = styled.div` const SupportText = styled.div` font-size: 16px; color: grey; - letter-spacing: 1px; line-height: 30px; - margin: 0 auto; margin-top: 30px; `; @@ -166,7 +164,6 @@ const FormArea = styled.div` flex-direction: column; gap: 15px; margin: 20px 0; - margin-left:50px; `; const InputForm = styled.input` diff --git a/src/pages/Support/MyInquiryPage.jsx b/src/pages/Support/MyInquiryPage.jsx new file mode 100644 index 0000000..2a3b451 --- /dev/null +++ b/src/pages/Support/MyInquiryPage.jsx @@ -0,0 +1,64 @@ +import React from 'react'; +import styled from 'styled-components'; +import AccordionTable from '../../components/common/AccordionTable'; + +// 테스트 데이터 +const testData = [ + { + date: '2024.10.15', + type: '회원가입', + title: '계정을 여러 개 생성하고 싶은데 가능한가요?', + status: '처리중', + answerDate: '-', + response: null, // 답변 없음 + }, + { + date: '2024.10.15', + type: '리뷰', + title: '저에게 작성된 리뷰 중 삭제하고 싶은 게 있어요', + status: '답변완료', + answerDate: '2024.10.18', + response: '문의해주신 리뷰 삭제 요청은 처리 완료되었습니다. 추가 문의 사항이 있으시면 말씀해주세요.', + }, +]; + + +const MyInquiries = () => { + return ( + + 나의 문의 내역 + +
    +
  • 처리상태가 처리중인 경우 상담원이 고객님의 문의 접수 후 처리중인 상태입니다.
  • +
  • 답변이 완료되면 고객님의 이메일로 알림이 전송됩니다.
  • +
+
+ +
+

총 {testData.length}건

+ +
+
+ ); +}; + +export default MyInquiries; + +const Container = styled.div` + padding-top: 40px; + h3 { + font-size: 16px; + padding-left: 4px; + } +` + +const Title = styled.h2` + font-size: 24px; + margin-bottom: 8px; +` + +const Description = styled.div` + padding-left: 18px; + color: #898989; + margin-bottom: 30px; +` \ No newline at end of file diff --git a/src/pages/Support/QnA.jsx b/src/pages/Support/QnA.jsx new file mode 100644 index 0000000..d8a4d58 --- /dev/null +++ b/src/pages/Support/QnA.jsx @@ -0,0 +1,127 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import Accordion from "../../components/common/Accordion"; + +const QnA = () => { + const [currentType, setCurrentType] = useState("개인"); // 개인/기업 선택 상태 + const [openIndex, setOpenIndex] = useState(null); // 열려 있는 아코디언의 인덱스 + + // 더미 데이터 + const personalData = [ + { id: 1, title: "개인 문의 1", content: "이것은 개인 문의 1의 내용입니다." }, + { id: 2, title: "개인 문의 2", content: "이것은 개인 문의 2의 내용입니다." }, + { id: 3, title: "개인 문의 3", content: "이것은 개인 문의 3의 내용입니다." }, + ]; + + const businessData = [ + { id: 1, title: "기업 문의 1", content: "이것은 기업 문의 1의 내용입니다." }, + { id: 2, title: "기업 문의 2", content: "이것은 기업 문의 2의 내용입니다." }, + { id: 3, title: "기업 문의 3", content: "이것은 기업 문의 3의 내용입니다." }, + ]; + + const currentData = currentType === "개인" ? personalData : businessData; + + // 데이터 전환 시 아코디언 상태 초기화 + const handleTypeChange = (type) => { + setCurrentType(type); + setOpenIndex(null); // 열려 있는 아코디언 닫기 + }; + + return ( + +
+ 자주 묻는 질문 + + + + +
+ + 찾으시는 Q&A가 없거나 준비된 답변이 만족스럽지 않으시다면, 문의 작성으로 더욱 자세히 도와드리겠습니다. + + + + {currentData.map((item, index) => ( + setOpenIndex(openIndex === index ? null : index)} + > + {item.content} + + ))} + +
+ ); +}; + +export default QnA; + + +const Container = styled.div` + padding-top: 40px; + + h3 { + font-size: 16px; + padding-left: 4px; + } +` + +const Header = styled.div` + display: flex; + justify-content: space-between; +` + +const Title = styled.h2` + font-size: 24px; +` + +const UserType = styled.div` + width: fit-content; + + button { + padding: 10px 20px; + background-color: #EFEFEF; + cursor: pointer; + font-size: 14px; + + &:disabled { + background-color: #6E3C3B; + color: #ffffff; + } + } + + #personalButton { + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + } + + #businessButton { + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; + } +`; + +const Description = styled.div` + color: #898989; + margin-bottom: 30px; + padding-left: 4px; + padding-top: 5px; +` + +const QnAList = styled.div` + margin-top: 20px; +`; \ No newline at end of file diff --git a/src/pages/Support/SupportPage.jsx b/src/pages/Support/SupportPage.jsx new file mode 100644 index 0000000..99cb926 --- /dev/null +++ b/src/pages/Support/SupportPage.jsx @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import Inquiry from './InquiryPage'; +import MyInquiries from './MyInquiryPage'; +import QnA from './QnA'; + +const SupportPage = () => { + const [currentPage, setCurrentPage] = useState('문의'); + + return ( + + + setCurrentPage('문의')}>문의 + setCurrentPage('나의 문의 내역')}>나의 문의 내역 + setCurrentPage('Q&A')}>Q&A + + + + {currentPage === '문의' && } + {currentPage === '나의 문의 내역' && } + {currentPage === 'Q&A' && } + + + ); +}; + +export default SupportPage; + +const Container = styled.div` + height: 100vh; +` + +const NavbarContainer = styled.div` + display: flex; + border-bottom: 1px solid #DFDFDF; + padding-left: 150px; +`; + +const NavItem = styled.div` + padding: 15px 20px 10px; + cursor: pointer; + transition: background-color 0.3s; + ${(props) => props.active && ` + border-bottom: 2px solid #7B4B42; + font-weight: bold; + background-color: #f0f0f0; + `} + + &:hover { + background-color: #f0f0f0; + } +`; + +const Content = styled.div` + background-color: #ffffff; + height: 100vh; + padding: 20px 150px; + border-top: 1px solid #DFDFDF; +`; \ No newline at end of file