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

[FEAT] Task 리스트 조회 api 연결 #169

Merged
merged 15 commits into from
Jul 17, 2024
Merged
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
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Router from './Router';
import Router from './router/Router';

function App() {
return <Router />;
Expand Down
28 changes: 0 additions & 28 deletions src/Router.tsx

This file was deleted.

5 changes: 5 additions & 0 deletions src/apis/tasks/getTask/GetTasksType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface GetTasksType {
isTotal?: boolean;
sortOrder?: string;
targetDate?: Date;
}
16 changes: 16 additions & 0 deletions src/apis/tasks/getTask/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { GetTasksType } from './GetTasksType';

import { privateInstance } from '@/apis/instance';

const getTasks = async ({ isTotal, sortOrder, targetDate }: GetTasksType) => {
const { data } = await privateInstance.get('/api/tasks', {
params: {
isTotal,
order: sortOrder,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 걍 궁금한건데 order는 왜 sortOrder로 한번 더 명명해준건가용??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state 이름을 order로 지으면 구분하기가 다소 모호한데 서버에서 요구하는 path variable 에서는 order로 명명되어 있어서 한번 바꿔서 전달해줬습니다!

targetDate,
},
});
return data;
};

export default getTasks;
13 changes: 13 additions & 0 deletions src/apis/tasks/getTask/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useQuery } from '@tanstack/react-query';

import getTasks from './axios';
import { GetTasksType } from './GetTasksType';

/** Task 리스트 조회 */
const useGetTasks = ({ isTotal, sortOrder, targetDate }: GetTasksType) =>
useQuery({
queryKey: ['today', isTotal, sortOrder, targetDate],
queryFn: () => getTasks({ isTotal, sortOrder, targetDate }),
});
Comment on lines +6 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요런 식으로 리액트 쿼리를 사용하는 거군요,, 처음 써보기에 좀 막막한데요오 먼저 잘 정리해주셔서 잘 참고할 수 있을 것 같습니다!
쿼리키에 today를 추가해주신 이유는 무엇인가요? 오늘 날짜를 기준으로 순서를 sort 하기 위함인가용?-?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

today 페이지에서 사용해서 페이지별로 구분하면 이해하기 빠를 것 같아서 앞에 써주었습니다! 소팅하는 건 getTasks로 전달하는 요소들 중 두번째에서 담당하고 있어요!


