Phase 0: React environment setup + project initialization
구현 사항: 1. React + TypeScript 마이그레이션 시작 - package.json: React, Redux Toolkit, TanStack Query, shadcn/ui dependencies 추가 - vite.config.js: React 플러그인 + Phase 5/7 API 프록시 추가 - tsconfig.json, tsconfig.node.json 추가 2. Redux 스토어 설정 - stores/ontologySlice.ts: 온톨로지 상태 관리 - stores/crawlSlice.ts: 크롤링 진행 상태 - stores/uiSlice.ts: UI 상태 3. 리액트 진입점 및 기본 컴포넌트 - src/main.tsx: React 앱 초기화 - src/App.tsx: 라우팅 설정 (대시보드, 온보딩, 소스, 크롤, 검증) - 5개 페이지 컴포넌트 (placeholder) 4. 스타일 및 설정 - tailwind.config.js: Tailwind 설정 - src/styles/globals.css: 글로벌 스타일 - postcss.config.js: PostCSS 설정 - src/i18n.ts: i18next 다국어 설정 - src/lib/queryClient.ts: React Query 설정 5. TypeScript 타입 정의 - src/stores/slices: 각 Redux slice의 TypeScript 타입 프로젝트 구조: crawler_platform/app/web/frontend/ ├── src/ │ ├── main.tsx (React 진입점) │ ├── App.tsx (라우팅) │ ├── pages/ (4개 페이지 컴포넌트) │ ├── stores/ (Redux 스토어 + slices) │ ├── lib/ (유틸리티) │ ├── styles/ (CSS) │ └── i18n.ts (다국어 설정) ├── index.html (업데이트: React root) ├── package.json (의존성 추가) ├── vite.config.js (React 플러그인) ├── tsconfig.json (TypeScript 설정) ├── tailwind.config.js (Tailwind 설정) └── postcss.config.js (PostCSS 설정) 다음 단계: - npm install로 의존성 설치 - Phase 1: 온톨로지 업로더 구현 - Phase 1: 참고 사이트 매니저 구현 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function ConfigureSourcesPage() {
|
||||
const navigate = useNavigate();
|
||||
const { projectId } = useParams();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
{t("Configure Reference Sites")}
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{t("Step 2 of 4: Add 5-20 reference sites for knowledge extraction")}
|
||||
</p>
|
||||
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<p className="text-gray-500">{t("No sites added yet")}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 mt-6">
|
||||
<button
|
||||
onClick={() => navigate("/onboard")}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition"
|
||||
>
|
||||
{t("Back")}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate(`/crawl/${projectId}`)}
|
||||
className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
|
||||
>
|
||||
{t("Next")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
40
crawler_platform/app/web/frontend/src/pages/CrawlPage.tsx
Normal file
40
crawler_platform/app/web/frontend/src/pages/CrawlPage.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function CrawlPage() {
|
||||
const navigate = useNavigate();
|
||||
const { projectId } = useParams();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
{t("Build Ontology")}
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{t("Step 3 of 4: Auto-crawl and build ontology with Phase 5 + 7")}
|
||||
</p>
|
||||
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<p className="text-gray-500">{t("Crawl pipeline will appear here")}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 mt-6">
|
||||
<button
|
||||
onClick={() => navigate(`/sources/${projectId}`)}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition"
|
||||
>
|
||||
{t("Back")}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate(`/review/${projectId}`)}
|
||||
className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
|
||||
>
|
||||
{t("Review Results")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Plus, BarChart3, Settings } from "lucide-react";
|
||||
|
||||
export default function DashboardPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<div className="max-w-7xl mx-auto px-4 py-12">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900">
|
||||
{t("Ontology Builder")}
|
||||
</h1>
|
||||
<p className="text-gray-600 mt-2">
|
||||
{t("Build and manage domain ontologies with AI-powered extraction")}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => navigate("/onboard")}
|
||||
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
{t("New Project")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<BarChart3 className="w-8 h-8 text-blue-600 mb-4" />
|
||||
<h3 className="font-semibold text-lg mb-2">{t("Quick Start")}</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
{t("Get started by uploading your domain ontology")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<Settings className="w-8 h-8 text-green-600 mb-4" />
|
||||
<h3 className="font-semibold text-lg mb-2">{t("Phase 5 GraphRAG")}</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
{t("Intelligent entity resolution and deduplication")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<Settings className="w-8 h-8 text-purple-600 mb-4" />
|
||||
<h3 className="font-semibold text-lg mb-2">{t("Phase 7 LLM")}</h3>
|
||||
<p className="text-gray-600 text-sm">
|
||||
{t("AI-powered extraction and validation")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function OnboardingPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 flex items-center justify-center p-4">
|
||||
<div className="bg-white rounded-lg shadow-xl p-8 max-w-2xl w-full">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
{t("Upload Ontology")}
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{t("Step 1 of 4: Upload your domain ontology (YAML, JSON, or OWL)")}
|
||||
</p>
|
||||
|
||||
<div className="border-2 border-dashed border-blue-300 rounded-lg p-8 text-center bg-blue-50 mb-6">
|
||||
<p className="text-gray-600">
|
||||
{t("Drag and drop your ontology file here, or click to browse")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<button
|
||||
onClick={() => navigate("/")}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition"
|
||||
>
|
||||
{t("Cancel")}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate("/sources/demo-project")}
|
||||
className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
|
||||
>
|
||||
{t("Next")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
51
crawler_platform/app/web/frontend/src/pages/ReviewPage.tsx
Normal file
51
crawler_platform/app/web/frontend/src/pages/ReviewPage.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function ReviewPage() {
|
||||
const navigate = useNavigate();
|
||||
const { projectId } = useParams();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
{t("Review & Validate")}
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{t("Step 4 of 4: Review extracted entities and relations")}
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-6 mb-6">
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<h3 className="font-semibold text-lg mb-2">
|
||||
{t("Phase 5 Entity Merges")}
|
||||
</h3>
|
||||
<p className="text-gray-500">{t("Review merge suggestions")}</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<h3 className="font-semibold text-lg mb-2">
|
||||
{t("Phase 7 Extractions")}
|
||||
</h3>
|
||||
<p className="text-gray-500">{t("Validate extracted claims")}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<button
|
||||
onClick={() => navigate(`/crawl/${projectId}`)}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition"
|
||||
>
|
||||
{t("Back")}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate("/")}
|
||||
className="flex-1 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition"
|
||||
>
|
||||
{t("Complete")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user