diff --git a/react-app/src/App.jsx b/react-app/src/App.jsx index 6626e9b..f39bd3d 100644 --- a/react-app/src/App.jsx +++ b/react-app/src/App.jsx @@ -2,6 +2,7 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import OnboardingPage from './pages/OnboardingPage'; import IdentifiedArticlesPage from './pages/IdentifiedArticlesPage'; import AnalysisPage from './pages/AnalysisPage'; +import mockAnalysisDataList from './data/mockData' // Mock 데이터 import export default function App() { return ( @@ -9,7 +10,10 @@ export default function App() { } /> {/* 온보딩 페이지 라우팅 */} } /> {/* 판별 기사 목록 페이지 라우팅 */} - } /> {/* 분석 차트 페이지 라우팅 */} + } // 기본적으로 첫 번째 데이터 표시 + /> {/* 분석 차트 페이지 라우팅 */} ); diff --git a/react-app/src/components/layout/AnalysisPage.module.css b/react-app/src/components/layout/AnalysisPage.module.css index 3fb653c..36853e3 100644 --- a/react-app/src/components/layout/AnalysisPage.module.css +++ b/react-app/src/components/layout/AnalysisPage.module.css @@ -1,57 +1,97 @@ -/* 페이지 전체 배경색을 연한 회색으로 설정 */ +/* 글로벌 색상 변수 */ +:root { + --color-background: #ebebeb; + --color-navy: #002b53; + --color-muted: #6c757d; + --color-white: #ffffff; + --color-border: #dee2e6; +} + +/* 배경색 */ .bg-background { - background-color: #ebebeb; + background-color: var(--color-background); } -/* 네비게이션 바의 배경색을 짙은 네이비로 설정 */ -.bg-navy-900 { - background-color: #002b53; +.bg-navy { + background-color: var(--color-navy); } -/* 텍스트 색상을 흰색으로 설정 */ +/* 텍스트 색상 */ .text-white { - color: white; + color: var(--color-white); } -/* 보조 텍스트(예: 설명글)의 색상을 회색 계열로 설정 */ -.text-muted-foreground { - color: #000000; +.text-muted { + color: var(--color-muted); } -/* 기본적인 테두리 스타일 정의 */ +/* 테두리 */ .border { - border: 1px solid #dee2e6; /* 밝은 회색 테두리 */ + border: 1px solid var(--color-border); } -/* 요소의 모서리를 부드럽게 라운드 처리 */ +/* 둥근 모서리 */ .rounded-lg { - border-radius: 0.5rem; /* 8px 반지름으로 둥글게 설정 */ + border-radius: 0.5rem; } -/* 컨테이너 최대 너비와 가운데 정렬을 설정 */ +/* 레이아웃 */ .container { - max-width: 1200px; /* 컨테이너의 최대 너비 */ - margin: 0 auto; /* 좌우 여백을 자동으로 설정해 가운데 정렬 */ + max-width: 100%; + margin: 0 auto; + padding: 0 1rem; } -/* 플렉스 박스 레이아웃 설정 */ +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1200px; + } +} + +/* 유틸리티 클래스 */ .flex { - display: flex; /* 요소들을 플렉스 박스로 배치 */ + display: flex; +} + +.flex-row { + display: flex; + flex-direction: row; +} + +.flex-col { + display: flex; + flex-direction: column; +} + +.items-center { + align-items: center; +} + +.justify-center { + justify-content: center; } -/* 좌우 여백을 자동으로 설정해 가운데 정렬 */ .mx-auto { margin-left: auto; margin-right: auto; } -/* 요소에 1rem(16px) 패딩을 추가 */ .p-4 { padding: 1rem; } -/* 요소의 아래쪽에 1rem(16px) 간격 추가 */ .mb-4 { margin-bottom: 1rem; } - diff --git a/react-app/src/pages/AnalysisPage.jsx b/react-app/src/pages/AnalysisPage.jsx index 02afc50..35f9690 100644 --- a/react-app/src/pages/AnalysisPage.jsx +++ b/react-app/src/pages/AnalysisPage.jsx @@ -1,12 +1,21 @@ // 뉴스 분석 페이지 구성 +import { useParams } from 'react-router-dom'; // useParams 가져오기 +import { mockAnalysisDataList } from '../data/mockData'; // Mock 데이터 가져오기 import { Button } from "../components/ui/Button"; import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card"; -import { Link } from 'react-router-dom'; // Link 컴포넌트를 사용하기 위해 임포트 -import '../components/layout/AnalysisPage.module.css'; import Navbar from '../components/layout/Navbar.jsx'; -export default function AnalysisPage() { - return ( +const AnalysisPage = () => { + const { id } = useParams(); // URL에서 id 파라미터 가져오기 + const data = mockAnalysisDataList.find((item, index) => index + 1 === parseInt(id, 10)); // ID로 데이터 선택 + + if (!data) { + return
데이터를 찾을 수 없습니다.
; // ID가 유효하지 않을 때 처리 + } + + const { summary, accuracy, originalArticle } = data; + + return (
{/* Navbar 사용 */} @@ -14,98 +23,118 @@ export default function AnalysisPage() { {/* 메인 콘텐츠 영역 */}
- {/* 왼쪽 섹션: 요약 및 분석 카드 */} -
- {/* 요약 박스 */} - - - 뉴스 요약 - - -
-

- 하마스 무장세력이 이스라엘 군인의 시신을 가자지구 거리로 끌고 다녀 양측의 긴장이 고조되었습니다. -

-
- - -
-
-
-
+ {/* 요약 및 분석 섹션 */} + + + + {/* 원본 기사 섹션 */} + +
+
+
+ ); +}; + +export default AnalysisPage; - {/* 분석 결과 카드 */} - - - Analysis Result - - -
-
-
-
-
93%
-
Accuracy
-
-
-
-
-
-
-
- 0-25% -
-
-
- 26-50% -
-
-
- 51-75% -
-
-
- 76-100% -
-
- - +// 요약 섹션 컴포넌트 +const AnalysisSummary = ({ summary }) => { + return ( +
+ + + 뉴스 요약 + + +
+