export default useGetTasks;
Empty file added src/apis/timeBlocks/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions src/components/common/StagingArea/StagingArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const StagingAreaLayout = styled.div`
display: inline-flex;
gap: 0.8rem;
align-items: center;
width: 31.7rem;
height: 76.8rem;
padding: 0 0.1rem 0 0.7rem;

Expand Down
17 changes: 10 additions & 7 deletions src/components/common/StagingArea/StagingAreaSetting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import TextBtn from '../button/textBtn/TextBtn';
import ModalArrange from '../modal/ModalArrange/ModalArrange';
import ModalBackdrop from '../modal/ModalBackdrop';

function StagingAreaSetting() {
const [activeButton, setActiveButton] = useState<'전체' | '지연'>('전체');
const [isModalOpen, setIsModalOpen] = useState(false);
import { SortOrderType } from '@/types/sortOrderType';

const handleTextBtnClick = (button: '전체' | '지연') => {
setActiveButton(button);
};
interface StagingAreaSettingProps {
handleTextBtnClick: (button: '전체' | '지연') => void;
activeButton: '전체' | '지연';
sortOrder: SortOrderType;
handleSortOrder: (order: SortOrderType) => void;
}
function StagingAreaSetting({ handleTextBtnClick, activeButton, sortOrder, handleSortOrder }: StagingAreaSettingProps) {
const [isModalOpen, setIsModalOpen] = useState(false);

const handleArrangeBtnClick = () => {
setIsModalOpen((prev) => !prev);
Expand Down Expand Up @@ -46,7 +49,7 @@ function StagingAreaSetting() {
</TextBtnContainer>
<ArrangeContainer>
<ArrangeBtn type="set" mode="DEFAULT" color="WHITE" size="small" onClick={handleArrangeBtnClick} />
{isModalOpen && <ModalArrange />}
{isModalOpen && <ModalArrange sortOrder={sortOrder} handleSortOrder={handleSortOrder} />}
</ArrangeContainer>
{isModalOpen && <ModalBackdrop onClick={handleCloseModal} />}
</StagingAreaSettingLayout>
Expand Down
86 changes: 58 additions & 28 deletions src/components/common/StagingArea/StagingAreaTaskContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import styled from '@emotion/styled';
import { useState } from 'react';
import { Draggable } from 'react-beautiful-dnd';

import BtnTaskContainer from '../BtnTaskContainer';
import ScrollGradient from '../ScrollGradient';

import useGetTasks from '@/apis/tasks/getTask/query';
import BtnTask from '@/components/common/BtnTask/BtnTask';
import StagingAreaSetting from '@/components/common/StagingArea/StagingAreaSetting';
import { SortOrderType } from '@/types/sortOrderType';
import { TaskType } from '@/types/tasks/taskType';

interface StagingAreaTaskContainerProps {
Expand All @@ -13,38 +17,64 @@ interface StagingAreaTaskContainerProps {
tasks: TaskType[];
}

function StagingAreaTaskContainer(props: StagingAreaTaskContainerProps) {
const { handleSelectedTarget, selectedTarget, tasks } = props;
function StagingAreaTaskContainer({ handleSelectedTarget, selectedTarget }: StagingAreaTaskContainerProps) {
const [activeButton, setActiveButton] = useState<'전체' | '지연'>('전체');
const [sortOrder, setSortOrder] = useState<SortOrderType>('recent');
const isTotal = activeButton === '전체';

// Task 목록 Get
const { isFetched, data } = useGetTasks({ isTotal, sortOrder });

/** isTotal 핸들링 함수 */
const handleTextBtnClick = (button: '전체' | '지연') => {
setActiveButton(button);
};

const handleSortOrder = (order: SortOrderType) => {
setSortOrder(order);
};
console.log(data);

return (
<StagingAreaTaskContainerLayout>
<StagingAreaSetting />
<StagingAreaSetting
handleTextBtnClick={handleTextBtnClick}
activeButton={activeButton}
sortOrder={sortOrder}
handleSortOrder={handleSortOrder}
/>
<BtnTaskContainer type="staging">
{tasks.map((task, index) => (
<Draggable key={task.id} draggableId={task.id.toString()} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{ userSelect: 'none', ...provided.draggableProps.style }}
>
<BtnTask
key={task.id + task.name}
iconType="stagingOrDelayed"
hasDescription={task.hasDescription}
id={task.id}
name={task.name}
status={task.status}
deadLine={task.deadLine}
selectedTarget={selectedTarget}
handleSelectedTarget={handleSelectedTarget}
isDragging={snapshot.isDragging}
/>
</div>
)}
</Draggable>
))}
{isFetched && (
<>
{data.data.tasks.map((task: TaskType, index: number) => (
<Draggable key={task.id} draggableId={task.id.toString()} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{ userSelect: 'none', ...provided.draggableProps.style }}
>
<BtnTask
key={task.id + task.name}
iconType="stagingOrDelayed"
hasDescription={task.hasDescription}
id={task.id}
name={task.name}
status={task.status}
deadLine={task.deadLine}
selectedTarget={selectedTarget}
handleSelectedTarget={handleSelectedTarget}
isDragging={snapshot.isDragging}
/>
</div>
)}
</Draggable>
))}
</>
)}

<ScrollGradient />
</BtnTaskContainer>
</StagingAreaTaskContainerLayout>
);
Expand Down
43 changes: 10 additions & 33 deletions src/components/common/modal/ModalArrange/ModalArrange.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,25 @@
import styled from '@emotion/styled';
import { useState } from 'react';

import SortBtn from '../../button/SortBtn';

import SORT_BY from '@/constants/sortType';
import { SortOrderType } from '@/types/sortOrderType';

function ModalArrange() {
const [activeSorByDateAdded, setActiveSorByDateAdded] = useState<string | null>(null);
const [activeSorByDeadLine, setActiveSorByDeadLine] = useState<string | null>(null);

const handleSortByDateAddedClick = (sortType: string) => {
setActiveSorByDateAdded((prev) => (prev === sortType ? null : sortType));
};

const handleSortByDeadLineClick = (sortType: string) => {
setActiveSorByDeadLine((prev) => (prev === sortType ? null : sortType));
};

interface ModalArrangeProps {
sortOrder: SortOrderType;
handleSortOrder: (order: SortOrderType) => void;
}
function ModalArrange({ sortOrder, handleSortOrder }: ModalArrangeProps) {
return (
<ModalArrangeLayout onClick={(e) => e.stopPropagation()}>
<SortBy>
<SortBtn
text={SORT_BY.NEWEST}
isActive={activeSorByDateAdded === SORT_BY.NEWEST}
onClick={() => handleSortByDateAddedClick(SORT_BY.NEWEST)}
/>
<SortBtn
text={SORT_BY.OLDEST}
isActive={activeSorByDateAdded === SORT_BY.OLDEST}
onClick={() => handleSortByDateAddedClick('오래된 등록순')}
/>
<SortBtn text={SORT_BY.NEWEST} isActive={sortOrder === 'recent'} onClick={() => handleSortOrder('recent')} />
<SortBtn text={SORT_BY.OLDEST} isActive={sortOrder === 'old'} onClick={() => handleSortOrder('old')} />
</SortBy>
<ModalArrangeLine />
<SortBy>
<SortBtn
text={SORT_BY.CLOSEST}
isActive={activeSorByDeadLine === SORT_BY.CLOSEST}
onClick={() => handleSortByDeadLineClick(SORT_BY.CLOSEST)}
/>
<SortBtn
text={SORT_BY.FARTHEST}
isActive={activeSorByDeadLine === SORT_BY.FARTHEST}
onClick={() => handleSortByDeadLineClick(SORT_BY.FARTHEST)}
/>
<SortBtn text={SORT_BY.CLOSEST} isActive={sortOrder === 'near'} onClick={() => handleSortOrder('near')} />
<SortBtn text={SORT_BY.FARTHEST} isActive={sortOrder === 'far'} onClick={() => handleSortOrder('far')} />
</SortBy>
</ModalArrangeLayout>
);
Expand Down
54 changes: 54 additions & 0 deletions src/components/loginPage/GoogleLoginBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import styled from '@emotion/styled';
import { useGoogleLogin } from '@react-oauth/google';
import { useNavigate } from 'react-router-dom';

import userLogin from '@/apis/login/loginAxios';
import Images from '@/assets/images';

function GoogleLoginBtn() {
const navigate = useNavigate();
const googleSocialLogin = useGoogleLogin({
onSuccess: async ({ code }) => {
try {
const response = await userLogin(code);
if (response.code === 'success') {
localStorage.setItem('accessToken', response.data.accessToken);
localStorage.setItem('refreshToken', response.data.refreshToken);
navigate('/today');
}
} catch (error) {
console.error(error);
}
},
onError: (errorResponse) => {
console.error(errorResponse);
},
flow: 'auth-code',
scope: 'email profile',
});
return (
<GoogleBtn onClick={googleSocialLogin}>
<GoogleImg src={Images.googleIcon} />
구글 계정으로 시작하기
</GoogleBtn>
);
}
const GoogleBtn = styled.button`
display: flex;
gap: 0.9rem;
align-items: center;
justify-content: center;
width: 100%;
height: 4.3rem;

color: ${({ theme }) => theme.palette.Grey.White};

background-color: ${({ theme }) => theme.palette.Grey.Black};
border-radius: 12px;
${({ theme }) => theme.fontTheme.LABEL_03};
`;
const GoogleImg = styled.img`
width: 1.8rem;
height: 1.8rem;
`;
export default GoogleLoginBtn;
2 changes: 1 addition & 1 deletion src/constants/sortType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const SORT_BY = {
NEWEST: '최신 등록순',
OLDEST: '오래된 등록순',
CLOSEST: '지연된 할 일',
CLOSEST: '가까운 마감기한순',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

FARTHEST: '먼 마감기한순',
};

Expand Down
9 changes: 8 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import '@/styles/font.css';

const CLIENT_ID = import.meta.env.VITE_GOOGLE_LOGIN_CLIENT_ID;

const queryClient = new QueryClient();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60,
gcTime: 1000 * 60,
},
},
});
ReactDOM.createRoot(document.getElementById('root')!).render(
<GoogleOAuthProvider clientId={CLIENT_ID}>
<QueryClientProvider client={queryClient}>
Expand Down
Loading
Loading