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

개인 대시보드 QA & 무한 스크롤 오류 #71

Merged
merged 8 commits into from
Sep 24, 2024
4 changes: 1 addition & 3 deletions src/api/PersonalBlockApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ export const patchPersonalBlock = async (
try {
const response = await axiosInstance.patch(`/blocks/${blockId}`, data);
console.log(response.data);

return response.data.data.blockId;
return response.data;
} catch (error) {
console.error('Error fetching data:', error);

return null;
}
};
Expand Down
8 changes: 2 additions & 6 deletions src/components/Block.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import Flex from './Flex';
import edit from '../img/edit.png';
import deleteicon from '../img/delete.png';
import * as S from '../styles/DashboardStyled';
import { Draggable } from 'react-beautiful-dnd';
import { useNavigate } from 'react-router-dom';
import CustomModal from './CustomModal';
import { dashboardType } from '../contexts/DashboardAtom';
import { Link } from 'react-router-dom';
import Profile from './Profile';
import useModal from '../hooks/useModal';
import { realDeleteBlock, restoreBlockFunc } from '../api/PersonalBlockApi';
import { getPersonalBlock, realDeleteBlock, restoreBlockFunc } from '../api/PersonalBlockApi';
import { useEffect, useState } from 'react';
import { useAtom } from 'jotai';
import { fetchTriggerAtom } from '../contexts/atoms';
Expand Down Expand Up @@ -94,7 +90,7 @@ const Block = ({
>
<Flex justifyContent="space-between">
<h3>{title}</h3>
<span>D-{dDay}</span>
<span>D-{dDay === -1 ? 0 : dDay}</span>
</Flex>
{dType === 'PersonalDashboard' ? (
<p>{contents}</p>
Expand Down
55 changes: 36 additions & 19 deletions src/components/CompletedDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ import { useNavigate, Outlet } from 'react-router-dom';
import Block from './Block';
import * as S from '../styles/DashboardStyled';
import { createPersonalBlock } from '../api/PersonalBlockApi';
import SidePage from '../pages/SidePage';
import { Droppable } from 'react-beautiful-dnd';
import theme from '../styles/Theme/Theme';
import main2 from '../img/main2.png';
import { BlockListResDto } from '../types/PersonalBlock';
import { useInView } from 'react-intersection-observer';
import { useEffect } from 'react';

type Props = {
// list: StatusPersonalBlock | undefined;
list: BlockListResDto[];
id: string;
dashboardId: string;
onLoadMore: () => void;
};

const CompletedDashboard = ({ list, id, dashboardId }: Props) => {
const CompletedDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => {
const navigate = useNavigate();
// const blocks = list.flatMap((item: StatusPersonalBlock) => item.blockListResDto);
// const blocks = list?.blockListResDto;

const settings = {
backGroundColor: '#F7F1FF',
Expand Down Expand Up @@ -50,6 +49,17 @@ const CompletedDashboard = ({ list, id, dashboardId }: Props) => {
navigate(`personalBlock/${blockId}`, { state: { highlightColor, progress, blockId } });
};

// 세로 무한 스크롤
const { ref: lastBlockRef, inView } = useInView({
threshold: 0, // 마지막 블록이 0% 보였을 때를 감지
});

useEffect(() => {
if (inView) {
onLoadMore(); // 부모 컴포넌트에 새로운 데이터 요청
}
}, [inView]);

return (
<S.CardContainer backGroundColor={settings.backGroundColor}>
<header>
Expand All @@ -67,20 +77,24 @@ const CompletedDashboard = ({ list, id, dashboardId }: Props) => {
className="container"
{...provided.droppableProps}
>
{list?.map((block, index) => (
<Block
dashboardId={dashboardId}
key={block.blockId}
index={index}
title={block.title ?? ''}
dDay={block.dDay ?? 0}
contents={block.contents ?? ''}
blockId={block.blockId ?? '0'}
dType={block.dType ?? 'TeamDashboard'}
name={block.nickname ?? '이름 없음'}
picture={block.picture ?? ''}
/>
))}
{list?.map((block, index) => {
const isLastBlock = index === list.length - 1;
return (
<div key={block.blockId}>
<Block
dashboardId={dashboardId}
index={index}
title={block.title ?? ''}
dDay={block.dDay ?? 0}
contents={block.contents ?? ''}
blockId={block.blockId ?? '0'}
dType={block.dType ?? 'TeamDashboard'}
name={block.nickname ?? '이름 없음'}
picture={block.picture ?? ''}
/>
</div>
);
})}
{provided.placeholder}
</S.BoxContainer>
)}
Expand All @@ -90,3 +104,6 @@ const CompletedDashboard = ({ list, id, dashboardId }: Props) => {
);
};
export default CompletedDashboard;
function onLoadMore() {
throw new Error('Function not implemented.');
}
10 changes: 1 addition & 9 deletions src/components/DeleteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import * as S from '../styles/MainPageStyled';
import { Droppable } from 'react-beautiful-dnd';
import Block from './Block';
import { BlockListResDto } from '../types/PersonalBlock';
import CustomModal from './CustomModal';
import useModal from '../hooks/useModal';

interface Props {
id: string;
Expand All @@ -23,6 +21,7 @@ const DeleteButton = ({ id, list, removeValue }: Props) => {
const onBlockIdHandler = (num: string | null | undefined) => {
if (num) setBlockId(num);
};

return (
<S.DeleteContainer>
{value && (
Expand Down Expand Up @@ -64,13 +63,6 @@ const DeleteButton = ({ id, list, removeValue }: Props) => {
<S.DeleteIconWrapper onClick={onValueFunction}>
<img src={deleteicon} alt="휴지통아이콘" />
</S.DeleteIconWrapper>
{/* {isModalOpen && (
<CustomModal
title={info.title}
subTitle={info.subTitle}
onClose={onModalHandler}
/>
)} */}
</S.DeleteContainer>
);
};
Expand Down
11 changes: 8 additions & 3 deletions src/components/Graph.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useState } from 'react';
import * as S from '../styles/DashboardStyled';
import Flex from './Flex';

type GraphProps = {
blockProgress: number;
Expand All @@ -7,9 +9,12 @@ type GraphProps = {
const Graph = ({ blockProgress }: GraphProps) => {
return (
<S.GraphContainer>
<S.GraphProgress blockProgress={blockProgress}>
<p>{blockProgress}%</p>
</S.GraphProgress>
<Flex>
<S.GraphWrapper>
<S.GraphProgress blockProgress={blockProgress}></S.GraphProgress>
</S.GraphWrapper>
<span>{blockProgress}%</span>
</Flex>
</S.GraphContainer>
);
};
Expand Down
7 changes: 1 addition & 6 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import Graph from '../components/Graph';
import Flex from './Flex';
import setting from '../img/setting.png';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import leftarrow from '../img/leftarrow.png';
import * as S from '../styles/HeaderStyled';
import { dashboardType } from '../contexts/DashboardAtom';

type Props = {
mainTitle: string;
Expand All @@ -18,10 +16,6 @@ const Header = ({ mainTitle, subTitle, blockProgress, dashboardType }: Props) =>
const location = useLocation();
const dashboardId = location.pathname.split('/')[1];

const handleBackClick = () => {
navigate(-1);
};

// URL에 "teamdocument"가 포함되어 있는지 확인하는 함수
// => 전역 변수로 개인 대시보드인지 팀 대시보드인지 확인할 예정이라 주석 처리
// const teamLocationUrl = location.pathname.includes('teamdocument') ?? true;
Expand Down Expand Up @@ -56,6 +50,7 @@ const Header = ({ mainTitle, subTitle, blockProgress, dashboardType }: Props) =>
</S.HeaderContentContainer>
<Flex>
<Graph blockProgress={blockProgress} />

{!dashboardType && (
<Link to={`/${dashboardId}/teamdocument`}>
<S.TeamDocButton>팀문서</S.TeamDocButton>
Expand Down
48 changes: 32 additions & 16 deletions src/components/InProgressDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import { Droppable } from 'react-beautiful-dnd';
import theme from '../styles/Theme/Theme';
import main from '../img/main.png';
import { BlockListResDto } from '../types/PersonalBlock';
import { useInView } from 'react-intersection-observer';
import { useEffect } from 'react';

type Props = {
// list: StatusPersonalBlock | undefined;
list: BlockListResDto[];
id: string;
dashboardId: string;
onLoadMore: () => void;
};

const InProgressDashboard = ({ list, id, dashboardId }: Props) => {
const InProgressDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => {
const navigate = useNavigate();
// const blocks = list.flatMap((item: StatusPersonalBlock) => item.blockListResDto);
// const blocks = list?.blockListResDto;
Expand Down Expand Up @@ -50,6 +52,16 @@ const InProgressDashboard = ({ list, id, dashboardId }: Props) => {
navigate(`personalBlock/${blockId}`, { state: { highlightColor, progress, blockId } });
};

// 세로 무한 스크롤
const { ref: lastBlockRef, inView } = useInView({
threshold: 0, // 마지막 블록이 0% 보였을 때를 감지
});

useEffect(() => {
if (inView) {
onLoadMore(); // 부모 컴포넌트에 새로운 데이터 요청
}
}, [inView]);
return (
<S.CardContainer backGroundColor={settings.backGroundColor}>
<header>
Expand All @@ -67,20 +79,24 @@ const InProgressDashboard = ({ list, id, dashboardId }: Props) => {
className="container"
{...provided.droppableProps}
>
{list?.map((block, index) => (
<Block
dashboardId={dashboardId}
key={block.blockId}
index={index}
title={block.title ?? ''}
dDay={block.dDay ?? 0}
contents={block.contents ?? ''}
blockId={block.blockId ?? '0'}
dType={block.dType ?? 'TeamDashboard'}
name={block.nickname ?? '이름 없음'}
picture={block.picture ?? ''}
/>
))}
{list?.map((block, index) => {
const isLastBlock = index === list.length - 1;
return (
<div key={block.blockId}>
<Block
dashboardId={dashboardId}
index={index}
title={block.title ?? ''}
dDay={block.dDay ?? 0}
contents={block.contents ?? ''}
blockId={block.blockId ?? '0'}
dType={block.dType ?? 'TeamDashboard'}
name={block.nickname ?? '이름 없음'}
picture={block.picture ?? ''}
/>
</div>
);
})}
{provided.placeholder}
</S.BoxContainer>
)}
Expand Down
22 changes: 4 additions & 18 deletions src/components/NotStartedDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ import { useNavigate, Outlet } from 'react-router-dom';
import Block from './Block';
import * as S from '../styles/DashboardStyled';
import { createPersonalBlock } from '../api/PersonalBlockApi';
import { useAtom } from 'jotai';
import { visibleAtom } from '../contexts/sideScreenAtom';
import SidePage from '../pages/SidePage';
import { Droppable } from 'react-beautiful-dnd';
import theme from '../styles/Theme/Theme';
import main3 from '../img/main3.png';
import { BlockListResDto, StatusPersonalBlock } from '../types/PersonalBlock';
import { BlockListResDto } from '../types/PersonalBlock';
import { useInView } from 'react-intersection-observer';
import { useEffect, useState } from 'react';
import { useEffect } from 'react';

type Props = {
// list: StatusPersonalBlock | undefined;
list: BlockListResDto[];
id: string;
dashboardId: string;
Expand Down Expand Up @@ -60,6 +56,7 @@ const NotStartedDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => {

useEffect(() => {
if (inView) {
console.log('되긴함?');
onLoadMore(); // 부모 컴포넌트에 새로운 데이터 요청
}
}, [inView]);
Expand All @@ -83,21 +80,10 @@ const NotStartedDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => {
className="container"
{...provided.droppableProps}
>
{/* {list?.map((block, index) => (
<Block
dashboardId={dashboardId}
key={block.blockId}
index={index}
title={block.title ?? ''}
dDay={block.dDay ?? 0}
contents={block.contents ?? ''}
blockId={block.blockId ?? '0'}
/>
))} */}
{list?.map((block, index) => {
const isLastBlock = index === list.length - 1;
return (
<div key={block.blockId} ref={isLastBlock ? lastBlockRef : null}>
<div key={block.blockId}>
<Block
dashboardId={dashboardId}
index={index}
Expand Down
22 changes: 10 additions & 12 deletions src/hooks/useSSE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { EventSourcePolyfill } from 'event-source-polyfill';
import { unreadCount } from '../contexts/sseAtom';
import { customErrToast } from '../utils/customErrorToast';
import { NotificationResponse } from '../types/MyPage';
import { apiBaseUrl } from '../utils/apiConfig';

const sseConnectedAtom = atom(false); // SSE 연결 상태
const sseMessagesAtom = atom<string[]>([]); // SSE 메시지 상태
Expand All @@ -26,18 +27,15 @@ export const useSSE = (
}

// SSE 연결 설정
eventSource.current = new EventSourcePolyfill(
'https://dev.kkeujeok.store/api/notifications/stream',
{
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
Connection: '',
Accept: 'text/event-stream',
},
heartbeatTimeout: 259200,
withCredentials: true,
}
);
eventSource.current = new EventSourcePolyfill(`${apiBaseUrl}/notifications/stream`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
Connection: '',
Accept: 'text/event-stream',
},
heartbeatTimeout: 86400000,
withCredentials: true,
});

// 메시지 수신 처리
eventSource.current.onmessage = event => {
Expand Down
Loading