{summary}

+
+ + +
+
+
+
+ ); +}; - {/* 오른쪽 섹션: 원본 기사 카드 */} - - - What are Israel's Iron Dome, David's Sling, and Arrow missile defenses? - - - {/* next/image 대신 img 태그 사용 */} - Israel missile defense system at night -
-

- Israel uses its elaborate system of air defenses to counter hundreds of missiles and drones launched by Iran on Tuesday night. -

-

What are the different tiers of Israel's missile defence system?

-

- Israel has several air defence systems, each one designed to intercept incoming missiles at different altitudes and distances... -

- - Read More - +// 분석 결과 섹션 컴포넌트 +const AnalysisResult = ({ accuracy }) => { + return ( + + + Analysis Result + + +
+
+
+
+
{accuracy}%
+
Accuracy
- - +
+
- -
- ); -} +
+ +
+
+
+ ); +}; + +// 정확도 범례 컴포넌트 +const AccuracyLegend = () => { + const legends = [ + { color: "bg-gray-300", label: "0-25%" }, + { color: "bg-blue-300", label: "26-50%" }, + { color: "bg-blue-500", label: "51-75%" }, + { color: "bg-blue-700", label: "76-100%" }, + ]; + + return ( + <> + {legends.map((legend, index) => ( +
+
+ {legend.label} +
+ ))} + + ); +}; + +// 원본 기사 섹션 컴포넌트 +const OriginalArticle = ({ article }) => { + const { title, image, description, extraDetails, link } = article; + + return ( + + + {title} + + + {title} +
+

{description}

+

{extraDetails}

+ + Read More + +
+
+
+ ); +};