Skip to content

Commit

Permalink
Merge pull request #184 from KDT-hahahoho/Feat/#183
Browse files Browse the repository at this point in the history
Feat/#183
  • Loading branch information
woojoung1217 authored Nov 20, 2024
2 parents 8dfaa8d + cb8c33e commit 4ab3df0
Show file tree
Hide file tree
Showing 13 changed files with 446 additions and 173 deletions.
2 changes: 1 addition & 1 deletion src/components/common/PageTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const PageTitle = ({
& h2 {
line-height: 4rem;
font-size: ${variables.size.large};
font-weight: 500;
font-weight: 700;
flex-grow: 1;
text-align: ${textAlign};
${pageBack && ` margin-right: 5rem;`}
Expand Down
99 changes: 62 additions & 37 deletions src/components/home/CoupleInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,50 +42,77 @@ const CoupleInformation = ({ coupleData }: OurReportProps) => {
const navigate = useNavigate();
const [selfMessage, setSelfMessage] = useState('');
const [mission, setMission] = useState('');
const [isMissionDone, setIsMissionDone] = useState(false); // 체크박스 상태
// isMissionDone 초기값을 서버 데이터와 동기화
const [isMissionDone, setIsMissionDone] = useState(false);
const { partnerName, myName, gender, isConnected } = useCoupleInfo();
const myMissionCompleted = coupleData?.result?.my_emotion?.is_complement || false;
const spouseMissionCompleted = coupleData?.result?.spouse_emotion?.is_complement || false;
const spouseExportMessage = coupleData?.result?.spouse_emotion?.export_message || '';

const getMissionStatusMessage = () => {
if (myMissionCompleted && spouseMissionCompleted) {
return spouseExportMessage;
return spouseExportMessage || '배우자의 메시지가 없습니다';
} else if (myMissionCompleted) {
return '배우자 미션 수행 대기중';
} else {
return '미션을 수행하면 배우자의 한마디를 볼 수 있어요';
}
};

const [prevEmotionId, setPrevEmotionId] = useState<number | null>(null);

useEffect(() => {
const emotion = coupleData?.result?.my_emotion;
const currentEmotionId = emotion?.id;

// 이전 이모션 ID와 현재 이모션 ID가 다르면 새로운 미션으로 간주
if (currentEmotionId && prevEmotionId !== currentEmotionId) {
setSelfMessage(emotion?.self_message || '');
setMission(emotion?.mission_content || '');
setIsMissionDone(false); // 새로운 미션이므로 미션 수행 여부 초기화
setPrevEmotionId(currentEmotionId); // 현재 이모션 ID 저장
} else if (!currentEmotionId) {
// 이모션이 없는 경우 초기화
setSelfMessage('');
setMission('');
setIsMissionDone(false);
setPrevEmotionId(null);
}
}, [coupleData?.result?.my_emotion?.id, prevEmotionId]);

/** 미션 수행 등록 함수 {PUT} */
const handleMissionToggle = async () => {
try {
setIsMissionDone(!isMissionDone);
if (coupleData?.result?.my_emotion) {
const result_id = coupleData.result.my_emotion.id;

const requestData = {
is_complement: true,
};

const response = await axios.put(`https://www.wishkr.site/emotions/results/${result_id}/`, requestData, {
headers: {
'Content-Type': 'application/json',
},
});
console.log('요청 성공:', response.data);
if (!isMissionDone) {
setIsMissionDone(true);
if (coupleData?.result?.my_emotion) {
const result_id = coupleData.result.my_emotion.id;

const requestData = {
is_complement: true,
};

const response = await axios.put(`https://www.wishkr.site/emotions/results/${result_id}/`, requestData, {
headers: {
'Content-Type': 'application/json',
},
});
console.log('요청 성공:', response.data);
}
}
} catch (error) {
console.error('에러:', error);
setIsMissionDone(isMissionDone);
setIsMissionDone(false);
}
};

// 서버 데이터가 변경될 때마다 로컬 상태 업데이트
useEffect(() => {
const emotion = coupleData?.result?.my_emotion;
setSelfMessage(emotion?.self_message || '');
setMission(emotion?.mission_content || '');
// isMissionDone 상태를 서버 데이터와 동기화
setIsMissionDone(emotion?.is_complement || false);
}, [coupleData]);

return (
Expand All @@ -110,31 +137,29 @@ const CoupleInformation = ({ coupleData }: OurReportProps) => {
<EmotionAnalysis>{partnerName ? '감정분석 필요' : '연동 필수'}</EmotionAnalysis>
</SpouseCard>
</CoupleCardsWrapper>
<>
<>
{mission ? (
<CoupleMissionToChoose isMissionDone={isMissionDone}>
<MissionTitle>{mission}</MissionTitle>
<IsMissionDone type="checkbox" checked={isMissionDone} onChange={handleMissionToggle} />
</CoupleMissionToChoose>
) : (
<CoupleMission>
{partnerName ? getMissionStatusMessage() : '배우자 연동을 하면 미션 등록이 가능해요'}
</CoupleMission>
)}
</>
</>
{partnerName ? (
<CoupleMissionWeekly></CoupleMissionWeekly>
) : (
<CoupleMission>배우자 연동을 하면 미션 등록이 가능해요</CoupleMission>
{mission && (
<CoupleMissionToChoose isMissionDone={isMissionDone}>
<MissionTitle>{mission}</MissionTitle>
{!isMissionDone && <IsMissionDone type="checkbox" checked={isMissionDone} onChange={handleMissionToggle} />}
{isMissionDone && <CompletedLabel>완료</CompletedLabel>}
</CoupleMissionToChoose>
)}

<CoupleMission>
{partnerName ? getMissionStatusMessage() : '배우자 연동을 하면 미션 등록이 가능해요'}
</CoupleMission>
<CoupleMissionWeekly></CoupleMissionWeekly>
</CoupleInformationContainer>
);
};

export default CoupleInformation;

const CompletedLabel = styled.span`
color: ${variables.colors.primary};
font-weight: 600;
font-size: ${variables.size.medium};
`;

const CoupleInformationContainer = styled.div`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -212,7 +237,7 @@ const CoupleMission = styled.div`
display: flex;
justify-content: center;
align-items: center;
box-shadow: inset ${variables.BoxShadow};
box-shadow: inset 0 0 0.3rem rgba(0, 0, 0, 0.1);
border-radius: calc(${variables.borderRadius} + 0.4rem);
color: ${variables.colors.black};
margin-bottom: 1.4rem;
Expand Down
80 changes: 64 additions & 16 deletions src/components/home/CoupleMissionWeekly.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,67 @@
import styled from '@emotion/styled';
import variables from '@styles/Variables';
import fetchMissionStatusWeekly from '@hooks/useCheckMissionStatus';
import { useEffect, useState } from 'react';

type DotStatus = 'completed' | 'current' | 'locked';
type DotStatus = 'bothCompleted' | 'oneCompleted' | 'locked';

interface MissionData {
is_complement: boolean;
created_at: string;
}

interface WeeklyStatusType {
user_is_complement: {
[key: string]: MissionData[];
};
spouse_is_complement: {
[key: string]: MissionData[];
};
}

const CoupleMissionWeekly = () => {
// 각 날짜의 상태를 정의
const dotStatuses: DotStatus[] = [
'completed', // 월요일 - 완료
'completed', // 화요일 - 완료
'completed', // 수요일 - 완료
'current', // 목요일 - 현재
'locked', // 금요일 - 잠김
'locked', // 토요일 - 잠김
'locked', // 일요일 - 잠김
];
const [weeklyStatus, setWeeklyStatus] = useState<WeeklyStatusType | null>(null);

useEffect(() => {
const MemberId = localStorage.getItem('MemberId');
if (MemberId) {
const fetchStatus = async () => {
const data = await fetchMissionStatusWeekly(MemberId);
if (data) {
setWeeklyStatus(data);
}
};
fetchStatus();
}
}, []);

const getDotStatus = (day: string): DotStatus => {
if (!weeklyStatus) return 'locked';

const userMission = weeklyStatus.user_is_complement[day]?.[0];
const spouseMission = weeklyStatus.spouse_is_complement[day]?.[0];

const userCompleted = userMission?.is_complement || false;
const spouseCompleted = spouseMission?.is_complement || false;

if (userCompleted && spouseCompleted) {
return 'bothCompleted';
} else if (userCompleted || spouseCompleted) {
return 'oneCompleted';
}
return 'locked';
};

const days = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'];
const today = new Date().getDay(); // 0(일요일)부터 6(토요일)
const mondayOffset = today === 0 ? 6 : today - 1; // 월요일 기준으로 조정

const dotStatuses: DotStatus[] = days.map((day, index) => {
if (index > mondayOffset) {
return 'locked';
}
return getDotStatus(day);
});

return (
<CoupleMissionWeeklyUI>
Expand Down Expand Up @@ -55,12 +103,12 @@ const Dot = styled.div<{ status: DotStatus }>`
height: 2.4rem;
background-color: ${({ status }) => {
switch (status) {
case 'completed':
return variables.colors.primary;
case 'current':
return variables.colors.secondary;
case 'bothCompleted':
return variables.colors.primary; // 파란색 - 둘 다 완료
case 'oneCompleted':
return variables.colors.secondary; // 빨간색 - 한 명만 완료
case 'locked':
return variables.colors.gray50;
return variables.colors.gray50; // 회색 - 미완료 또는 잠김
default:
return variables.colors.gray50;
}
Expand Down
22 changes: 19 additions & 3 deletions src/components/home/CoupleReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ const CoupleReport = ({ coupleData }: CoupleReportProps) => {
sexual: spouseInfSexual = 0,
social: spouseInfSocial = 0,
} = coupleData?.result?.spouse_inf_tests[0] || {};

const option = {
legend: {
show: true,
bottom: '0',
},
radar: {
indicator: [
{ name: '사회적' },
{ name: '성적' },
{ name: '필요성' },
{ name: '아이가 없는 일상에 대한 거부' },
{ name: '아이가 없는 일상' },
{ name: '관계적' },
],
splitNumber: 10,
Expand Down Expand Up @@ -98,7 +101,7 @@ const CoupleReport = ({ coupleData }: CoupleReportProps) => {
itemStyle: {
color: variables.colors.primary,
},
name: selected === 'self' ? '' : '배우자',
name: selected === 'self' ? '검사 점수' : '배우자',
},
{
value:
Expand Down Expand Up @@ -133,6 +136,11 @@ const CoupleReport = ({ coupleData }: CoupleReportProps) => {
<CoupleReportDescription>난임 스트레스 예상 점수</CoupleReportDescription>
<ChartCover>
<EChartsReact option={option} />
{coupleData?.result && (
<div className="flex-box">
<EmotionGraphContainer></EmotionGraphContainer>
</div>
)}
</ChartCover>
</CoupleReportLineChartContainer>
</CoupleReportContainer>
Expand All @@ -141,6 +149,14 @@ const CoupleReport = ({ coupleData }: CoupleReportProps) => {

export default CoupleReport;

const EmotionGraphContainer = styled.div`
width: 100%;
.flex-box {
display: flex;
}
`;

const ToggleContainer = styled.div`
display: flex;
justify-content: space-between;
Expand Down
23 changes: 18 additions & 5 deletions src/components/home/OurKeyword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ const OurKeyword = ({ coupleData }: OurKeywordProps) => {
<OurKeywordDescription>우리의 관심사</OurKeywordDescription>
<KeywordContainer>
{[...myKeywordArray, ...spouseKeywordArray].map((keyword, index) => (
<KeywordBox key={index}>#{keyword.trim()}</KeywordBox>
<KeywordBox key={index} colorIndex={index}>
#{keyword.trim()}
</KeywordBox>
))}
</KeywordContainer>
</OurKeywordLineChartContainer>
Expand Down Expand Up @@ -80,12 +82,23 @@ const KeywordContainer = styled.div`
margin-top: 3.5rem;
`;

const KeywordBox = styled.div`
const KeywordBox = styled.div<{ colorIndex: number }>`
padding: 0.8rem 1.6rem;
background-color: ${variables.colors.secondaryStrong};
background-color: ${({ colorIndex }) => {
switch (colorIndex % 3) {
case 0:
return variables.colors.primaryStrong;
case 1:
return variables.colors.primaryStrong;
case 2:
return variables.colors.secondaryStrong;
default:
return variables.colors.secondaryStrong;
}
}};
border-radius: 0.5rem;
font-size: ${variables.size.small};
color: ${variables.colors.tertiarySoft};
font-size: ${variables.size.medium};
color: ${variables.colors.white};
`;

const OurKeywordContainer = styled.div`
Expand Down
28 changes: 28 additions & 0 deletions src/hooks/useCheckMissionStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import axios from 'axios';

const fetchMissionStatusWeekly = async (member_id: string) => {
try {
const response = await axios.get('https://www.wishkr.site/emotions/missions/', {
params: { member_id },
});

// response.data가 undefined인지 체크
if (!response.data) {
console.error('응답 데이터가 없습니다');
return null;
}

if (!response.data) {
console.error('result 필드가 없습니다', response.data);
return null;
}

console.log('주간 미션 현황', response.data);
return response.data;
} catch (error) {
console.error('미션 상태 조회 중 에러 발생:', error);
return null;
}
};

export default fetchMissionStatusWeekly;
Loading

0 comments on commit 4ab3df0

Please sign in to comment.