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: 라우팅 개선 #91

Merged
merged 3 commits into from
Dec 29, 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
20 changes: 14 additions & 6 deletions app/admin/(components)/CreateTheme/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { FormEvent } from "react";

import "../../(style)/createTheme.modules.sass";
import { useRouter } from "next/navigation";

import { usePostTheme } from "@/mutations/postTheme";
import { useCreateThemeValue } from "@/components/atoms/createTheme.atom";
import { useSelectedThemeWrite } from "@/components/atoms/selectedTheme.atom";
import { setSelectedThemeId } from "@/utils/localStorage";

import CreateThemeTitle from "./CreateThemeTitle";
import CreateThemeBody from "./CreateThemeBody";
Expand All @@ -13,7 +15,7 @@ export default function CreateTheme() {
const createTheme = useCreateThemeValue();
const setSelectedTheme = useSelectedThemeWrite();
const { mutateAsync: postTheme } = usePostTheme();

const router = useRouter();
const handleKeyDownSubmit = async (e: FormEvent) => {
e.preventDefault();
const isDisabled =
Expand All @@ -24,10 +26,16 @@ export default function CreateTheme() {
if (isDisabled) {
return;
}
const response = await postTheme(createTheme);
const { id } = response.data.data;
if (id) {
setSelectedTheme(createTheme);
try {
const response = await postTheme(createTheme);
const { id } = response.data.data;
router.push(`/admin?themeId=${encodeURIComponent(id)}`);
if (id) {
setSelectedTheme(createTheme);
setSelectedThemeId(id);
}
} catch (err) {
console.error("Login failed:", err);
}
};

Expand Down
15 changes: 10 additions & 5 deletions app/admin/(components)/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";
import Image from "next/image";
import classNames from "classnames";
import { useRouter, useSearchParams } from "next/navigation";
Expand All @@ -13,11 +13,9 @@ import {
import {
getSelectedThemeId,
getStatus,
removeAccessToken,
removeThemeId,
} from "@/utils/localStorage";
import { useSelectedThemeReset } from "@/components/atoms/selectedTheme.atom";
import { useIsLoggedInWrite } from "@/components/atoms/account.atom";
import { useDrawerState } from "@/components/atoms/drawer.atom";
import useModal from "@/hooks/useModal";

Expand All @@ -39,7 +37,7 @@ interface Props {
export default function Sidebar(props: Props) {
const router = useRouter();
const resetSelectedTheme = useSelectedThemeReset();
// const setIsLoggedIn = useIsLoggedInWrite();

const [drawer, setDrawer] = useDrawerState();
const { open } = useModal();

Expand All @@ -58,6 +56,13 @@ export default function Sidebar(props: Props) {
// removeAccessToken();
// setIsLoggedIn(false);
// };
useEffect(() => {
if (selectedThemeId && selectedThemeId !== "0")
router.push(
`/admin?themeId=${encodeURIComponent(selectedThemeId)}
`
);
}, [selectedThemeId]);

const navigateToNewTheme = () => {
resetSelectedTheme();
Expand Down Expand Up @@ -111,7 +116,7 @@ export default function Sidebar(props: Props) {
<button
type="button"
className={classNames("sidebar__theme-button", {
selected: selectedThemeId === theme.id?.toString() && params,
selected: selectedThemeId === theme.id.toString(),
})}
onClick={() => handleSelectTheme(theme)}
>
Expand Down
13 changes: 3 additions & 10 deletions app/admin/Admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ type Theme = {
};

function Admin() {
const { data: categories = [] } = useGetThemeList();
const [isLoading, setIsLoading] = useState<boolean>(true);
const { data: categories = [], isLoading } = useGetThemeList();

const isLoggedIn = useCheckSignIn();

const [selectedTheme, setSelectedTheme] = useSelectedTheme();
Expand All @@ -30,13 +30,6 @@ function Admin() {
const [toast, setToast] = useToastInfo();
const router = useRouter();

useEffect(() => {
if (categories.length > 0 && selectedTheme.id === 0) {
setSelectedTheme(categories[categories.length - 1]);
setIsLoading(false);
}
}, [categories, selectedTheme, setSelectedTheme]);

const handleClickSelected = (theme: Theme) => {
setSelectedTheme(theme);
setSelectedThemeId(theme.id);
Expand Down Expand Up @@ -64,7 +57,7 @@ function Admin() {
isOpen: toast.isOpen,
};

if (!isLoggedIn || !isLoading) {
if (!isLoggedIn || isLoading) {
return <Loader />;
}

Expand Down
57 changes: 6 additions & 51 deletions app/components/RequireAuth/RequireAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,7 @@
import React, { ReactNode, useEffect, useMemo, useState } from "react";
import { useRouter, usePathname } from "next/navigation";

import { useTokenRefresh } from "@/mutations/useRefresh";
import { useGetThemeList } from "@/queries/getThemeList";
import {
useCurrentTheme,
useCurrentThemeReset,
} from "@/components/atoms/currentTheme.atom";
import { useSelectedThemeReset } from "@/components/atoms/selectedTheme.atom";
import { useIsLoggedIn } from "@/components/atoms/account.atom";
import { getSelectedThemeId } from "@/utils/localStorage";
import * as S from "@/home/HomeView.styled";
import Header from "@/components/common/Header/Header";
import MainDrawer from "@/components/common/Drawer/Drawer";

import Mobile from "../Mobile/Mobile";

Expand All @@ -25,66 +14,32 @@ function RequireAuth({
children,
}: RequireAuthProps): React.ReactElement | null {
const [isLoggedIn, setIsLoggedIn] = useIsLoggedIn();
const [currentTheme, setCurrentTheme] = useCurrentTheme();
const resetCurrentTheme = useCurrentThemeReset();
const resetSelectedTheme = useSelectedThemeReset();

const router = useRouter();
const pathname = usePathname();
const allowUnauthPaths = useMemo(() => ["/", "/trial", "/signup"], []);
const allowUnauthPaths = useMemo(() => ["/", "/signup"], []);
const [isMobile, setIsMobile] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const { data: categories = [] } = useGetThemeList();
const { refreshToken, error } = useTokenRefresh();

useEffect(() => {
if (typeof window !== "undefined") {
const { userAgent } = window.navigator;
const mobileRegex =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i;
setIsMobile(mobileRegex.test(userAgent));
setIsLoading(false);
}
}, []);

useEffect(() => {
if (categories.length > 0) {
setCurrentTheme(categories.map(({ id, title }) => ({ id, title })));
} else {
resetCurrentTheme();
resetSelectedTheme();
}
}, [categories, setCurrentTheme]);
useEffect(() => {
const selectedThemeId = getSelectedThemeId();

if (!isLoggedIn && !allowUnauthPaths.includes(pathname)) {
router.push("/login");
} else if (isLoggedIn && pathname === "/") {
} else if (isLoggedIn) {
router.push(pathname);
} else if (isLoggedIn && currentTheme.length === 0) {
router.push("/admin");
} else if (selectedThemeId !== "0" && isLoggedIn) {
router.push(`/admin?themeId=${selectedThemeId}`);
}
}, [isLoggedIn, currentTheme, router, allowUnauthPaths, pathname]);

if (isLoading) {
return <></>;
}
}, [isLoggedIn, pathname]);

if (isMobile && !allowUnauthPaths.includes(pathname)) return <Mobile />;

if (!isLoggedIn) return <>{children}</>;
if (isLoggedIn && (pathname === "/" || "/admin")) return <>{children}</>;

return (
<S.Wrapper>
<MainDrawer {...{ categories }} />
<S.Cont component="main">
<Header />
{children}
</S.Cont>
</S.Wrapper>
);
return <>{children}</>;
}

export default RequireAuth;
4 changes: 0 additions & 4 deletions app/components/common/Dialog-new/Hint-Dialog-new/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,4 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
);
});

Dialog.defaultProps = {
type: "",
};

export default Dialog;
4 changes: 0 additions & 4 deletions app/components/common/Dialog-new/Image-Dialog-new/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,4 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
);
});

Dialog.defaultProps = {
type: "",
};

export default Dialog;
4 changes: 0 additions & 4 deletions app/components/common/Dialog-new/Noti-Dialog-new/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,4 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
);
});

Dialog.defaultProps = {
type: "",
};

export default Dialog;
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,4 @@ const PreviewDialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
);
});

