Skip to content

Commit

Permalink
Merge pull request #266 from SCBJ-7/feature/#264-fix-room-page
Browse files Browse the repository at this point in the history
[#264] 상세 페이지 QA 및 에러 해결
  • Loading branch information
im-na0 authored Jan 27, 2024
2 parents 25edca4 + dddf8aa commit 0685ff7
Show file tree
Hide file tree
Showing 34 changed files with 243 additions and 190 deletions.
11 changes: 6 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Outlet } from "react-router-dom";
import ScrollToTop from "@components/scrollToTop/ScrollToTop";
import Toast from "./components/toast/Toast";
import Toast from "@components/toast/Toast";
import "./firebase.ts";

import { useToastStore } from "./store/store";
import { AnimatePresence } from "framer-motion";
import IsLogin from "@components/isLogin/IsLogin";

function App() {
const App = () => {
const toastConfig = useToastStore((state) => state.config);

return (
<>
<IsLogin>
<ScrollToTop />
<AnimatePresence>{toastConfig.isShow && <Toast />}</AnimatePresence>
<Outlet />
</>
</IsLogin>
);
}
};

export default App;
23 changes: 19 additions & 4 deletions src/apis/fetchRoom.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import { BASE_URL, END_POINTS } from "@constants/api";
import axios from "axios";
import { ACCESS_TOKEN, BASE_URL, END_POINTS } from "@constants/api";
import type { ResponseData } from "@type/responseType";
import type { RoomData } from "@type/room";
import axios from "axios";
import { ResponseError } from "@/components/error/Error";

