diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 45dd2855..4a8d28ac 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -7,6 +7,7 @@ permissions: on: pull_request: branches: [develop] + types: [opened, synchronize, reopened] jobs: preview: @@ -14,6 +15,9 @@ jobs: steps: - name: Git Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -36,7 +40,13 @@ jobs: NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} - name: Build - run: pnpm -filter=web build + run: | + echo "GITHUB_EVENT_NAME=${{ github.event_name }}" >> apps/web/.env.production.local + echo "GITHUB_EVENT_NUMBER=${{ github.event.pull_request.number }}" >> apps/web/.env.production.local + pnpm -filter=web build + env: + GITHUB_EVENT_NAME: ${{ github.event_name }} + GITHUB_EVENT_NUMBER: ${{ github.event.pull_request.number }} - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/apps/mobile/app/(route)/dashboard.tsx b/apps/mobile/app/(route)/dashboard.tsx index 6e96b635..bf0a8625 100644 --- a/apps/mobile/app/(route)/dashboard.tsx +++ b/apps/mobile/app/(route)/dashboard.tsx @@ -3,13 +3,16 @@ import WebView, { WebViewMessageEvent } from "react-native-webview"; import { ROUTES } from "@/constants/routes"; import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; import { getWebViewApiUrl } from "@/utils/getWebViewApiUrl"; +import { parseMessage } from "@/utils/parseMessage"; export default function DashboardScreen() { const baseUrl = getWebViewApiUrl(); const handleNavigationActions = useHandleNavigationActions(); const requestOnMessage = (e: WebViewMessageEvent) => { - handleNavigationActions(e); + const { type, data } = parseMessage(e); + + handleNavigationActions({ type, data }); }; return ; diff --git a/apps/mobile/app/(route)/meetings.tsx b/apps/mobile/app/(route)/meetings.tsx index 1883a399..d6a442fa 100644 --- a/apps/mobile/app/(route)/meetings.tsx +++ b/apps/mobile/app/(route)/meetings.tsx @@ -3,13 +3,16 @@ import WebView, { WebViewMessageEvent } from "react-native-webview"; import { ROUTES } from "@/constants/routes"; import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; import { getWebViewApiUrl } from "@/utils/getWebViewApiUrl"; +import { parseMessage } from "@/utils/parseMessage"; export default function MeetingsScreen() { const baseUrl = getWebViewApiUrl(); const handleNavigationActions = useHandleNavigationActions(); const requestOnMessage = (e: WebViewMessageEvent) => { - handleNavigationActions(e); + const { type, data } = parseMessage(e); + + handleNavigationActions({ type, data }); }; return ; diff --git a/apps/mobile/app/(route)/seats.tsx b/apps/mobile/app/(route)/seats.tsx index 08c04fb2..f363efc6 100644 --- a/apps/mobile/app/(route)/seats.tsx +++ b/apps/mobile/app/(route)/seats.tsx @@ -3,13 +3,16 @@ import WebView, { WebViewMessageEvent } from "react-native-webview"; import { ROUTES } from "@/constants/routes"; import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; import { getWebViewApiUrl } from "@/utils/getWebViewApiUrl"; +import { parseMessage } from "@/utils/parseMessage"; export default function SeatsScreen() { const baseUrl = getWebViewApiUrl(); const handleNavigationActions = useHandleNavigationActions(); const requestOnMessage = (e: WebViewMessageEvent) => { - handleNavigationActions(e); + const { type, data } = parseMessage(e); + + handleNavigationActions({ type, data }); }; return ; diff --git a/apps/mobile/app/(route)/settings.tsx b/apps/mobile/app/(route)/settings.tsx index 7fe7c530..a368796a 100644 --- a/apps/mobile/app/(route)/settings.tsx +++ b/apps/mobile/app/(route)/settings.tsx @@ -3,13 +3,17 @@ import WebView, { WebViewMessageEvent } from "react-native-webview"; import { ROUTES } from "@/constants/routes"; import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; import { getWebViewApiUrl } from "@/utils/getWebViewApiUrl"; +import { parseMessage } from "@/utils/parseMessage"; export default function SettingsScreen() { const baseUrl = getWebViewApiUrl(); const handleNavigationActions = useHandleNavigationActions(); const requestOnMessage = (e: WebViewMessageEvent) => { - handleNavigationActions(e); + const { type, data } = parseMessage(e); + + handleNavigationActions({ type, data }); }; + return ; } diff --git a/apps/web/app/_components/AuthGuard.tsx b/apps/web/app/_components/AuthGuard.tsx index 778b58f8..4c579830 100644 --- a/apps/web/app/_components/AuthGuard.tsx +++ b/apps/web/app/_components/AuthGuard.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { PAGE_NAME } from "@ui/src/utils/constants/pageNames"; -import { useRouter } from "next/navigation"; +import { useRouter, usePathname } from "next/navigation"; import { useAuthStore } from "@/app/store/useAuthStore"; import { createWebViewEventListener } from "../../lib/bridge/createWebViewEventListener"; import { parseWebViewAuthMessage } from "../../lib/bridge/parseWebViewAuthMessage"; @@ -11,10 +11,10 @@ import SignInForm from "./SignInForm"; export default function AuthGuard(): JSX.Element | null { const router = useRouter(); + const pathname = usePathname(); const [isLoading, setIsLoading] = useState(true); const { isLoggedIn } = useAuthStore(); const { isIOSWebView, isAndroidWebView } = useDetectWebView(); - const webViewEventListener = createWebViewEventListener({ isIOSWebView, isAndroidWebView }); useEffect(() => { @@ -23,14 +23,25 @@ export default function AuthGuard(): JSX.Element | null { }, []); useEffect(() => { - if (isLoggedIn) { - router.replace(PAGE_NAME.DASHBOARD); + if (!isLoggedIn) { + setIsLoading(false); + return; + } + + if (pathname === "/" && typeof window !== "undefined") { + const urlParams = new URLSearchParams(window.location.search); + const prNumber = urlParams.get("pr"); + + if (prNumber) { + router.replace(`/dashboard?pr=${prNumber}`); + } else { + router.replace(PAGE_NAME.DASHBOARD); + } } setIsLoading(false); - }, [isLoggedIn, router]); + }, [isLoggedIn, router, pathname]); if (isLoading) return null; - return isLoggedIn ? null : ; } diff --git a/apps/web/app/dashboard/_components/DashboardSection.tsx b/apps/web/app/dashboard/_components/DashboardSection.tsx index d5add773..43c1c08e 100644 --- a/apps/web/app/dashboard/_components/DashboardSection.tsx +++ b/apps/web/app/dashboard/_components/DashboardSection.tsx @@ -33,6 +33,7 @@ export default function DashboardSection({ data = [] }: DashboardSectionProps): return (
+

Preview Test

내 회의


{upcomingMeetings.length > 0 ? ( diff --git a/apps/web/components/Gnb/GnbMenu.tsx b/apps/web/components/Gnb/GnbMenu.tsx index 433d94bc..58c74b79 100644 --- a/apps/web/components/Gnb/GnbMenu.tsx +++ b/apps/web/components/Gnb/GnbMenu.tsx @@ -33,8 +33,22 @@ export default function GnbMenu({ isAdmin }: GnbMenuProps): JSX.Element | null { const { push } = useAppRouter(); const { isWebView } = useDetectWebView(); + const getPrNumber = (): string | null => { + if (typeof window === "undefined") return null; + + const urlParams = new URLSearchParams(window.location.search); + + return urlParams.get("pr"); + }; + + const getUrlWithPR = (path: string): string => { + const prNumber = getPrNumber(); + + return prNumber ? `${path}?pr=${prNumber}` : path; + }; + const handleButtonClick = (path: string): void => { - push(path); + push(getUrlWithPR(path)); }; return ( @@ -57,7 +71,7 @@ export default function GnbMenu({ isAdmin }: GnbMenuProps): JSX.Element | null { }, } : { - href, + href: getUrlWithPR(href), })} className={cn("h-full justify-start md:h-40 md:w-full md:px-0 md:py-0", index === 3 && "block md:hidden")} variant="Text" @@ -82,7 +96,7 @@ export default function GnbMenu({ isAdmin }: GnbMenuProps): JSX.Element | null { {ADMIN_ITEMS.map(({ href, name, icon: Icon }) => { const isActive = pathname === href; return ( - +