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

[FE] swipe 기능을 ref를 받아 쓰도록 개선한다 #959

Merged
merged 8 commits into from
Nov 15, 2024
12 changes: 6 additions & 6 deletions frontend/src/apis/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ export const deleteToken = async () => {
};

export const postReissueAccessToken = async () => {
return await fetch(`${BASE_URL}${ENDPOINT.USER_ACCESS_TOKEN_REISSUE}`, {
method: 'POST',
return await fetcher.post({
url: `${BASE_URL}${ENDPOINT.USER_ACCESS_TOKEN_REISSUE}`,
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
// 쿠키전달이기때문에 body가 비어있는 post
Comment on lines 40 to +41
Copy link
Contributor

Choose a reason for hiding this comment

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

fetcher 내부에 이미 credentials: 'include',이 포함되어 있어서 불필요한 코드인거 같네요~!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

반영했습니다.

});
};

export const postSignUp = async ({ name, email, password }: { name: string; email: string; password: string }) => {
return await fetch(`${BASE_URL}${ENDPOINT.REGISTER}`, {
method: 'POST',
body: JSON.stringify({ name, email, password }),
return await fetcher.post({
url: `${BASE_URL}${ENDPOINT.REGISTER}`,
body: { name, email, password },
credentials: 'include',
Copy link
Contributor

Choose a reason for hiding this comment

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

이부분도 동일합니다~!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

반영했습니다.

});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import RoomInfoTemplate from '@/components/NewChecklist/NewRoomInfoForm/RoomInfo
import OptionTemplate from '@/components/NewChecklist/Option/OptionTemplate';

const EditChecklistContent = () => {
const { currentTabId } = useTabContext();
const { currentTabId, useDragForTab } = useTabContext();

const ref = useDragForTab();

return (
<S.Container>
<S.Container ref={ref}>
{/*방 기본정보 템플릿 */}
{currentTabId === -1 && <RoomInfoTemplate />}
{/* 옵션 선택 템플릿 */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Divider from '@/components/_common/Divider/Divider';
import Layout from '@/components/_common/layout/Layout';
import { useTabContext } from '@/components/_common/Tabs/TabContext';
import ChecklistQuestionItem from '@/components/NewChecklist/ChecklistQuestion/ChecklistQuestion';
import MoveNextButton from '@/components/NewChecklist/MoveNextButton';
import useChecklistStore from '@/store/useChecklistStore';
import { flexColumn } from '@/styles/common';
import theme from '@/styles/theme';
Expand Down Expand Up @@ -37,6 +38,8 @@ const EditChecklistQuestionTemplate = () => {
);
})}
</S.ContentBox>

<MoveNextButton marginTop="2rem" marginBottom="4rem" />
</Layout>
);
};
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/NewChecklist/ChecklistContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import RoomInfoTemplate from '@/components/NewChecklist/NewRoomInfoForm/RoomInfo
import OptionTemplate from '@/components/NewChecklist/Option/OptionTemplate';

const ChecklistContent = () => {
const { currentTabId } = useTabContext();
const { currentTabId, useDragForTab } = useTabContext();
useDragForTab();

return (
<S.Container>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { useMemo } from 'react';

import ChecklistTabSuspense from '@/components/_common/errorBoundary/ChecklistTabSuspense';
import { useTabContext } from '@/components/_common/Tabs/TabContext';
import Tabs from '@/components/_common/Tabs/Tabs';
import { DefaultChecklistTabsNames } from '@/constants/tabs';
import useInitialChecklist from '@/hooks/useInitialChecklist';
import useMouseDrag from '@/hooks/useMouseDrag';
import useTabs from '@/hooks/useTabs';
import useChecklistStore from '@/store/useChecklistStore';
import isSameCategory from '@/utils/isSameCategory';
Expand All @@ -14,20 +11,6 @@ const NewChecklistTab = () => {
const { data: checklist, isSuccess, isLoading } = useInitialChecklist();
const checklistStore = useChecklistStore(state => state.checklistCategoryQnA);
const { getTabsForChecklist } = useTabs();
const { setCurrentTabId } = useTabContext();

useMouseDrag((S, E) => {
const DRAG_THRESHOLD = 100;
const TAB_COUNT = DefaultChecklistTabsNames.length;
const remainOp = (a: number, b: number) => (((a % b) + b + 1) % b) - 1; // 나머지연산자. -1부터 시작하므로 +1 -1
setCurrentTabId(tabId => {
const isLeftDrag = E.x - S.x > DRAG_THRESHOLD;
const isRightDrag = S.x - E.x > DRAG_THRESHOLD;
if (isLeftDrag) return remainOp(tabId - 1, TAB_COUNT);
if (isRightDrag) return remainOp(tabId + 1, TAB_COUNT);
return tabId;
});
});

const categoryTabs = useMemo(() => {
if (isSuccess && isSameCategory(checklist, checklistStore)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const DepositAndRent = () => {
<FormField.Label label="보증금 / 월세 (만원)" />
<FormStyled.FieldBox>
<FormField.Input
inputMode="decimal"
width="medium"
onChange={deposit.onChange}
name="deposit"
Expand All @@ -21,6 +22,7 @@ const DepositAndRent = () => {
/>
<FormStyled.FlexLabel label=" / " />
<FormField.Input
inputMode="decimal"
Copy link
Contributor

Choose a reason for hiding this comment

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

이런 속성이 있는지는 처음 알았네요 제이드 덕분에 배우고 갑니다!!

width="medium"
placeholder=""
onChange={rent.onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const MaintenanceFee = () => {
<FormField.Label label="관리비" htmlFor="maintenanceFee" />
<FormStyled.FieldBox>
<Input
inputMode="decimal"
Copy link
Contributor

Choose a reason for hiding this comment

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

👍👍👍

width="medium"
placeholder=""
onChange={maintenanceFee.onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const OccupancyMonth = () => {
<FormField.Label label="입주 가능일" htmlFor="occupancyMonth" />
<FormStyled.FieldBox>
<FormField.Input
inputMode="decimal"
width="medium"
onChange={occupancyMonth.onChange}
name="occupancyMonth"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const RoomContractTerm = () => {
<FormField.Label label="계약 기간" htmlFor="contractTerm" />
<S.FieldBox>
<Input
inputMode="decimal"
width="medium"
placeholder=""
onChange={contractTerm.onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const RoomFloor = () => {
onSelectSetter={handleClickDropdown}
/>
<Input
inputMode="decimal"
width="medium"
disabled={floorLevel.rawValue === '반지하/지하'}
placeholder=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const RoomSize = () => {
<FormField.Label label="방 크기" htmlFor="size" />
<FormStyled.FieldBox>
<Input
inputMode="decimal"
width="medium"
placeholder=""
onChange={roomSize.onChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ const SendVerificationEmailStep = ({ onNext }: Props) => {
onSuccess: () => setIsComplete(true),
onError: error => setPostErrorMessage(error.message),
});
const handleClickNext = () => {
onNext(email);
};
const handleClickNext = () => onNext(email);

const canMove = isEmailValid && isComplete;

Expand Down Expand Up @@ -74,7 +72,7 @@ const SendVerificationEmailStep = ({ onNext }: Props) => {
style={{ width: '25rem' }}
/>
<div>
<CS.SendButton onClick={handleClickSubmit} disabled={canMove}>
<CS.SendButton onClick={handleClickSubmit} disabled={canMove || !isEmailValid}>
전송
</CS.SendButton>
</div>
Expand Down
34 changes: 26 additions & 8 deletions frontend/src/components/_common/Tabs/TabContext.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
import { createContext, ReactNode, useContext, useState } from 'react';
import { createContext, ReactNode, RefObject, useContext, useRef, useState } from 'react';

import { ERROR_MESSAGE } from '@/constants/messages/errorMessage';
import { DefaultChecklistTabsNames, DRAG_THRESHOLD_PIXEL } from '@/constants/tabs';
import useMouseDrag from '@/hooks/useMouseDrag';

interface ContextProps {
currentTabId: number;
setCurrentTabId: React.Dispatch<React.SetStateAction<number>>;
useDragForTab: () => RefObject<HTMLElement>;
}

const defaultContext: ContextProps = {
currentTabId: 0,
setCurrentTabId: () => {},
};

const TabContext = createContext<ContextProps>(defaultContext);
const TabContext = createContext<ContextProps | null>(null);

interface Props {
children: ReactNode;
defaultTab: number;
}

const remainOp = (a: number, b: number) => (((a % b) + b + 1) % b) - 1; // 나머지연산자. -1부터 시작하므로 +1 -1

export const TabProvider = ({ children, defaultTab = 0 }: Props) => {
const [currentTabId, setCurrentTabId] = useState<number>(defaultTab);

return <TabContext.Provider value={{ currentTabId, setCurrentTabId }}>{children}</TabContext.Provider>;
// 드래그로 탭이동을 위한 훅을 리턴에 제공
const useDragForTab = (dragThreshold: number = DRAG_THRESHOLD_PIXEL) => {
const ref = useRef<HTMLElement>(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

TabContext에 넣으니까 응집성 있고 좋네요!!👍

useMouseDrag(ref, (S, E) => {
const TAB_COUNT = DefaultChecklistTabsNames.length;

setCurrentTabId(tabId => {
const isLeftDrag = E.x - S.x > dragThreshold;
const isRightDrag = S.x - E.x > dragThreshold;
if (isLeftDrag) return remainOp(tabId - 1, TAB_COUNT);
if (isRightDrag) return remainOp(tabId + 1, TAB_COUNT);
return tabId;
});
});

return ref;
};

return <TabContext.Provider value={{ currentTabId, setCurrentTabId, useDragForTab }}>{children}</TabContext.Provider>;
};

export const useTabContext = () => {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/constants/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export const DefaultChecklistTabsNames: Tab[] = [
name: '보안',
},
];

export const DRAG_THRESHOLD_PIXEL = 100;
32 changes: 16 additions & 16 deletions frontend/src/hooks/useMouseDrag.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { useEffect, useState } from 'react';
import { MutableRefObject, useEffect, useState } from 'react';

interface MousePosition {
x: number;
y: number;
}
type Handler = (start: MousePosition, end: MousePosition) => void;

const useMouseDrag = (handler: Handler) => {
const useMouseDrag = (ref: MutableRefObject<HTMLElement | null>, handler: Handler) => {
const [startPosition, setStartPosition] = useState<MousePosition | null>(null);

useEffect(() => {
const pointerdownListener = (e: MouseEvent) => {
setStartPosition({ x: e.clientX, y: e.clientY });
};
const touchStartListener = (e: TouchEvent) => {
const pointerdownListener = (e: MouseEvent) => setStartPosition({ x: e.clientX, y: e.clientY });

const touchStartListener = (e: TouchEvent) =>
setStartPosition({ x: e.changedTouches[0].clientX, y: e.changedTouches[0].clientX });
};

const pointerupListener = (e: MouseEvent) => {
const endPosition = { x: e.clientX, y: e.clientY };
Expand All @@ -30,18 +28,20 @@ const useMouseDrag = (handler: Handler) => {
setStartPosition(null);
};

window.addEventListener('mousedown', pointerdownListener);
window.addEventListener('touchstart', touchStartListener);
window.addEventListener('mouseup', pointerupListener);
window.addEventListener('touchend', touchEndListener);
const el = ref.current;

el?.addEventListener('mousedown', pointerdownListener);
el?.addEventListener('touchstart', touchStartListener);
el?.addEventListener('mouseup', pointerupListener);
el?.addEventListener('touchend', touchEndListener);

return () => {
window.removeEventListener('mousedown', pointerdownListener);
window.removeEventListener('mouseup', pointerupListener);
window.removeEventListener('touchstart', touchStartListener);
window.removeEventListener('touchend', touchEndListener);
el?.removeEventListener('mousedown', pointerdownListener);
el?.removeEventListener('mouseup', pointerupListener);
el?.removeEventListener('touchstart', touchStartListener);
el?.removeEventListener('touchend', touchEndListener);
};
}, [startPosition, handler]);
}, [startPosition, ref, handler]);
};

export default useMouseDrag;
Loading