From b5200f6a9d40240388b0f032aff9981bb88c747d Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 13:33:40 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EC=95=B1=20=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=9C=A0=EB=8F=84=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app-download/page.tsx | 98 +++++++++++++++++++ src/proxy.ts | 2 +- src/widgets/layout/admin-layout/ui/Header.tsx | 7 +- 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/app/app-download/page.tsx diff --git a/src/app/app-download/page.tsx b/src/app/app-download/page.tsx new file mode 100644 index 0000000..c664cd5 --- /dev/null +++ b/src/app/app-download/page.tsx @@ -0,0 +1,98 @@ +import Link from "next/link"; +import React from "react"; +import { WasherLogo } from "@/lib"; +import AuthLayout from "@/widgets/layout/auth-layout/ui/AuthLayout"; + +export default function AppDownloadPage() { + return ( + +
+
+
+ + + Washer + +
+
+ +
+

+ 앱으로 다운로드하여 이용해주세요 +

+

+ 이제 편하게 모바일로 새로워진 washer를 이용해보세요! +

+
+ +
+ + + + +
+ + Download on the + + + App Store + +
+
+ + + +
+ + GET IT ON + + + Google Play + +
+
+
+ +
+ + 로그인 페이지로 돌아가기 + +
+
+
+ ); +} diff --git a/src/proxy.ts b/src/proxy.ts index 481a882..39af9af 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -5,7 +5,7 @@ export async function proxy(request: NextRequest) { const { pathname } = request.nextUrl; const accessToken = request.cookies.get(COOKIE_KEYS.ACCESS_TOKEN)?.value; - if (pathname.startsWith("/api/") || pathname === "/sign-in") { + if (pathname.startsWith("/api/") || pathname === "/sign-in" || pathname === "/app-download") { return NextResponse.next(); } diff --git a/src/widgets/layout/admin-layout/ui/Header.tsx b/src/widgets/layout/admin-layout/ui/Header.tsx index 281b674..24a2ab4 100644 --- a/src/widgets/layout/admin-layout/ui/Header.tsx +++ b/src/widgets/layout/admin-layout/ui/Header.tsx @@ -27,9 +27,12 @@ export default function Header() { useEffect(() => { if (myInfo && myInfo.role === "USER") { toast.error("관리자만 접근 가능합니다."); - handleLogout(); + queryClient.clear(); + deleteCookie(COOKIE_KEYS.ACCESS_TOKEN); + deleteCookie(COOKIE_KEYS.REFRESH_TOKEN); + window.location.href = "/app-download"; } - }, [myInfo, handleLogout]); + }, [myInfo, queryClient]); return (
From 779247857ec169c887a29bf5acb2b30be3523b7c Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 13:36:26 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EC=97=AD=ED=95=A0=20=ED=8C=90?= =?UTF-8?q?=EB=B3=84=20=EB=A1=9C=EB=94=A9=20=EC=8A=A4=ED=94=BC=EB=84=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin-layout/ui/AdminLayout/index.tsx | 31 +++++++++++++++++-- src/widgets/layout/admin-layout/ui/Header.tsx | 10 +----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx b/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx index 37d5bbe..8fba9d1 100644 --- a/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx +++ b/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx @@ -1,20 +1,47 @@ "use client"; -import { useQuery } from "@tanstack/react-query"; -import type { PropsWithChildren } from "react"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { useEffect, type PropsWithChildren } from "react"; +import { toast } from "sonner"; +import { COOKIE_KEYS } from "@/shared"; +import { deleteCookie } from "@/shared/utils/cookies"; +import { useGetMyInfo } from "@/entities/user"; import { getDashboardSummary, mapDashboard } from "@/entities/dashboard"; import DashboardTabs from "../DashboardTabs"; import Header from "../Header"; import SummaryCards from "../SummaryCards"; export default function AdminLayout({ children }: PropsWithChildren) { + const queryClient = useQueryClient(); + const { data: myInfoData, isLoading: isMyInfoLoading } = useGetMyInfo(); + const myInfo = myInfoData?.data; + + useEffect(() => { + if (myInfo && myInfo.role === "USER") { + toast.error("관리자만 접근 가능합니다."); + queryClient.clear(); + deleteCookie(COOKIE_KEYS.ACCESS_TOKEN); + deleteCookie(COOKIE_KEYS.REFRESH_TOKEN); + window.location.href = "/app-download"; + } + }, [myInfo, queryClient]); + const { data, isLoading, isError } = useQuery({ queryKey: ["dashboard", "summary"], queryFn: getDashboardSummary, + enabled: !!myInfo && myInfo.role !== "USER", }); const summaryItems = data ? mapDashboard(data) : []; + if (isMyInfoLoading || (myInfo && myInfo.role === "USER")) { + return ( +
+
+
+ ); + } + return (
diff --git a/src/widgets/layout/admin-layout/ui/Header.tsx b/src/widgets/layout/admin-layout/ui/Header.tsx index 24a2ab4..fbb11fe 100644 --- a/src/widgets/layout/admin-layout/ui/Header.tsx +++ b/src/widgets/layout/admin-layout/ui/Header.tsx @@ -24,15 +24,7 @@ export default function Header() { window.location.reload(); }, [queryClient]); - useEffect(() => { - if (myInfo && myInfo.role === "USER") { - toast.error("관리자만 접근 가능합니다."); - queryClient.clear(); - deleteCookie(COOKIE_KEYS.ACCESS_TOKEN); - deleteCookie(COOKIE_KEYS.REFRESH_TOKEN); - window.location.href = "/app-download"; - } - }, [myInfo, queryClient]); + return (
From 8ac7bbd3527a291ce0e6f121e920e527325c2076 Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 13:37:55 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=EC=9C=A0=EB=8F=84=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=B0=98=EC=9D=91=ED=98=95=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app-download/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app-download/page.tsx b/src/app/app-download/page.tsx index c664cd5..ff32e58 100644 --- a/src/app/app-download/page.tsx +++ b/src/app/app-download/page.tsx @@ -6,7 +6,7 @@ import AuthLayout from "@/widgets/layout/auth-layout/ui/AuthLayout"; export default function AppDownloadPage() { return ( -
+
From 836e1bddfb4278c9e9aa9ce65ac479af0a3c07dc Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 13:56:32 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app-download/page.tsx | 6 ++++-- src/widgets/layout/admin-layout/ui/Header.tsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/app-download/page.tsx b/src/app/app-download/page.tsx index ff32e58..4200e40 100644 --- a/src/app/app-download/page.tsx +++ b/src/app/app-download/page.tsx @@ -1,5 +1,5 @@ import Link from "next/link"; -import React from "react"; + import { WasherLogo } from "@/lib"; import AuthLayout from "@/widgets/layout/auth-layout/ui/AuthLayout"; @@ -30,7 +30,7 @@ export default function AppDownloadPage() { href="https://apps.apple.com/app/6760886865" className="flex-1 flex items-center justify-center gap-4 rounded-xl bg-[#1D1D1F] hover:bg-black text-white py-3.5 px-4 transition-all duration-200 shadow-sm hover:shadow-md hover:-translate-y-0.5" > - +
@@ -52,6 +52,8 @@ export default function AppDownloadPage() { aria-hidden="true" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg" + role="img" + aria-label="Google Play Logo" > diff --git a/src/widgets/layout/admin-layout/ui/Header.tsx b/src/widgets/layout/admin-layout/ui/Header.tsx index fbb11fe..297778e 100644 --- a/src/widgets/layout/admin-layout/ui/Header.tsx +++ b/src/widgets/layout/admin-layout/ui/Header.tsx @@ -3,7 +3,7 @@ import { useQueryClient } from "@tanstack/react-query"; import { LogOut } from "lucide-react"; import Image from "next/image"; -import { useCallback, useEffect } from "react"; +import { useCallback } from "react"; import { toast } from "sonner"; import { useGetMyInfo } from "@/entities/user"; import { COOKIE_KEYS } from "@/shared"; From e2c14321a00cecd5882144f22049191618c482af Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 13:59:29 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin-layout/ui/AdminLayout/index.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx b/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx index 8fba9d1..858db3f 100644 --- a/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx +++ b/src/widgets/layout/admin-layout/ui/AdminLayout/index.tsx @@ -13,10 +13,19 @@ import SummaryCards from "../SummaryCards"; export default function AdminLayout({ children }: PropsWithChildren) { const queryClient = useQueryClient(); - const { data: myInfoData, isLoading: isMyInfoLoading } = useGetMyInfo(); + const { data: myInfoData, isLoading: isMyInfoLoading, isError: isMyInfoError } = useGetMyInfo(); const myInfo = myInfoData?.data; useEffect(() => { + if (isMyInfoError) { + toast.error("로그인이 만료되었거나 유효하지 않습니다. 다시 로그인해주세요."); + queryClient.clear(); + deleteCookie(COOKIE_KEYS.ACCESS_TOKEN); + deleteCookie(COOKIE_KEYS.REFRESH_TOKEN); + window.location.href = "/sign-in"; + return; + } + if (myInfo && myInfo.role === "USER") { toast.error("관리자만 접근 가능합니다."); queryClient.clear(); @@ -24,17 +33,17 @@ export default function AdminLayout({ children }: PropsWithChildren) { deleteCookie(COOKIE_KEYS.REFRESH_TOKEN); window.location.href = "/app-download"; } - }, [myInfo, queryClient]); + }, [myInfo, isMyInfoError, queryClient]); const { data, isLoading, isError } = useQuery({ queryKey: ["dashboard", "summary"], queryFn: getDashboardSummary, - enabled: !!myInfo && myInfo.role !== "USER", + enabled: !!myInfo && myInfo.role !== "USER" && !isMyInfoError, }); const summaryItems = data ? mapDashboard(data) : []; - if (isMyInfoLoading || (myInfo && myInfo.role === "USER")) { + if (isMyInfoLoading || isMyInfoError || (myInfo && myInfo.role === "USER") || (!myInfo && !isMyInfoError)) { return (
From fe269ed2a0734ef4adbb78d8b6f891d5962a964e Mon Sep 17 00:00:00 2001 From: LeeSangHyeok0731 Date: Thu, 11 Jun 2026 14:05:04 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=EB=A7=81=ED=81=AC=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app-download/page.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/app-download/page.tsx b/src/app/app-download/page.tsx index 4200e40..b293791 100644 --- a/src/app/app-download/page.tsx +++ b/src/app/app-download/page.tsx @@ -28,6 +28,8 @@ export default function AppDownloadPage() {