diff --git a/FE/src/components/DiaryModal/DiaryAnalysisModal.js b/FE/src/components/DiaryModal/DiaryAnalysisModal.js index c10bfa1..be67e4f 100644 --- a/FE/src/components/DiaryModal/DiaryAnalysisModal.js +++ b/FE/src/components/DiaryModal/DiaryAnalysisModal.js @@ -30,6 +30,11 @@ function DiaryAnalysisModal() { left: 0, text: "", }); + const emotions = [ + { bg: "#618cf7", text: "긍정" }, + { bg: "#e5575b", text: "부정" }, + { bg: "#a848f6", text: "중립" }, + ]; async function getDataFn(data) { return fetch( @@ -250,39 +255,19 @@ function DiaryAnalysisModal() { text={false} /> - - - - 긍정 - - - - - - 부정 - - - - - - 중립 - - + {emotions.map((emotion, index) => ( + + + + {emotion.text} + + + ))} @@ -340,30 +325,17 @@ function DiaryAnalysisModal() { - {tagsRankData && tagsRankData?.first ? ( - - ) : null} - {tagsRankData && tagsRankData?.second ? ( - - ) : null} - {tagsRankData && tagsRankData?.third ? ( - - ) : null} + {tagsRankData && + ["first", "second", "third"].map((rank) => + tagsRankData[rank] ? ( + + ) : null, + )} ) : ( @@ -379,30 +351,17 @@ function DiaryAnalysisModal() { - {shapesRankData && shapesRankData?.first ? ( - - ) : null} - {shapesRankData && shapesRankData?.second ? ( - - ) : null} - {shapesRankData && shapesRankData?.third ? ( - - ) : null} + {shapesRankData && + ["first", "second", "third"].map((rank) => + shapesRankData[rank] ? ( + + ) : null, + )} ) : ( diff --git a/FE/src/components/DiaryModal/DiaryListModal.js b/FE/src/components/DiaryModal/DiaryListModal.js index 755df85..491ebe1 100644 --- a/FE/src/components/DiaryModal/DiaryListModal.js +++ b/FE/src/components/DiaryModal/DiaryListModal.js @@ -52,50 +52,54 @@ function DiaryListModal() { }, [selectedDiary]); useEffect(() => { - if (diaryState.diaryList) { - const filteredList = diaryState.diaryList - .filter((diary) => { - return ( - (!filterState.date.start && !filterState.date.end) || - (filterState.date.start && - filterState.date.end && - new Date(diary.date) >= filterState.date.start && - new Date(diary.date) <= filterState.date.end) || - (filterState.date.start && - !filterState.date.end && - new Date(diary.date) >= filterState.date.start) || - (filterState.date.end && - !filterState.date.start && - new Date(diary.date) <= filterState.date.end) - ); - }) - .filter((diary) => { - return ( - (!filterState.emotion.positive && - !filterState.emotion.neutral && - !filterState.emotion.negative) || - (filterState.emotion.positive && - diary.emotion.sentiment === "positive") || - (filterState.emotion.neutral && - diary.emotion.sentiment === "neutral") || - (filterState.emotion.negative && - diary.emotion.sentiment === "negative") - ); - }) - .filter((diary) => { - return ( - filterState.shape.length === 0 || - filterState.shape.includes(diary.shapeUuid) - ); - }) - .filter((diary) => { - return ( - filterState.tag.length === 0 || - filterState.tag.every((tag) => diary.tags.includes(tag)) - ); - }); - setFilteredDiaryList([...filteredList]); - } + if (!diaryState.diaryList) return; + + const isDateInRange = (diaryDate) => { + const startDateCondition = + !filterState.date.start || + new Date(diaryDate) >= filterState.date.start; + + const endDateCondition = + !filterState.date.end || new Date(diaryDate) <= filterState.date.end; + + return startDateCondition && endDateCondition; + }; + + const isEmotionMatch = (diaryEmotion) => { + const { positive, neutral, negative } = filterState.emotion; + + return ( + (!positive && !neutral && !negative) || + (positive && diaryEmotion === "positive") || + (neutral && diaryEmotion === "neutral") || + (negative && diaryEmotion === "negative") + ); + }; + + const isShapeMatch = (diaryShapeUuid) => { + return ( + filterState.shape.length === 0 || + filterState.shape.includes(diaryShapeUuid) + ); + }; + + const areTagsMatch = (diaryTags) => { + return ( + filterState.tag.length === 0 || + filterState.tag.every((tag) => diaryTags.includes(tag)) + ); + }; + + const filteredList = diaryState.diaryList.filter((diary) => { + const isDateValid = isDateInRange(diary.date); + const isEmotionValid = isEmotionMatch(diary.emotion.sentiment); + const isShapeValid = isShapeMatch(diary.shapeUuid); + const areTagsValid = areTagsMatch(diary.tags); + + return isDateValid && isEmotionValid && isShapeValid && areTagsValid; + }); + + setFilteredDiaryList([...filteredList]); }, [ filterState.date, filterState.emotion, @@ -103,6 +107,22 @@ function DiaryListModal() { filterState.tag, ]); + const toggleEmotionFilter = (emotionType) => { + setFilterState((prev) => ({ + ...prev, + emotion: { + ...prev.emotion, + [emotionType]: !prev.emotion[emotionType], + }, + })); + }; + + const emotionButtons = [ + { type: "positive", borderColor: "#00ccff", text: "긍정" }, + { type: "neutral", borderColor: "#ba55d3", text: "중립" }, + { type: "negative", borderColor: "#d1180b", text: "부정" }, + ]; + return ( @@ -154,51 +174,16 @@ function DiaryListModal() { 감정 - { - setFilterState((prev) => ({ - ...prev, - emotion: { - ...prev.emotion, - positive: !prev.emotion.positive, - }, - })); - }} - > - 긍정 - - { - setFilterState((prev) => ({ - ...prev, - emotion: { - ...prev.emotion, - neutral: !prev.emotion.neutral, - }, - })); - }} - > - 중립 - - { - setFilterState((prev) => ({ - ...prev, - emotion: { - ...prev.emotion, - negative: !prev.emotion.negative, - }, - })); - }} - > - 부정 - + {emotionButtons.map(({ type, borderColor, text }) => ( + toggleEmotionFilter(type)} + > + {text} + + ))} diff --git a/FE/src/components/PurchaseModal/PurchaseModal.js b/FE/src/components/PurchaseModal/PurchaseModal.js index 6b9d327..7b55492 100644 --- a/FE/src/components/PurchaseModal/PurchaseModal.js +++ b/FE/src/components/PurchaseModal/PurchaseModal.js @@ -12,6 +12,50 @@ import fourStar from "../../assets/fourstar.svg"; import diaryAtom from "../../atoms/diaryAtom"; import handleResponse from "../../utils/handleResponse"; +function PurchaseButtonComponent(props) { + const { + onClick = () => { + alert("준비 중인 서비스입니다."); + }, + text, + price, + } = props; + + return ( + + {text} + {price} 별가루 + + ); +} + +function ExchangeButtonComponent(props) { + const { + onClick = () => { + alert("준비 중인 서비스입니다."); + }, + icon, + width, + star, + bonus, + price, + } = props; + + return ( + + + + 별가루 + {star} + {bonus && ( + + {bonus} + )} + + ₩ {price} + + ); +} + function PurchaseModal(props) { const { premiumRefetch } = props; const [userState, setUserState] = useRecoilState(userAtom); @@ -47,6 +91,31 @@ function PurchaseModal(props) { ), ); + const exchangeButtons = [ + { icon: oneStar, width: "5rem", star: "100", price: "1000" }, + { + icon: twoStar, + width: "4.5rem", + star: "300", + bonus: "120", + price: "5000", + }, + { + icon: threeStar, + width: "4rem", + star: "1000", + bonus: "500", + price: "10000", + }, + { + icon: fourStar, + width: "10rem", + star: "2000", + bonus: "1000", + price: "20000", + }, + ]; + const { mutate: purchase } = useMutation((data) => { if (data.credit > creditData.credit) { alert("별가루가 부족합니다."); @@ -107,23 +176,11 @@ function PurchaseModal(props) { - { - alert("준비 중인 서비스입니다."); - }} - > - 땅 스킨 구매 - 100 별가루 - - { - alert("준비 중인 서비스입니다."); - }} - > - 모양 슬롯 확장 - 100 별가루 - - + + { purchase({ credit: 350, @@ -131,18 +188,8 @@ function PurchaseModal(props) { accessToken: userState.accessToken, }); }} - > - 광고 제거 - 350 별가루 - - { - alert("준비 중인 서비스입니다."); - }} - > - 별숲 후원 - 30000 별가루 - + /> + @@ -156,57 +203,17 @@ function PurchaseModal(props) { - { - alert("준비 중인 서비스입니다."); - }} - > - - - 별가루 - 100 - - ₩ 1000 - - { - alert("준비 중인 서비스입니다."); - }} - > - - - 별가루 - 300 - + 120 - - ₩ 5000 - - { - alert("준비 중인 서비스입니다."); - }} - > - - - 별가루 - 1000 - + 300 - - ₩ 10000 - - { - alert("준비 중인 서비스입니다."); - }} - > - - - 별가루 - 2000 - + 1000 - - ₩ 20000 - + {exchangeButtons.map((button, index) => ( + + ))} { + setHeaderState((prev) => ({ + ...prev, + isSideBar: false, + })); + onClick(); + }} + > + {text} + + ); +} + function SideBar() { const setDiaryState = useSetRecoilState(diaryAtom); const setHeaderState = useSetRecoilState(headerAtom); const [userState, setUserState] = useRecoilState(userAtom); const setStarState = useSetRecoilState(starAtom); + const sideBarList = [ + { + text: "나의 별숲", + onClick: () => { + setDiaryState((prev) => ({ + ...prev, + isRead: false, + isList: false, + isAnalysis: false, + isPurchase: false, + })); + }, + }, + { + text: "별숲 목록", + onClick: () => { + setDiaryState((prev) => ({ + ...prev, + isCreate: false, + isRead: false, + isUpdate: false, + isList: true, + isAnalysis: false, + isPurchase: false, + })); + setStarState((prev) => ({ + ...prev, + mode: "create", + })); + }, + }, + { + text: "별숲 현황", + onClick: () => { + setDiaryState((prev) => ({ + ...prev, + isCreate: false, + isRead: false, + isUpdate: false, + isList: false, + isAnalysis: true, + isPurchase: false, + })); + setStarState((prev) => ({ + ...prev, + mode: "create", + })); + }, + }, + { + text: "별숲 상점", + onClick: () => { + setDiaryState((prev) => ({ + ...prev, + isCreate: false, + isRead: false, + isUpdate: false, + isList: false, + isAnalysis: false, + isPurchase: true, + })); + setStarState((prev) => ({ + ...prev, + mode: "create", + })); + }, + }, + { + text: "도움말", + onClick: () => { + window.open( + "https://byeolsoop.notion.site/551e1070f73a405badb8aeb178dac192?pvs=4", + "_blank", + ); + }, + }, + ]; return ( - { - setHeaderState((prev) => ({ - ...prev, - isSideBar: false, - })); - setDiaryState((prev) => ({ - ...prev, - isRead: false, - isList: false, - isAnalysis: false, - isPurchase: false, - })); - }} - > - 나의 별숲 - - { - setHeaderState((prev) => ({ - ...prev, - isSideBar: false, - })); - setDiaryState((prev) => ({ - ...prev, - isCreate: false, - isRead: false, - isUpdate: false, - isList: true, - isAnalysis: false, - isPurchase: false, - })); - setStarState((prev) => ({ - ...prev, - mode: "create", - })); - }} - > - 별숲 목록 - - { - setHeaderState((prev) => ({ - ...prev, - isSideBar: false, - })); - setDiaryState((prev) => ({ - ...prev, - isCreate: false, - isRead: false, - isUpdate: false, - isList: false, - isAnalysis: true, - isPurchase: false, - })); - setStarState((prev) => ({ - ...prev, - mode: "create", - })); - }} - > - 별숲 현황 - - { - setHeaderState((prev) => ({ - ...prev, - isSideBar: false, - })); - setDiaryState((prev) => ({ - ...prev, - isCreate: false, - isRead: false, - isUpdate: false, - isList: false, - isAnalysis: false, - isPurchase: true, - })); - setStarState((prev) => ({ - ...prev, - mode: "create", - })); - }} - > - 별숲 상점 - - - window.open( - "https://byeolsoop.notion.site/551e1070f73a405badb8aeb178dac192?pvs=4", - "_blank", - ) - } - > - 도움말 - + {sideBarList.map((item) => ( + + ))} { diff --git a/FE/src/components/SignUpModal/SignUpModal.js b/FE/src/components/SignUpModal/SignUpModal.js index 13264c7..2fd1e9d 100644 --- a/FE/src/components/SignUpModal/SignUpModal.js +++ b/FE/src/components/SignUpModal/SignUpModal.js @@ -10,6 +10,16 @@ import ModalInputBox from "../../styles/Modal/ModalInputBox"; import ModalBackground from "../ModalBackground/ModalBackground"; import SignUpRuleGuide from "./SignUpRuleGuide"; +function SignUpModalInputComponent(props) { + const { title, type, onChange } = props; + return ( + + {title} + + + ); +} + function SignUpModal() { const setHeaderState = useSetRecoilState(headerAtom); const [email, setEmail] = useState(""); @@ -18,6 +28,43 @@ function SignUpModal() { const [password, setPassword] = useState(""); const [passwordCheck, setPasswordCheck] = useState(""); const errorRef = useRef(); + const signUpInputList = [ + { + title: "* 아이디", + type: "text", + onChange: (e) => { + setUserId(e.target.value); + }, + }, + { + title: "* 비밀번호", + type: "password", + onChange: (e) => { + setPassword(e.target.value); + }, + }, + { + title: "* 비밀번호 확인", + type: "password", + onChange: (e) => { + setPasswordCheck(e.target.value); + }, + }, + { + title: "* 이메일", + type: "email", + onChange: (e) => { + setEmail(e.target.value); + }, + }, + { + title: "* 닉네임", + type: "text", + onChange: (e) => { + setNickname(e.target.value); + }, + }, + ]; const { mutate: signUp } = useMutation(() => { fetch(`${process.env.REACT_APP_BACKEND_URL}/auth/signup`, { @@ -106,56 +153,13 @@ function SignUpModal() { 당신의 이야기를 펼쳐보세요! - - * 아이디 - { - setUserId(e.target.value); - }} - /> - - - * 비밀번호 - { - setPassword(e.target.value); - }} - /> - - - * 비밀번호 확인 - { - setPasswordCheck(e.target.value); - }} - /> - - - * 이메일 - { - setEmail(e.target.value); - }} - /> - - - * 닉네임 - { - setNickname(e.target.value); - }} + {signUpInputList.map((input) => ( + - + ))}
diff --git a/FE/src/styles/Modal/ModalInputBox.js b/FE/src/styles/Modal/ModalInputBox.js index d679ca6..660fd75 100644 --- a/FE/src/styles/Modal/ModalInputBox.js +++ b/FE/src/styles/Modal/ModalInputBox.js @@ -2,7 +2,7 @@ import styled from "styled-components"; const ModalInputBox = styled.input` width: 100%; - height: ${(props) => props.height || "3.5rem"}; + height: 3.1rem; border-radius: 0.2rem; border: 1px solid #ffffff; background-color: transparent;