diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..54182bc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: CI + +on: + pull_request: + branches: [ develop, main ] + types: [ opened, synchronize, reopened ] + +permissions: + contents: read + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run linting + run: pnpm run lint + + # - name: Run tests + # run: pnpm run test + + - name: Build application + run: pnpm run build + env: + NEXT_PUBLIC_API_BASE_URL: ${{ secrets.NEXT_PUBLIC_API_BASE_URL }} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a8d652d..fac3d93 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -5,6 +5,7 @@ import { QueryProvider } from "@/components/providers/QueryProvider"; import AnalyticsTools from "@/components/common/AnalyticsTools"; export const metadata: Metadata = { + metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'), title: "수상한 녀석들", description: "공모전 출품작 분석 AI 서비스", icons: { diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index d1f35d6..b3ee60e 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, Suspense } from "react"; import { Google, KaKao, Naver } from "../../../public"; import ToolTip from "./_components/Tooltip"; import Header from "@/components/common/Header"; @@ -10,7 +10,8 @@ import { trackGAEvent, GA_EVENT } from "@/libs/ga"; const BACKEND_URL = process.env.NEXT_PUBLIC_BASE_URL; const REDIRECT_BASE_URL = process.env.NEXT_PUBLIC_RIDRECT_BASE_URL || ""; -const Page = () => { +// useSearchParams를 사용하는 컴포넌트를 분리 +function LoginForm() { const [lastProvider, setLastProvider] = useState(null); const [showTooltip, setShowTooltip] = useState(true); const searchParams = useSearchParams(); @@ -21,10 +22,12 @@ const Page = () => { setLastProvider(localStorage.getItem("socialLogin")); } }, []); + const onClose = (e: React.MouseEvent) => { e.stopPropagation(); setShowTooltip(false); }; + return (
@@ -130,6 +133,32 @@ const Page = () => {
); +} + +// 로딩 컴포넌트 +function LoginLoading() { + return ( +
+
+
+
+
+
+

로딩 중...

+
+
+
+
+ ); +} + +// 메인 페이지 컴포넌트 +const Page = () => { + return ( + }> + + + ); }; export default Page;