export const getRoom = async (
productId: string,
isLoggedIn: boolean,
): Promise<RoomData> => {
const headers: { [key: string]: string } = {};

if (isLoggedIn) {
const accessToken = localStorage.getItem(ACCESS_TOKEN);
if (!accessToken) throw new ResponseError(401, "토큰이 없습니다.");

headers["Authorization"] = accessToken;
}

export const getRoom = async (productId: string): Promise<RoomData> => {
const { data } = await axios.get<ResponseData<RoomData>>(
BASE_URL + END_POINTS.ROOM(productId),
`${BASE_URL}${END_POINTS.ROOM(productId)}`,
{ headers },
);

return data.data;
};
13 changes: 6 additions & 7 deletions src/components/errorBoundary/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@ import { useQueryErrorResetBoundary } from "@tanstack/react-query";
import { ComponentType, ReactNode } from "react";
import { ErrorBoundary, FallbackProps } from "react-error-boundary";
import ErrorFallback from "./ErrorFallback";
import { useLocation } from "react-router-dom";

export interface LocalErrorBoundaryProps {
children: ReactNode;
fallback?: ComponentType<FallbackProps>;
}

const LocalErrorBoundary = ({
children,
fallback,
}: LocalErrorBoundaryProps) => {
const ApiErrorBoundary = ({ children }: LocalErrorBoundaryProps) => {
const { reset } = useQueryErrorResetBoundary();
const { pathname } = useLocation();

return (
<ErrorBoundary
FallbackComponent={fallback ? fallback : ErrorFallback}
FallbackComponent={ErrorFallback}
onReset={reset}
resetKeys={[location.pathname]}
resetKeys={[pathname]}
>
{children}
</ErrorBoundary>
);
};

export default LocalErrorBoundary;
export default ApiErrorBoundary;
2 changes: 1 addition & 1 deletion src/components/errorBoundary/ErrorFallback.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { hexToRgba } from "@utils/hexTorgba";
import styled, { DefaultTheme } from "styled-components";
import { breakpoints } from "@styles/theme";

export const Container = styled.main`
export const ErrorContainer = styled.main`
width: 100%;
height: 100%;
Expand Down
4 changes: 2 additions & 2 deletions src/components/errorBoundary/ErrorFallback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => {
};

return (
<S.Container>
<S.ErrorContainer>
<S.MainWrapper>
<S.LogoWrapper>
<Blank />
Expand All @@ -32,7 +32,7 @@ const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => {
{button}
</S.Button>
</S.BottomWrapper>
</S.Container>
</S.ErrorContainer>
);
};

Expand Down
21 changes: 21 additions & 0 deletions src/components/isLogin/IsLogin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ACCESS_TOKEN } from "@/constants/api";
import useAuthStore from "@/store/authStore";
import { useLayoutEffect } from "react";

interface IsLoginProps {
children: React.ReactNode;
}

const IsLogin = ({ children }: IsLoginProps) => {
const setIsLoggedIn = useAuthStore((state) => state.setIsLoggedIn);

useLayoutEffect(() => {
if (localStorage.getItem(ACCESS_TOKEN)) {
setIsLoggedIn(true);
}
}, [setIsLoggedIn]);

return <>{children}</>;
};

export default IsLogin;
2 changes: 1 addition & 1 deletion src/constants/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const STATUS_CODE = {
} as const;

export const ERROR_CODE = {
NULL_STOCK: 509,
NULL_STOCK: 409,
INVALID_TOKEN: 402,
UNAUTHORIZED_WRITE_TRANSFER: 1002,
UNAUTHORIZED_YANOLJA: 5003,
Expand Down
9 changes: 0 additions & 9 deletions src/constants/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,3 @@ export const PATH = {
PAYMENT: (productId: string) => `/payment/${productId}`,
PAYMENT_SUCCESS: (productId: string) => `/payment/${productId}/success`,
} as const;
// 참고

// EDIT_TRIP: (tripId: string) => `/trip/${tripId}/edit`,
// TRIP: (tripId: string) => `/trip/${tripId}`,
// EXPENSE: (tripId: string) => `/trip/${tripId}/expense`,
// SHARE_TRIP: (tripId: string) => `/trip/share/${tripId}`,
// SHARE_EXPENSE: (tripId: string) => `/trip/share/expense/${tripId}`,
// COMMUNITY_TRIP: (tripId: string) => `/community/trip/${tripId}`,
// COMMUNITY_EXPENSE: (tripId: string) => `/community/trip/expense/${tripId}`,
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/hooks/api/useRoomQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ interface RoomQueryData {
discountRate: string;
}

export const useRoomQuery = (roomId: string) => {
export const useRoomQuery = (roomId: string, isLoggedIn: boolean) => {
return useSuspenseQuery<RoomData, AxiosError, RoomQueryData>({
queryKey: ["room", roomId],
queryFn: () => getRoom(roomId),
queryFn: () => getRoom(roomId, isLoggedIn),
select: (data) => {
const discountRate = calculateDiscount(
data.originalPrice,
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { useEffect, useState } from "react";

interface UseIntersectionObserverProps {
root?: null;
rootMargin?: string;
threshold?: number;
onIntersect: IntersectionObserverCallback;
}

const UseIntersectionObserver = ({
root,
rootMargin = "0px",
threshold = 0.5,
onIntersect,
}: UseIntersectionObserverProps) => {
const [target, setTarget] = useState<HTMLElement | null | undefined>(null);

useEffect(() => {
if (!target) return;

const observer = new IntersectionObserver(onIntersect, {
root,
rootMargin,
threshold,
});
observer.observe(target);

return () => observer.unobserve(target);
}, [onIntersect, root, rootMargin, target, threshold]);

return { setTarget };
};

export default UseIntersectionObserver;
import { useEffect, useState } from "react";

interface UseIntersectionObserverProps {
root?: null;
rootMargin?: string;
threshold?: number;
onIntersect: IntersectionObserverCallback;
}

const UseIntersectionObserver = ({
root,
rootMargin = "0px",
threshold = 0.5,
onIntersect,
}: UseIntersectionObserverProps) => {
const [target, setTarget] = useState<HTMLElement | null | undefined>(null);

useEffect(() => {
if (!target) return;

const observer = new IntersectionObserver(onIntersect, {
root,
rootMargin,
threshold,
});
observer.observe(target);

return () => observer.unobserve(target);
}, [onIntersect, root, rootMargin, target, threshold]);

return { setTarget };
};

export default UseIntersectionObserver;
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import { useEffect, RefObject } from "react";

interface UseOnClickOutsideProps {
ref: RefObject<HTMLElement>;
handler: () => void;
isModalTwoOpen: boolean;
refTwo: RefObject<HTMLElement>;
handlerTwo: () => void;
}
const useOnClickOutside = ({
ref,
handler,
isModalTwoOpen,
refTwo,
handlerTwo,
}: UseOnClickOutsideProps) => {
useEffect(() => {
const listener = (event: MouseEvent | TouchEvent) => {
if (!ref.current || ref.current.contains(event.target as Node)) {
return;
}
if (!isModalTwoOpen) {
handler();
}
};
const listenerTwo = (event: MouseEvent | TouchEvent) => {
if (!refTwo.current || refTwo.current.contains(event.target as Node)) {
return;
}
if (isModalTwoOpen) {
handlerTwo();
}
};
document.addEventListener("mousedown", listener);
document.addEventListener("touchstart", listener);
document.addEventListener("mousedown", listenerTwo);
document.addEventListener("touchstart", listenerTwo);

return () => {
document.removeEventListener("mousedown", listener);
document.removeEventListener("touchstart", listener);
document.removeEventListener("mousedown", listenerTwo);
document.removeEventListener("touchstart", listenerTwo);
};
// eslint-disable-next-line
}, [ref, handler, refTwo, handlerTwo]);
};

export default useOnClickOutside;
import { useEffect, RefObject } from "react";

interface UseOnClickOutsideProps {
ref: RefObject<HTMLElement>;
handler: () => void;
isModalTwoOpen: boolean;
refTwo: RefObject<HTMLElement>;
handlerTwo: () => void;
}
const useOnClickOutside = ({
ref,
handler,
isModalTwoOpen,
refTwo,
handlerTwo,
}: UseOnClickOutsideProps) => {
useEffect(() => {
const listener = (event: MouseEvent | TouchEvent) => {
if (!ref.current || ref.current.contains(event.target as Node)) {
return;
}
if (!isModalTwoOpen) {
handler();
}
};
const listenerTwo = (event: MouseEvent | TouchEvent) => {
if (!refTwo.current || refTwo.current.contains(event.target as Node)) {
return;
}
if (isModalTwoOpen) {
handlerTwo();
}
};
document.addEventListener("mousedown", listener);
document.addEventListener("touchstart", listener);
document.addEventListener("mousedown", listenerTwo);
document.addEventListener("touchstart", listenerTwo);

return () => {
document.removeEventListener("mousedown", listener);
document.removeEventListener("touchstart", listener);
document.removeEventListener("mousedown", listenerTwo);
document.removeEventListener("touchstart", listenerTwo);
};
// eslint-disable-next-line
}, [ref, handler, refTwo, handlerTwo]);
};

export default useOnClickOutside;
5 changes: 2 additions & 3 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import ReactDOM from "react-dom/client";
import { RouterProvider } from "react-router-dom";
import { ThemeProvider } from "styled-components";
// import { worker } from "./mocks/broswer";
import { router } from "./routes/router";
import AppRouter from "./routes/router";
import { GlobalStyle } from "./styles/globalStyle";
import { theme } from "./styles/theme";

Expand All @@ -26,7 +25,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<RouterProvider router={router} />
<AppRouter />
</ThemeProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useConnectAccountMutation } from "@hooks/api/mutation/useConnectAccountMutation";
import { useConnectAccountMutation } from "@/hooks/api/useConnectAccountMutation";
import { useFormContext } from "react-hook-form";

import * as S from "./SubmitButton.style";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import InputField from "@components/inputField/InputField";
import { useValidateEmailMutation } from "@hooks/api/mutation/useValidateEmailMutation";
import { useValidateEmailMutation } from "@/hooks/api/useValidateEmailMutation.ts";
import axios from "axios";
import { useEffect, useState } from "react";
import { useFormContext } from "react-hook-form";
Expand Down
Loading

0 comments on commit 0685ff7

Please sign in to comment.