From 51cc9dd17d2b58094e4541eb0cd1f7870e2422a5 Mon Sep 17 00:00:00 2001 From: hskwon Date: Tue, 14 Oct 2025 14:30:05 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=8D=B0=EB=AA=A8=20URL=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DemoPage 컴포넌트: 토큰 검증 및 상태별 UI - App.tsx: /d/:token 라우트 추가 - 활성/만료/철회/오류 상태 처리 --- src/App.tsx | 52 +++++++------ src/pages/DemoPage.tsx | 168 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 21 deletions(-) create mode 100644 src/pages/DemoPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 635c65e..c8ddb8a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,33 +1,43 @@ import { QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -import { BrowserRouter } from 'react-router-dom' +import { BrowserRouter, Routes, Route } from 'react-router-dom' import { queryClient } from '@/lib/query-client' +import DemoPage from '@/pages/DemoPage' function App() { return ( -
-
-

- SAM React Frontend -

-

- React 프로젝트가 성공적으로 설정되었습니다. -

-
-

설정 완료

-
    -
  • Vite + React + TypeScript
  • -
  • Tailwind CSS with shadcn/ui theming
  • -
  • React Query for server state
  • -
  • Zustand for global state
  • -
  • Axios with interceptors
  • -
  • React Router for routing
  • -
+ + {/* 데모 페이지 */} + } /> + + {/* 홈 페이지 */} + +
+

+ SAM React Frontend +

+

+ React 프로젝트가 성공적으로 설정되었습니다. +

+
+

설정 완료

+
    +
  • Vite + React + TypeScript
  • +
  • Tailwind CSS with shadcn/ui theming
  • +
  • React Query for server state
  • +
  • Zustand for global state
  • +
  • Axios with interceptors
  • +
  • React Router for routing
  • +
  • Demo System (/d/:token)
  • +
+
+
-
-
+ } /> +
diff --git a/src/pages/DemoPage.tsx b/src/pages/DemoPage.tsx new file mode 100644 index 0000000..bb03c4a --- /dev/null +++ b/src/pages/DemoPage.tsx @@ -0,0 +1,168 @@ +import { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import axios from 'axios'; + +interface DemoResponse { + status: 'active' | 'expired' | 'revoked' | 'error'; + message: string; + company?: string; + expires_at?: string; + visit_count?: number; + expired_at?: string; +} + +export default function DemoPage() { + const { token } = useParams<{ token: string }>(); + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchDemoData = async () => { + try { + const response = await axios.get(`http://admin.sam.kr/d/${token}`); + setData(response.data); + } catch (error: any) { + setData(error.response?.data || { + status: 'error', + message: '데모 링크를 확인할 수 없습니다.', + }); + } finally { + setLoading(false); + } + }; + + if (token) { + fetchDemoData(); + } + }, [token]); + + if (loading) { + return ( +
+
+
+

데모 링크 확인 중...

+
+
+ ); + } + + if (!data) { + return ( +
+
+

오류

+

데모 링크를 불러올 수 없습니다.

+
+
+ ); + } + + // 활성 상태 + if (data.status === 'active') { + return ( +
+
+
+
+ + + +
+

+ {data.message} +

+
+
+

고객사

+

{data.company}

+
+
+
+

만료 일시

+

{data.expires_at}

+
+
+

방문 횟수

+

{data.visit_count}회

+
+
+
+
+

SAM 데모 시스템

+

+ 데모 콘텐츠가 여기에 표시됩니다. +

+
+
+
+
+ ); + } + + // 만료/철회/에러 상태 + const statusConfig = { + expired: { + title: '만료된 링크', + color: 'text-orange-600', + bgColor: 'bg-orange-100', + iconColor: 'text-orange-600', + icon: ( + + + + ), + }, + revoked: { + title: '철회된 링크', + color: 'text-red-600', + bgColor: 'bg-red-100', + iconColor: 'text-red-600', + icon: ( + + + + ), + }, + error: { + title: '오류', + color: 'text-gray-600', + bgColor: 'bg-gray-100', + iconColor: 'text-gray-600', + icon: ( + + + + ), + }, + }; + + const config = statusConfig[data.status as keyof typeof statusConfig] || statusConfig.error; + + return ( +
+
+
+
+ {config.icon} +
+
+

+ {config.title} +

+

+ {data.message} +

+ {data.expired_at && ( +
+

만료 일시

+

{data.expired_at}

+
+ )} +

+ 데모 링크가 필요하시면 담당자에게 문의하세요. +

+
+
+ ); +}