Skip to content
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
70 changes: 32 additions & 38 deletions src/components/feedbacks/feedbacks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,52 @@ import { useNavigate } from 'react-router-dom';
import moment from 'moment';
import * as Style from '../../css/Feedbacks/FeedbackStyle';
import { fbInfo } from 'interfaces/feedbackType';
import { useRecoilState } from 'recoil';
import {
fbListState,
taskIdState,
profileImgState,
feedbackState,
} from 'state';
import { useRecoilState, useRecoilValue } from 'recoil';
import { taskIdState, profileImgState, fbListState } from 'state';

const Feedbacks = ({ pathname }: { pathname: string }) => {
const [fbList, setFbList] = useRecoilState(fbListState);
const fbList = useRecoilValue(fbListState);
const [taskId, setTaskId] = useRecoilState(taskIdState);
const [isOpen, setIsOpen] = useRecoilState(feedbackState);
const navigate = useNavigate();

const getTaskId = (e: React.MouseEvent<HTMLElement>) => {
setTaskId(parseInt((e.target as HTMLElement).id));
navigate(`/teample-detail/${(e.target as HTMLElement).id}`);
setIsOpen(false);
};
const [profileImg, setProfileImg] = useRecoilState(profileImgState);
const [profileImg] = useRecoilValue(profileImgState);

return (
<Style.FeedBox pathname={pathname}>
<div className="feedText">피드백</div>
<div className="feedList">
{fbList.map((fb: fbInfo, index: number) => (
<Style.Feed
id={fb.taskId.toString()}
key={index}
onClick={getTaskId}
checked={fb.checked}
>
<div className="icon" id={fb.taskId.toString()}>
{profileImg && (
<img
src={require('../images/profile/proImageU' +
profileImg +
'.png')}
id={fb.taskId.toString()}
/>
)}
</div>
<div className="feedContent" id={fb.taskId.toString()}>
[{fb.teamName}]
<br />
{fb.taskName}에 적힌 피드백입니다.
</div>
<div className="feedAt" id={fb.taskId.toString()}>
{moment(fb.modifiedAt).format('MM-DD HH:mm')}
</div>
</Style.Feed>
))}
{fbList &&
fbList.map((fb: fbInfo, index: number) => (
<Style.Feed
id={fb.taskId.toString()}
key={index}
onClick={getTaskId}
checked={fb.checked}
>
<div className="icon" id={fb.taskId.toString()}>
{profileImg && (
<img
src={require('../images/profile/proImageU' +
profileImg +
'.png')}
id={fb.taskId.toString()}
/>
)}
</div>
<div className="feedContent" id={fb.taskId.toString()}>
[{fb.teamName}]
<br />
{fb.taskName}에 적힌 피드백입니다.
</div>
<div className="feedAt" id={fb.taskId.toString()}>
{moment(fb.modifiedAt).format('MM-DD HH:mm')}
</div>
</Style.Feed>
))}
</div>
</Style.FeedBox>
);
Expand Down
60 changes: 19 additions & 41 deletions src/components/homePage/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,40 @@
import React, { useEffect } from 'react';
import { useRecoilState } from 'recoil';
import { feedbackState, fbListState, isCheckedState } from 'state';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { checkedfbSelector, fbListState } from 'state';
import feedback from '../images/feedback.png';
import userAPI from 'api/userAPI';
import * as Style from '../../css/HomePage/HomeHeaderStyle';
import { useModal } from 'hooks/useModal';
import Feedbacks from 'components/feedbacks/feedbacks';
import { fbInfo } from 'interfaces/feedbackType';

const HomeHeader = () => {
const [fbList, setFbList] = useRecoilState(fbListState);
const [isCheck, setIsCheck] = useRecoilState(isCheckedState);

const getFeedbackAPI = () => {
userAPI.getFeedback()
.then((response) => {
setFbList(response.data.data.feedbacks.reverse());
})
.catch(function (error) {
console.log(error);
});
};

const countChecked = () => {
let cnt = 0;
fbList &&
fbList.map((fb) => {
if (!fb.checked) {
cnt += 1;
}
});
if (cnt > 0) {
return true;
} else {
return false;
const setFbList = useSetRecoilState(fbListState);
const checked = useRecoilValue(checkedfbSelector);
const { isOpen, toggleModal } = useModal();

const getFeedback = async () => {
try {
const feedbacks = await userAPI.getFeedback();
setFbList(feedbacks.data.data.feedbacks.reverse());
} catch (error) {
console.log(error);
}
};
useEffect(() => {
setIsCheck(countChecked());
}, [fbList]);

useEffect(() => {
getFeedbackAPI();
getFeedback();
}, []);

const [isOpen, setIsOpen] = useRecoilState(feedbackState);

const openFeed = () => {
setIsOpen(!isOpen);
};

return (
<Style.HomeHeaderContainer>
<Style.HomeTitle>홈</Style.HomeTitle>
<div className="iconBox" onClick={openFeed}>
{isCheck ? <Style.MsgIcon /> : <img id="feedback" src={feedback} />}
<div className="iconBox" onClick={toggleModal}>
{checked ? <Style.MsgIcon /> : <img id="feedback" src={feedback} />}
</div>
{isOpen && <Feedbacks pathname="/home" />}
</Style.HomeHeaderContainer>
);
};



export default HomeHeader;
22 changes: 3 additions & 19 deletions src/components/layouts/teampleHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import feedback from '../images/feedback.png';
import ModifyTeample from 'components/popup/ModifyTeample';
import TeamMateInfo from 'components/popup/TeamMateInfo';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import {
feedbackState,
modal2State,
Expand Down Expand Up @@ -30,7 +30,7 @@ const TeampleHeader = () => {
const [deadDay, setDeadDay] = useState<string | null>(null);
const token = localStorage.getItem('jwt_accessToken');
const [teamid] = useRecoilState(teamidState);
const [fbList, setFbList] = useRecoilState(fbListState);
const fbList = useRecoilValue(fbListState);
const [isCheck, setIsCheck] = useRecoilState(isCheckedState);

const showModal1 = () => {
Expand All @@ -46,17 +46,6 @@ const TeampleHeader = () => {
setIsOpen(!isOpen);
};

const getFeedbackAPI = () => {
userAPI
.getFeedback()
.then((response) => {
setFbList(response.data.data.feedbacks);
})
.catch(function (error) {
console.log(error);
});
};

const countChecked = () => {
let cnt = 0;
fbList &&
Expand All @@ -75,13 +64,8 @@ const TeampleHeader = () => {
setIsCheck(countChecked());
}, [fbList]);

useEffect(() => {
getFeedbackAPI();
}, []);

const getTHeader = async () => {
teamAPI.get(teamid)
.then((res) => {
teamAPI.get(teamid).then((res) => {
setName(res.data.data.name);
setGoal(res.data.data.goal);
setTeamMatesNum(res.data.data.teammatesNum);
Expand Down
4 changes: 2 additions & 2 deletions src/css/Feedbacks/FeedbackStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const FeedBox = styled.div<StyledFeedInfo>`
position: absolute;
margin-right: 2.8125vw;
margin-top: ${(props) =>
props.pathname === '/home' ? '6.777777vh' : '0.1111111vh'};
props.pathname === '/home' ? '50.777777vh' : '0.1111111vh'};
margin-left: auto;
z-index: 1001;

Expand Down Expand Up @@ -93,4 +93,4 @@ export const Feed = styled.div<StyledFeedInfo>`
width: 4vw;
// margin-left: 2.083333vw;
}
`;
`;
35 changes: 35 additions & 0 deletions src/hooks/useModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useEffect, useRef, useState } from 'react';

export const useModal = () => {
const [isOpen, setIsOpen] = useState(false);
const modalRef = useRef<HTMLDivElement>(null);

useEffect(() => {
document.addEventListener('mousedown', handleOutsideClick);

return () => {
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [isOpen]);

const toggleModal = () => {
setIsOpen((prevIsOpen) => !prevIsOpen);
};

const openModal = () => {
setIsOpen(true);
};

const closeModal = () => {
setIsOpen(false);
};

const handleOutsideClick = (e: Event) => {
const current = modalRef.current;
if (isOpen && current && !current.contains(e.target as Node)) {
setIsOpen(false);
}
};

return { isOpen, modalRef, toggleModal, closeModal, openModal };
};
21 changes: 20 additions & 1 deletion src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { detailInfo } from 'interfaces/taskType';
import { makeTeampleInfo, modTeampleInfo } from 'interfaces/teamType';
import { stageInfo } from 'interfaces/stageType';
import { fbInfo } from 'interfaces/feedbackType';
import { atom } from 'recoil';
import { atom, selector } from 'recoil';
import { v1 } from 'uuid'; // key duplicate 방지를 위한 라이브러리
import { recoilPersist } from 'recoil-persist';
import userAPI from 'api/userAPI';
const { persistAtom } = recoilPersist();

export const usernameState = atom<string>({
Expand Down Expand Up @@ -161,6 +162,24 @@ export const fbListState = atom<fbInfo[]>({
],
});

export const checkedfbSelector = selector<number>({
key: 'checkedLength',
get: ({ get }) => {
let cnt = 0;
const checked = get(fbListState);
checked.map((fb: fbInfo) => {
if (!fb.checked) {
cnt += 1;
}
});

return cnt;
},
cachePolicy_UNSTABLE: {
eviction: 'most-recent',
},
});

export const profileImgState = atom<string>({
key: 'profileImg',
default: '',
Expand Down