PreviewDialog.defaultProps = {
type: "",
};

export default PreviewDialog;
26 changes: 16 additions & 10 deletions app/components/common/Dialog-new/Theme-Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { forwardRef, useRef } from "react";
import { SubmitHandler, useForm } from "react-hook-form";
import Image from "next/image";
import { useRouter } from "next/navigation";

import { usePutTheme } from "@/mutations/putTheme";
import { useDeleteTheme } from "@/mutations/deleteTheme";
Expand Down Expand Up @@ -58,8 +59,8 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {

const { mutateAsync: putTheme } = usePutTheme();
const { mutateAsync: deleteTheme } = useDeleteTheme();

const onSubmit: SubmitHandler<FormValues> = () => {
const router = useRouter();
const onSubmit: SubmitHandler<FormValues> = async () => {
const { id } = selectedTheme;

const submitData = {
Expand All @@ -68,12 +69,21 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
};

if (type === "put") {
putTheme(submitData);
setSelectedTheme(submitData);
try {
await putTheme(submitData);
setSelectedTheme(submitData);
} catch (error) {
console.error("Error updating theme:", error);
}
} else if (type === "delete") {
deleteTheme({ id });
resetSelectedTheme();
try {
await deleteTheme({ id });
router.push(`/admin`);
} catch (error) {
console.error("Error deleting theme:", error);
}
}

close();
resetCreateTheme();

Expand Down Expand Up @@ -124,8 +134,4 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
);
});

Dialog.defaultProps = {
type: "",
};

export default Dialog;
44 changes: 41 additions & 3 deletions app/hooks/useAnalytics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
import { getAnalytics, logEvent as firebaseLogEvent } from "firebase/analytics";
import {
getAnalytics,
logEvent as firebaseLogEvent,
isSupported,
} from "firebase/analytics";
import { useEffect, useState } from "react";

import { isDevMode } from "@/consts/env";

const useAnalytics = () => {
const analytics = getAnalytics();
const [analytics, setAnalytics] = useState<ReturnType<
typeof getAnalytics
> | null>(null);

useEffect(() => {
if (typeof window !== "undefined") {
isSupported()
.then((supported) => {
if (supported) {
const analyticsInstance = getAnalytics();
setAnalytics(analyticsInstance);
} else {
console.warn(
"Firebase Analytics is not supported in this environment."
);
}
})
.catch((error) => {
console.error("Failed to check Firebase Analytics support:", error);
});
}
}, []);

const logEvent = (eventName: string, eventParam: Record<string, any>) => {
if (isDevMode) return;
firebaseLogEvent(analytics, eventName, eventParam);

if (analytics) {
try {
firebaseLogEvent(analytics, eventName, eventParam);
} catch (error) {
console.error("Failed to log event:", error);
}
} else {
console.warn(
"Analytics instance is not initialized. Event not logged:",
eventName
);
}
};

return { logEvent };
Expand Down
2 changes: 1 addition & 1 deletion app/hooks/useClickOutside.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useEffect, RefObject } from "react";
* @param {boolean} ignoreSiblings - 형제 요소 클릭 시에도 닫힐지 여부
*/
function useClickOutside(
ref: RefObject<HTMLElement | HTMLElement[]>,
ref: React.RefObject<HTMLElement | HTMLElement[] | HTMLFormElement | null>,
handler: (event: MouseEvent) => void,
isActive = true,
targetIndex = 0,
Expand Down
Loading
Loading