diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f217521 --- /dev/null +++ b/.env.example @@ -0,0 +1,19 @@ +# Google Gemini AI 配置 (必需) +VITE_GEMINI_API_KEY=your_gemini_api_key_here +VITE_GEMINI_MODEL=gemini-2.5-flash +VITE_GEMINI_TIMEOUT_MS=25000 + +# Supabase 配置 (可选,用于数据持久化) +VITE_SUPABASE_URL=https://your-project.supabase.co +VITE_SUPABASE_ANON_KEY=your-anon-key-here + +# GitHub 集成 (可选,用于仓库分析) +VITE_GITHUB_TOKEN=your_github_token_here + +# 应用配置 +VITE_APP_ID=xcodereviewer + +# 分析配置 +VITE_MAX_ANALYZE_FILES=40 +VITE_LLM_CONCURRENCY=2 +VITE_LLM_GAP_MS=500 \ No newline at end of file diff --git a/README.md b/README.md index bf50b98..bc5d345 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # XCodeReviewer - 您的智能代码审计伙伴 🚀
- VerifyVision-Pro Logo + XCodeReviewer Logo
@@ -25,25 +25,25 @@ 在快节奏的软件开发中,保证代码质量至关重要。传统代码审计工具规则死板、效率低下,而人工审计则耗时耗力。XCodeReviewer 借助 Google Gemini AI 的强大能力,彻底改变了代码审查的方式: -- **🤖 AI 驱动的深度分析**:超越传统静态分析,理解代码意图,发现深层逻辑问题。 -- **🎯 多维度、全方位评估**:从**安全性**、**性能**、**可维护性**到**代码风格**,提供 360 度无死角的质量评估。 -- **💡 清晰、可行的修复建议**:独创 **What-Why-How** 模式,不仅告诉您“是什么”问题,还解释“为什么”,并提供“如何修复”的具体代码示例。 -- **⚡ 实时反馈,即时提升**:无论是代码片段还是整个代码仓库,都能获得快速、准确的分析结果。 -- **✨ 现代化、高颜值的用户界面**:基于 React + TypeScript 构建,提供流畅、直观的操作体验。 +- **AI 驱动的深度分析**:超越传统静态分析,理解代码意图,发现深层逻辑问题。 +- **多维度、全方位评估**:从**安全性**、**性能**、**可维护性**到**代码风格**,提供 360 度无死角的质量评估。 +- **清晰、可行的修复建议**:独创 **What-Why-How** 模式,不仅告诉您“是什么”问题,还解释“为什么”,并提供“如何修复”的具体代码示例。 +- **实时反馈,即时提升**:无论是代码片段还是整个代码仓库,都能获得快速、准确的分析结果。 +- **现代化、高颜值的用户界面**:基于 React + TypeScript 构建,提供流畅、直观的操作体验。 ## 🎬 项目演示 ### 主要功能界面 -#### 📊 智能仪表盘 +#### 智能仪表盘 ![智能仪表盘](public/images/example1.png) *实时展示项目统计、质量趋势和系统性能,提供全面的代码审计概览* -#### ⚡ 即时分析 +#### 即时分析 ![即时分析](public/images/example3.png) *支持代码片段快速分析,提供详细的 What-Why-How 解释和修复建议* -#### 🚀 项目管理 +#### 项目管理 ![项目管理](public/images/example2.png) *集成 GitHub/GitLab 仓库,支持多语言项目审计和批量代码分析* @@ -78,11 +78,11 @@ 3. **配置环境变量** ```bash - # 创建环境变量文件 - touch .env + # 复制环境变量模板 + cp .env.example .env ``` - 在 `.env` 文件中添加以下配置: + 编辑 `.env` 文件,配置必要的环境变量: ```env # Google Gemini AI 配置 (必需) VITE_GEMINI_API_KEY=your_gemini_api_key_here @@ -93,8 +93,16 @@ VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_ANON_KEY=your-anon-key-here + # GitHub 集成 (可选,用于仓库分析) + VITE_GITHUB_TOKEN=your_github_token_here + # 应用配置 VITE_APP_ID=xcodereviewer + + # 分析配置 + VITE_MAX_ANALYZE_FILES=40 + VITE_LLM_CONCURRENCY=2 + VITE_LLM_GAP_MS=500 ``` 4. **启动开发服务器** @@ -112,7 +120,7 @@ 2. 创建新的 API Key 3. 将 API Key 添加到 `.env` 文件中的 `VITE_GEMINI_API_KEY` -#### Supabase 配置 +#### Supabase 配置(可选) 1. 访问 [Supabase](https://supabase.com/) 创建新项目 2. 在项目设置中获取 URL 和匿名密钥 3. 运行数据库迁移脚本: @@ -120,6 +128,7 @@ # 在 Supabase SQL 编辑器中执行 cat supabase/migrations/full_schema.sql ``` +4. 如果不配置 Supabase,系统将以演示模式运行,数据不会持久化 ## ✨ 核心功能 @@ -188,8 +197,12 @@ ``` XCodeReviewer/ ├── src/ -│ ├── components/ # React 组件 -│ │ ├── common/ # 通用组件 (Header, Footer, PageMeta) +│ ├── app/ # 应用配置 +│ │ ├── App.tsx # 主应用组件 +│ │ ├── main.tsx # 应用入口点 +│ │ └── routes.tsx # 路由配置 +│ ├── components/ # React 组件 +│ │ ├── layout/ # 布局组件 (Header, Footer, PageMeta) │ │ ├── ui/ # UI 组件库 (基于 Radix UI) │ │ └── debug/ # 调试组件 │ ├── pages/ # 页面组件 @@ -198,20 +211,25 @@ XCodeReviewer/ │ │ ├── InstantAnalysis.tsx # 即时分析 │ │ ├── AuditTasks.tsx # 审计任务 │ │ └── AdminDashboard.tsx # 系统管理 -│ ├── services/ # 服务层 -│ │ ├── codeAnalysis.ts # AI 代码分析引擎 -│ │ ├── repoScan.ts # 仓库扫描服务 -│ │ └── repoZipScan.ts # ZIP 文件扫描 -│ ├── db/ # 数据库配置 -│ │ └── supabase.ts # Supabase 客户端和 API -│ ├── types/ # TypeScript 类型定义 -│ ├── hooks/ # 自定义 React Hooks -│ ├── lib/ # 工具函数 -│ └── routes.tsx # 路由配置 +│ ├── features/ # 功能模块 +│ │ ├── analysis/ # 分析相关服务 +│ │ │ └── services/ # AI 代码分析引擎 +│ │ └── projects/ # 项目相关服务 +│ │ └── services/ # 仓库扫描、ZIP 文件扫描 +│ ├── shared/ # 共享工具 +│ │ ├── config/ # 配置文件 (数据库、环境变量) +│ │ ├── types/ # TypeScript 类型定义 +│ │ ├── hooks/ # 自定义 React Hooks +│ │ ├── utils/ # 工具函数 +│ │ └── constants/ # 常量定义 +│ └── assets/ # 静态资源 +│ └── styles/ # 样式文件 ├── supabase/ │ └── migrations/ # 数据库迁移文件 -├── public/ # 静态资源 -└── docs/ # 文档 +├── public/ +│ └── images/ # 图片资源 +├── scripts/ # 构建和设置脚本 +└── rules/ # 代码规则配置 ``` ## 🎯 使用指南 diff --git a/README_EN.md b/README_EN.md index e787d86..001dee5 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,4 +1,8 @@ -# XCodeReviewer - Your Intelligent Code Review Partner 🚀 +# XCodeReviewer - Your Intelligent Code Audit Partner 🚀 + +
+ XCodeReviewer Logo +

@@ -14,19 +18,18 @@ [![Vite](https://img.shields.io/badge/Vite-5.1.4-646CFF.svg)](https://vitejs.dev/) [![Supabase](https://img.shields.io/badge/Supabase-3ECF8E.svg)](https://supabase.com/) [![Google Gemini](https://img.shields.io/badge/Google%20Gemini-4285F4.svg)](https://ai.google.dev/) -[![Star History](https://api.star-history.com/svg?repos=lintsinghua/XCodeReviewer&type=Date)](https://star-history.com/#lintsinghua/XCodeReviewer&Date) -**XCodeReviewer** is a modern code auditing platform powered by Large Language Models (LLM), designed to provide developers with intelligent, comprehensive, and in-depth code quality analysis and review services. +**XCodeReviewer** is a modern code audit platform powered by Large Language Models (LLM), designed to provide developers with intelligent, comprehensive, and in-depth code quality analysis and review services. ## 🌟 Why Choose XCodeReviewer? -In the fast-paced world of software development, ensuring code quality is crucial. Traditional code auditing tools are rigid and inefficient, while manual auditing is time-consuming and labor-intensive. XCodeReviewer leverages the powerful capabilities of Google Gemini AI to revolutionize the way code review is conducted: +In the fast-paced world of software development, ensuring code quality is crucial. Traditional code audit tools are rigid and inefficient, while manual audits are time-consuming and labor-intensive. XCodeReviewer leverages the powerful capabilities of Google Gemini AI to revolutionize the way code reviews are conducted: -- **🤖 AI-Driven Deep Analysis**: Beyond traditional static analysis, understanding code intent and discovering deep logical issues. +- **🤖 AI-Driven Deep Analysis**: Beyond traditional static analysis, understands code intent and discovers deep logical issues. - **🎯 Multi-dimensional, Comprehensive Assessment**: From **security**, **performance**, **maintainability** to **code style**, providing 360-degree quality evaluation. -- **💡 Clear, Actionable Fix Suggestions**: Innovative **What-Why-How** pattern that not only tells you "what" the problem is, but also explains "why" and provides "how to fix" with specific code examples. -- **⚡ Real-time Feedback, Instant Improvement**: Whether it's code snippets or entire code repositories, you can get fast and accurate analysis results. -- **✨ Modern, High-Quality User Interface**: Built with React + TypeScript, providing smooth and intuitive user experience. +- **💡 Clear, Actionable Fix Suggestions**: Innovative **What-Why-How** approach that not only tells you "what" the problem is, but also explains "why" and provides "how to fix" with specific code examples. +- **⚡ Real-time Feedback, Instant Improvement**: Whether it's code snippets or entire repositories, get fast and accurate analysis results. +- **✨ Modern, Beautiful User Interface**: Built with React + TypeScript, providing a smooth and intuitive user experience. ## 🎬 Project Demo @@ -34,77 +37,15 @@ In the fast-paced world of software development, ensuring code quality is crucia #### 📊 Intelligent Dashboard ![Intelligent Dashboard](public/images/example1.png) -*Real-time display of project statistics, quality trends and system performance, providing comprehensive code audit overview* +*Real-time display of project statistics, quality trends, and system performance, providing comprehensive code audit overview* #### ⚡ Instant Analysis ![Instant Analysis](public/images/example3.png) -*Support for rapid code snippet analysis, providing detailed What-Why-How explanations and fix suggestions* +*Support for quick code snippet analysis with detailed What-Why-How explanations and fix suggestions* #### 🚀 Project Management ![Project Management](public/images/example2.png) -*Integration with GitHub/GitLab repositories, supporting multi-language project auditing and batch code analysis* - -## ✨ Core Features - -

-🚀 Project Management - -- **One-click Repository Integration**: Seamless integration with mainstream platforms like GitHub, GitLab. -- **Multi-language "Full Suite" Support**: Covering popular languages like JavaScript, TypeScript, Python, Java, Go, Rust. -- **Flexible Branch Auditing**: Support for precise analysis of specified code branches. -
- -
-⚡ Instant Analysis - -- **Code Snippet "Paste & Go"**: Directly paste code in the web interface and get instant analysis results. -- **10+ Language Instant Support**: Meeting your diverse code analysis needs. -- **Millisecond Response**: Quickly get code quality scores and optimization suggestions. -
- -
-🧠 Intelligent Auditing - -- **AI Deep Code Understanding**: Based on Google Gemini, providing intelligent analysis beyond keyword matching. -- **Five Core Dimension Detection**: - - 🐛 **Potential Bugs**: Accurately capture logic errors, boundary conditions, and null pointer issues. - - 🔒 **Security Vulnerabilities**: Identify security risks like SQL injection, XSS, sensitive information leakage. - - ⚡ **Performance Bottlenecks**: Discover inefficient algorithms, memory leaks, and unreasonable async operations. - - 🎨 **Code Style**: Ensure code follows industry best practices and unified standards. - - 🔧 **Maintainability**: Evaluate code readability, complexity, and modularity. -
- -
-💡 Explainable Analysis (What-Why-How) - -- **What (What is it)**: Clearly point out problems in the code. -- **Why (Why)**: Detailed explanation of potential risks and impacts this problem may bring. -- **How (How to fix)**: Provide specific, directly usable code fix examples. -- **Precise Code Location**: Quickly jump to the line and column where the problem is located. -
- -
-📊 Visual Reports - -- **Code Quality Dashboard**: Provide 0-100 comprehensive quality assessment, making code health status clear at a glance. -- **Multi-dimensional Issue Statistics**: Classify and count issues by type and severity. -- **Quality Trend Analysis**: Display code quality changes over time through charts. -
- -## 🛠️ Tech Stack - -| Category | Technology | Description | -| :--- | :--- | :--- | -| **Frontend Framework** | `React 18` `TypeScript` `Vite` | Modern frontend development stack with hot reload and type safety | -| **UI Components** | `Tailwind CSS` `Radix UI` `Lucide React` | Responsive design, accessibility, rich icon library | -| **Data Visualization** | `Recharts` | Professional chart library supporting multiple chart types | -| **Routing** | `React Router v6` | Single-page application routing solution | -| **State Management** | `React Hooks` `Sonner` | Lightweight state management and notification system | -| **AI Engine** | `Google Gemini 2.5 Flash` | Powerful large language model for code analysis | -| **Backend Service** | `Supabase` `PostgreSQL` | Full-stack backend-as-a-service with real-time database | -| **HTTP Client** | `Axios` `Ky` | Modern HTTP request libraries | -| **Code Quality** | `Biome` `Ast-grep` `TypeScript` | Code formatting, static analysis, and type checking | -| **Build Tools** | `Vite` `PostCSS` `Autoprefixer` | Fast build tools and CSS processing | +*Integrated GitHub/GitLab repositories, supporting multi-language project audits and batch code analysis* ## 🚀 Quick Start @@ -137,11 +78,11 @@ In the fast-paced world of software development, ensuring code quality is crucia 3. **Configure environment variables** ```bash - # Create environment variables file - touch .env + # Copy environment template + cp .env.example .env ``` - Add the following configuration to the `.env` file: + Edit the `.env` file and configure the necessary environment variables: ```env # Google Gemini AI Configuration (Required) VITE_GEMINI_API_KEY=your_gemini_api_key_here @@ -152,8 +93,16 @@ In the fast-paced world of software development, ensuring code quality is crucia VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_ANON_KEY=your-anon-key-here - # App Configuration + # GitHub Integration (Optional, for repository analysis) + VITE_GITHUB_TOKEN=your_github_token_here + + # Application Configuration VITE_APP_ID=xcodereviewer + + # Analysis Configuration + VITE_MAX_ANALYZE_FILES=40 + VITE_LLM_CONCURRENCY=2 + VITE_LLM_GAP_MS=500 ``` 4. **Start development server** @@ -169,49 +118,121 @@ In the fast-paced world of software development, ensuring code quality is crucia #### Google Gemini API Key 1. Visit [Google AI Studio](https://makersuite.google.com/app/apikey) 2. Create a new API Key -3. Add the API Key to `VITE_GEMINI_API_KEY` in the `.env` file +3. Add the API Key to `VITE_GEMINI_API_KEY` in your `.env` file -#### Supabase Configuration +#### Supabase Configuration (Optional) 1. Visit [Supabase](https://supabase.com/) to create a new project 2. Get the URL and anonymous key from project settings -3. Run the database migration script: +3. Run database migration scripts: ```bash - # Execute in Supabase SQL editor + # Execute in Supabase SQL Editor cat supabase/migrations/full_schema.sql ``` +4. If Supabase is not configured, the system will run in demo mode without data persistence + +## ✨ Core Features + +
+🚀 Project Management + +- **One-click Repository Integration**: Seamlessly connect with GitHub, GitLab, and other mainstream platforms. +- **Multi-language "Full Stack" Support**: Covers popular languages like JavaScript, TypeScript, Python, Java, Go, Rust, and more. +- **Flexible Branch Auditing**: Support for precise analysis of specified code branches. +
+ +
+⚡ Instant Analysis + +- **Code Snippet "Quick Paste"**: Directly paste code in the web interface for immediate analysis results. +- **10+ Language Instant Support**: Meet your diverse code analysis needs. +- **Millisecond Response**: Quickly get code quality scores and optimization suggestions. +
+ +
+🧠 Intelligent Auditing + +- **AI Deep Code Understanding**: Based on Google Gemini, providing intelligent analysis beyond keyword matching. +- **Five Core Detection Dimensions**: + - 🐛 **Potential Bugs**: Precisely capture logical errors, boundary conditions, and null pointer issues. + - 🔒 **Security Vulnerabilities**: Identify SQL injection, XSS, sensitive information leakage, and other security risks. + - ⚡ **Performance Bottlenecks**: Discover inefficient algorithms, memory leaks, and unreasonable asynchronous operations. + - 🎨 **Code Style**: Ensure code follows industry best practices and unified standards. + - 🔧 **Maintainability**: Evaluate code readability, complexity, and modularity. +
+ +
+💡 Explainable Analysis (What-Why-How) + +- **What**: Clearly identify problems in the code. +- **Why**: Detailed explanation of potential risks and impacts the problem may cause. +- **How**: Provide specific, directly usable code fix examples. +- **Precise Code Location**: Quickly jump to the problematic line and column. +
+ +
+📊 Visual Reports + +- **Code Quality Dashboard**: Provides comprehensive quality assessment from 0-100, making code health status clear at a glance. +- **Multi-dimensional Issue Statistics**: Classify and count issues by type and severity. +- **Quality Trend Analysis**: Display code quality changes over time through charts. +
+ +## 🛠️ Tech Stack + +| Category | Technology | Description | +| :--- | :--- | :--- | +| **Frontend Framework** | `React 18` `TypeScript` `Vite` | Modern frontend development stack with hot reload and type safety | +| **UI Components** | `Tailwind CSS` `Radix UI` `Lucide React` | Responsive design, accessibility, rich icon library | +| **Data Visualization** | `Recharts` | Professional chart library supporting multiple chart types | +| **Routing** | `React Router v6` | Single-page application routing solution | +| **State Management** | `React Hooks` `Sonner` | Lightweight state management and notification system | +| **AI Engine** | `Google Gemini 2.5 Flash` | Powerful large language model supporting code analysis | +| **Backend Service** | `Supabase` `PostgreSQL` | Full-stack backend-as-a-service with real-time database | +| **HTTP Client** | `Axios` `Ky` | Modern HTTP request libraries | +| **Code Quality** | `Biome` `Ast-grep` `TypeScript` | Code formatting, static analysis, and type checking | +| **Build Tools** | `Vite` `PostCSS` `Autoprefixer` | Fast build tools and CSS processing | ## 📁 Project Structure ``` XCodeReviewer/ ├── src/ -│ ├── components/ # React Components -│ │ ├── common/ # Common Components (Header, Footer, PageMeta) -│ │ ├── ui/ # UI Component Library (Based on Radix UI) -│ │ └── debug/ # Debug Components -│ ├── pages/ # Page Components +│ ├── app/ # Application configuration +│ │ ├── App.tsx # Main application component +│ │ ├── main.tsx # Application entry point +│ │ └── routes.tsx # Route configuration +│ ├── components/ # React components +│ │ ├── layout/ # Layout components (Header, Footer, PageMeta) +│ │ ├── ui/ # UI component library (based on Radix UI) +│ │ └── debug/ # Debug components +│ ├── pages/ # Page components │ │ ├── Dashboard.tsx # Dashboard -│ │ ├── Projects.tsx # Project Management -│ │ ├── InstantAnalysis.tsx # Instant Analysis -│ │ ├── AuditTasks.tsx # Audit Tasks -│ │ └── AdminDashboard.tsx # System Management -│ ├── services/ # Service Layer -│ │ ├── codeAnalysis.ts # AI Code Analysis Engine -│ │ ├── repoScan.ts # Repository Scanning Service -│ │ └── repoZipScan.ts # ZIP File Scanning -│ ├── db/ # Database Configuration -│ │ └── supabase.ts # Supabase Client and API -│ ├── types/ # TypeScript Type Definitions -│ ├── hooks/ # Custom React Hooks -│ ├── lib/ # Utility Functions -│ └── routes.tsx # Route Configuration +│ │ ├── Projects.tsx # Project management +│ │ ├── InstantAnalysis.tsx # Instant analysis +│ │ ├── AuditTasks.tsx # Audit tasks +│ │ └── AdminDashboard.tsx # System management +│ ├── features/ # Feature modules +│ │ ├── analysis/ # Analysis related services +│ │ │ └── services/ # AI code analysis engine +│ │ └── projects/ # Project related services +│ │ └── services/ # Repository scanning, ZIP file scanning +│ ├── shared/ # Shared utilities +│ │ ├── config/ # Configuration files (database, environment) +│ │ ├── types/ # TypeScript type definitions +│ │ ├── hooks/ # Custom React Hooks +│ │ ├── utils/ # Utility functions +│ │ └── constants/ # Constants definition +│ └── assets/ # Static assets +│ └── styles/ # Style files ├── supabase/ -│ └── migrations/ # Database Migration Files -├── public/ # Static Assets -└── docs/ # Documentation +│ └── migrations/ # Database migration files +├── public/ +│ └── images/ # Image resources +├── scripts/ # Build and setup scripts +└── rules/ # Code rules configuration ``` -## 🎯 User Guide +## 🎯 Usage Guide ### Instant Code Analysis 1. Visit the `/instant-analysis` page @@ -224,12 +245,12 @@ XCodeReviewer/ 1. Visit the `/projects` page 2. Click "New Project" to create a project 3. Configure repository URL and scan parameters -4. Start code audit tasks +4. Start code audit task 5. View audit results and issue statistics ### Audit Tasks -1. Create audit tasks in project details page -2. Select scan branch and exclude patterns +1. Create audit tasks in project detail page +2. Select scan branch and exclusion patterns 3. Configure analysis depth and scope 4. Monitor task execution status 5. View detailed issue reports @@ -245,23 +266,27 @@ pnpm build # Preview build results pnpm preview -# Code checking +# Code linting pnpm lint ``` ### Environment Variables + | Variable | Required | Description | |----------|----------|-------------| -| `VITE_GEMINI_API_KEY` | ✅ | Google Gemini API Key | -| `VITE_GEMINI_MODEL` | ❌ | AI Model Name (default: gemini-2.5-flash) | -| `VITE_GEMINI_TIMEOUT_MS` | ❌ | Request Timeout (default: 25000ms) | -| `VITE_SUPABASE_URL` | ❌ | Supabase Project URL | -| `VITE_SUPABASE_ANON_KEY` | ❌ | Supabase Anonymous Key | -| `VITE_APP_ID` | ❌ | App Identifier (default: xcodereviewer) | +| `VITE_GEMINI_API_KEY` | ✅ | Google Gemini API key | +| `VITE_GEMINI_MODEL` | ❌ | AI model name (default: gemini-2.5-flash) | +| `VITE_GEMINI_TIMEOUT_MS` | ❌ | Request timeout (default: 25000ms) | +| `VITE_SUPABASE_URL` | ❌ | Supabase project URL | +| `VITE_SUPABASE_ANON_KEY` | ❌ | Supabase anonymous key | +| `VITE_APP_ID` | ❌ | Application identifier (default: xcodereviewer) | +| `VITE_MAX_ANALYZE_FILES` | ❌ | Maximum files to analyze (default: 40) | +| `VITE_LLM_CONCURRENCY` | ❌ | LLM concurrency limit (default: 2) | +| `VITE_LLM_GAP_MS` | ❌ | Gap between LLM requests (default: 500ms) | ## 🤝 Contributing -We warmly welcome all forms of contributions! Whether it's submitting issues, creating PRs, or improving documentation, every contribution is crucial to us. Please contact us for detailed information. +We warmly welcome all forms of contributions! Whether it's submitting issues, creating PRs, or improving documentation, every contribution is important to us. Please contact us for detailed information. ### Development Workflow @@ -271,19 +296,6 @@ We warmly welcome all forms of contributions! Whether it's submitting issues, cr 4. Push to the branch (`git push origin feature/AmazingFeature`) 5. Create a **Pull Request** -#### 4. Build Failure -**Problem**: `pnpm build` command fails -**Solution**: -```bash -# Clear cache -pnpm clean -rm -rf node_modules -pnpm install - -# Check TypeScript type errors -pnpm type-check -``` - ## 🙏 Acknowledgments - **[Google Gemini AI](https://ai.google.dev/)**: Providing powerful AI analysis capabilities @@ -291,14 +303,15 @@ pnpm type-check - **[Radix UI](https://www.radix-ui.com/)**: Providing accessible UI components - **[Tailwind CSS](https://tailwindcss.com/)**: Providing modern CSS framework - **[Recharts](https://recharts.org/)**: Providing professional chart components -- And all the authors of the open source software used in this project! +- And all the authors of open source software used in this project! ## 📞 Contact Us - **Project Link**: [https://github.com/lintsinghua/XCodeReviewer](https://github.com/lintsinghua/XCodeReviewer) -- **Issue Feedback**: [Issues](https://github.com/lintsinghua/XCodeReviewer/issues) -- **Email**: tsinghuaiiilove@gmail.com +- **Issue Reports**: [Issues](https://github.com/lintsinghua/XCodeReviewer/issues) +- **Author Email**: tsinghuaiiilove@gmail.com --- -⭐ If this project is helpful to you, please give us a **Star**! Your support is the driving force for our continuous progress! +⭐ If this project helps you, please give us a **Star**! Your support is our motivation to keep moving forward! +[![Star History](https://api.star-history.com/svg?repos=lintsinghua/XCodeReviewer&type=Date)](https://star-history.com/#lintsinghua/XCodeReview \ No newline at end of file diff --git a/components.json b/components.json index 7dfce35..4f86a62 100644 --- a/components.json +++ b/components.json @@ -1,10 +1,9 @@ { - "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": false, "tsx": true, "tailwind": { - "config": "", + "config": "config/tailwind.config.js", "css": "src/index.css", "baseColor": "slate", "cssVariables": true, @@ -18,4 +17,4 @@ "hooks": "@/hooks" }, "iconLibrary": "lucide" -} \ No newline at end of file +} diff --git a/index.html b/index.html index b6c9d18..13297cb 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,10 @@ + XCodeReviewer
- + diff --git a/package.json b/package.json index ae64810..db3f13f 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,18 @@ { - "name": "miaoda-react-admin", + "name": "xcode-reviewer", "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview --strictPort --port 5173", - "lint": "tsgo -p tsconfig.check.json; biome lint --only=correctness/noUndeclaredDependencies; ast-grep scan" + "lint": "tsgo -p tsconfig.check.json; biome lint --only=correctness/noUndeclaredDependencies; ast-grep scan", + "lint:fix": "biome check --apply .", + "type-check": "tsc --noEmit", + "format": "biome format --write .", + "clean": "rm -rf dist node_modules/.vite", + "setup": "node scripts/setup.js || ./scripts/setup.sh", + "analyze": "vite build --mode analyze" }, "dependencies": { "@google/generative-ai": "^0.24.1", @@ -82,6 +88,7 @@ "globals": "^15.14.0", "postcss": "^8.5.2", "tailwindcss": "^3.4.11", + "terser": "^5.44.0", "typescript": "~5.7.2", "vite": "^5.1.4", "vite-plugin-svgr": "^4.3.0" diff --git a/postcss.config.js b/postcss.config.js index 2aa7205..fbe14a4 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -}; +}; \ No newline at end of file diff --git a/scripts/check-setup.js b/scripts/check-setup.js new file mode 100644 index 0000000..790488a --- /dev/null +++ b/scripts/check-setup.js @@ -0,0 +1,102 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +console.log('🔍 检查项目设置...'); + +// 检查必要文件 +const requiredFiles = [ + 'src/main.tsx', + 'src/App.tsx', + 'src/index.css', + 'src/components/common/PageMeta.tsx', + 'src/components/common/Header.tsx', + 'src/components/common/Footer.tsx', + 'src/pages/Dashboard.tsx', + 'src/pages/Projects.tsx', + 'src/pages/InstantAnalysis.tsx', + 'src/pages/AuditTasks.tsx', + 'src/pages/ProjectDetail.tsx', + 'src/pages/TaskDetail.tsx', + 'src/pages/AdminDashboard.tsx', + 'src/services/codeAnalysis.ts', + 'src/services/repoScan.ts', + 'src/services/repoZipScan.ts', + 'src/db/supabase.ts', + 'src/types/types.ts', + 'src/lib/utils.ts', + 'src/routes.tsx', + 'package.json', + 'vite.config.ts', + 'tailwind.config.js', + 'tsconfig.json', + 'tsconfig.app.json' +]; + +let missingFiles = []; + +for (const file of requiredFiles) { + if (!fs.existsSync(file)) { + missingFiles.push(file); + } +} + +if (missingFiles.length > 0) { + console.log('❌ 缺少以下文件:'); + missingFiles.forEach(file => console.log(` - ${file}`)); + process.exit(1); +} else { + console.log('✅ 所有必要文件都存在'); +} + +// 检查环境变量文件 +if (!fs.existsSync('.env') && !fs.existsSync('.env.example')) { + console.log('⚠️ 缺少环境变量文件'); +} else { + console.log('✅ 环境变量文件存在'); +} + +// 检查node_modules +if (!fs.existsSync('node_modules')) { + console.log('❌ 缺少 node_modules,请运行 npm install'); + process.exit(1); +} else { + console.log('✅ 依赖已安装'); +} + +// 检查关键依赖 +const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); +const requiredDeps = [ + 'react', + 'react-dom', + 'react-router-dom', + '@google/generative-ai', + '@supabase/supabase-js', + 'tailwindcss', + 'vite', + 'typescript' +]; + +let missingDeps = []; +for (const dep of requiredDeps) { + if (!packageJson.dependencies[dep] && !packageJson.devDependencies[dep]) { + missingDeps.push(dep); + } +} + +if (missingDeps.length > 0) { + console.log('❌ 缺少以下依赖:'); + missingDeps.forEach(dep => console.log(` - ${dep}`)); + process.exit(1); +} else { + console.log('✅ 所有关键依赖都存在'); +} + +console.log(''); +console.log('🎉 项目设置检查完成!'); +console.log(''); +console.log('📝 下一步:'); +console.log(' 1. 确保 .env 文件中配置了 VITE_GEMINI_API_KEY'); +console.log(' 2. 运行 npm run dev 启动开发服务器'); +console.log(' 3. 在浏览器中访问 http://localhost:5173'); \ No newline at end of file diff --git a/scripts/setup.bat b/scripts/setup.bat new file mode 100644 index 0000000..9974548 --- /dev/null +++ b/scripts/setup.bat @@ -0,0 +1,124 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +echo 🚀 XCodeReviewer 项目设置开始... + +REM 检查 Node.js 版本 +echo 📋 检查 Node.js 版本... +node -v >nul 2>&1 +if errorlevel 1 ( + echo ❌ 未找到 Node.js,请先安装 Node.js 18+ + pause + exit /b 1 +) + +for /f "tokens=1 delims=." %%a in ('node -v') do ( + set NODE_MAJOR=%%a + set NODE_MAJOR=!NODE_MAJOR:~1! +) + +if !NODE_MAJOR! LSS 18 ( + echo ❌ Node.js 版本过低,需要 18+,当前版本: + node -v + pause + exit /b 1 +) + +echo ✅ Node.js 版本检查通过: +node -v + +REM 检查包管理器 +echo 📦 检查包管理器... +pnpm -v >nul 2>&1 +if not errorlevel 1 ( + set PKG_MANAGER=pnpm + echo ✅ 使用 pnpm + goto install_deps +) + +yarn -v >nul 2>&1 +if not errorlevel 1 ( + set PKG_MANAGER=yarn + echo ✅ 使用 yarn + goto install_deps +) + +npm -v >nul 2>&1 +if not errorlevel 1 ( + set PKG_MANAGER=npm + echo ✅ 使用 npm + goto install_deps +) + +echo ❌ 未找到包管理器,请安装 npm、yarn 或 pnpm +pause +exit /b 1 + +:install_deps +REM 安装依赖 +echo 📥 安装项目依赖... +%PKG_MANAGER% install + +REM 检查环境变量文件 +echo 🔧 检查环境变量配置... +if not exist ".env" ( + if exist ".env.example" ( + copy ".env.example" ".env" >nul + echo ✅ 已创建 .env 文件,请编辑配置必要的环境变量 + echo. + echo 📝 必需配置的环境变量: + echo VITE_GEMINI_API_KEY - Google Gemini API 密钥 + echo. + echo 📝 可选配置的环境变量: + echo VITE_SUPABASE_URL - Supabase 项目 URL + echo VITE_SUPABASE_ANON_KEY - Supabase 匿名密钥 + echo VITE_GITHUB_TOKEN - GitHub 访问令牌 + echo. + echo ⚠️ 请在启动项目前配置 VITE_GEMINI_API_KEY + ) else ( + echo ❌ 未找到 .env.example 文件 + pause + exit /b 1 + ) +) else ( + echo ✅ .env 文件已存在 +) + +REM 检查 Gemini API Key +if exist ".env" ( + findstr /C:"VITE_GEMINI_API_KEY=your_gemini_api_key_here" .env >nul + if not errorlevel 1 ( + echo ⚠️ 请配置 Google Gemini API Key: + echo 1. 访问 https://makersuite.google.com/app/apikey + echo 2. 创建 API Key + echo 3. 在 .env 文件中设置 VITE_GEMINI_API_KEY + ) else ( + findstr /C:"VITE_GEMINI_API_KEY=" .env >nul + if not errorlevel 1 ( + echo ✅ Gemini API Key 已配置 + ) else ( + echo ⚠️ 请在 .env 文件中配置 VITE_GEMINI_API_KEY + ) + ) +) + +echo. +echo 🎉 项目设置完成! +echo. +echo 📚 接下来的步骤: +echo 1. 编辑 .env 文件,配置必要的环境变量 +echo 2. 运行 '%PKG_MANAGER% dev' 启动开发服务器 +echo 3. 在浏览器中访问 http://localhost:5173 +echo. +echo 📖 更多信息请查看: +echo - README.md - 项目介绍和使用指南 +echo - DEPLOYMENT.md - 部署指南 +echo - FEATURES.md - 功能特性详解 +echo. +echo 🆘 需要帮助? +echo - GitHub Issues: https://github.com/lintsinghua/XCodeReviewer/issues +echo - 邮箱: tsinghuaiiilove@gmail.com +echo. +echo Happy coding! 🚀 +pause \ No newline at end of file diff --git a/scripts/setup.js b/scripts/setup.js new file mode 100644 index 0000000..10fc845 --- /dev/null +++ b/scripts/setup.js @@ -0,0 +1,142 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +console.log('🚀 XCodeReviewer 项目设置开始...'); + +// 检查 Node.js 版本 +function checkNodeVersion() { + console.log('📋 检查 Node.js 版本...'); + const nodeVersion = process.version; + const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0]); + + if (majorVersion < 18) { + console.error(`❌ Node.js 版本过低,需要 18+,当前版本: ${nodeVersion}`); + process.exit(1); + } + + console.log(`✅ Node.js 版本检查通过: ${nodeVersion}`); +} + +// 检查包管理器 +function detectPackageManager() { + console.log('📦 检查包管理器...'); + + const managers = ['pnpm', 'yarn', 'npm']; + + for (const manager of managers) { + try { + execSync(`${manager} --version`, { stdio: 'ignore' }); + console.log(`✅ 使用 ${manager}`); + return manager; + } catch (error) { + // 继续检查下一个 + } + } + + console.error('❌ 未找到包管理器,请安装 npm、yarn 或 pnpm'); + process.exit(1); +} + +// 安装依赖 +function installDependencies(packageManager) { + console.log('📥 安装项目依赖...'); + try { + execSync(`${packageManager} install`, { stdio: 'inherit' }); + } catch (error) { + console.error('❌ 依赖安装失败'); + process.exit(1); + } +} + +// 设置环境变量 +function setupEnvironment() { + console.log('🔧 检查环境变量配置...'); + + const envPath = '.env'; + const envExamplePath = '.env.example'; + + if (!fs.existsSync(envPath)) { + if (fs.existsSync(envExamplePath)) { + fs.copyFileSync(envExamplePath, envPath); + console.log('✅ 已创建 .env 文件,请编辑配置必要的环境变量'); + console.log(''); + console.log('📝 必需配置的环境变量:'); + console.log(' VITE_GEMINI_API_KEY - Google Gemini API 密钥'); + console.log(''); + console.log('📝 可选配置的环境变量:'); + console.log(' VITE_SUPABASE_URL - Supabase 项目 URL'); + console.log(' VITE_SUPABASE_ANON_KEY - Supabase 匿名密钥'); + console.log(' VITE_GITHUB_TOKEN - GitHub 访问令牌'); + console.log(''); + console.log('⚠️ 请在启动项目前配置 VITE_GEMINI_API_KEY'); + } else { + console.error('❌ 未找到 .env.example 文件'); + process.exit(1); + } + } else { + console.log('✅ .env 文件已存在'); + } +} + +// 检查 API Key 配置 +function checkApiKey() { + const envPath = '.env'; + + if (fs.existsSync(envPath)) { + const envContent = fs.readFileSync(envPath, 'utf8'); + + if (envContent.includes('VITE_GEMINI_API_KEY=your_gemini_api_key_here') || + !envContent.includes('VITE_GEMINI_API_KEY=')) { + console.log('⚠️ 请配置 Google Gemini API Key:'); + console.log(' 1. 访问 https://makersuite.google.com/app/apikey'); + console.log(' 2. 创建 API Key'); + console.log(' 3. 在 .env 文件中设置 VITE_GEMINI_API_KEY'); + } else { + console.log('✅ Gemini API Key 已配置'); + } + } +} + +// 主函数 +function main() { + try { + checkNodeVersion(); + const packageManager = detectPackageManager(); + installDependencies(packageManager); + setupEnvironment(); + checkApiKey(); + + console.log(''); + console.log('🎉 项目设置完成!'); + console.log(''); + console.log('📚 接下来的步骤:'); + console.log(` 1. 编辑 .env 文件,配置必要的环境变量`); + console.log(` 2. 运行 '${packageManager} dev' 启动开发服务器`); + console.log(' 3. 在浏览器中访问 http://localhost:5173'); + console.log(''); + console.log('📖 更多信息请查看:'); + console.log(' - README.md - 项目介绍和使用指南'); + console.log(' - DEPLOYMENT.md - 部署指南'); + console.log(' - FEATURES.md - 功能特性详解'); + console.log(''); + console.log('🆘 需要帮助?'); + console.log(' - GitHub Issues: https://github.com/lintsinghua/XCodeReviewer/issues'); + console.log(' - 邮箱: tsinghuaiiilove@gmail.com'); + console.log(''); + console.log('Happy coding! 🚀'); + + } catch (error) { + console.error('❌ 设置过程中出现错误:', error.message); + process.exit(1); + } +} + +// 运行主函数 +if (require.main === module) { + main(); +} + +module.exports = { main }; \ No newline at end of file diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000..e265810 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +# XCodeReviewer 项目设置脚本 +# 用于快速设置开发环境 + +set -e + +echo "🚀 XCodeReviewer 项目设置开始..." + +# 检查 Node.js 版本 +echo "📋 检查 Node.js 版本..." +if ! command -v node &> /dev/null; then + echo "❌ 未找到 Node.js,请先安装 Node.js 18+" + exit 1 +fi + +NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) +if [ "$NODE_VERSION" -lt 18 ]; then + echo "❌ Node.js 版本过低,需要 18+,当前版本: $(node -v)" + exit 1 +fi + +echo "✅ Node.js 版本检查通过: $(node -v)" + +# 检查包管理器 +echo "📦 检查包管理器..." +if command -v pnpm &> /dev/null; then + PKG_MANAGER="pnpm" + echo "✅ 使用 pnpm" +elif command -v yarn &> /dev/null; then + PKG_MANAGER="yarn" + echo "✅ 使用 yarn" +elif command -v npm &> /dev/null; then + PKG_MANAGER="npm" + echo "✅ 使用 npm" +else + echo "❌ 未找到包管理器,请安装 npm、yarn 或 pnpm" + exit 1 +fi + +# 安装依赖 +echo "📥 安装项目依赖..." +$PKG_MANAGER install + +# 检查环境变量文件 +echo "🔧 检查环境变量配置..." +if [ ! -f ".env" ]; then + if [ -f ".env.example" ]; then + cp .env.example .env + echo "✅ 已创建 .env 文件,请编辑配置必要的环境变量" + echo "" + echo "📝 必需配置的环境变量:" + echo " VITE_GEMINI_API_KEY - Google Gemini API 密钥" + echo "" + echo "📝 可选配置的环境变量:" + echo " VITE_SUPABASE_URL - Supabase 项目 URL" + echo " VITE_SUPABASE_ANON_KEY - Supabase 匿名密钥" + echo " VITE_GITHUB_TOKEN - GitHub 访问令牌" + echo "" + echo "⚠️ 请在启动项目前配置 VITE_GEMINI_API_KEY" + else + echo "❌ 未找到 .env.example 文件" + exit 1 + fi +else + echo "✅ .env 文件已存在" +fi + +# 检查 Gemini API Key +if [ -f ".env" ]; then + if grep -q "VITE_GEMINI_API_KEY=your_gemini_api_key_here" .env || ! grep -q "VITE_GEMINI_API_KEY=" .env; then + echo "⚠️ 请配置 Google Gemini API Key:" + echo " 1. 访问 https://makersuite.google.com/app/apikey" + echo " 2. 创建 API Key" + echo " 3. 在 .env 文件中设置 VITE_GEMINI_API_KEY" + else + echo "✅ Gemini API Key 已配置" + fi +fi + +# 构建检查 +echo "🔨 检查构建配置..." +if $PKG_MANAGER run build --dry-run &> /dev/null; then + echo "✅ 构建配置正常" +else + echo "⚠️ 构建配置可能有问题,请检查" +fi + +echo "" +echo "🎉 项目设置完成!" +echo "" +echo "📚 接下来的步骤:" +echo " 1. 编辑 .env 文件,配置必要的环境变量" +echo " 2. 运行 '$PKG_MANAGER dev' 启动开发服务器" +echo " 3. 在浏览器中访问 http://localhost:5173" +echo "" +echo "📖 更多信息请查看:" +echo " - README.md - 项目介绍和使用指南" +echo " - DEPLOYMENT.md - 部署指南" +echo " - FEATURES.md - 功能特性详解" +echo "" +echo "🆘 需要帮助?" +echo " - GitHub Issues: https://github.com/lintsinghua/XCodeReviewer/issues" +echo " - 邮箱: tsinghuaiiilove@gmail.com" +echo "" +echo "Happy coding! 🚀" \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 536e8a3..fe68e77 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,9 +7,9 @@ function App() { return ( -
+
-
+
{routes.map((route) => ( + +
+
+
+ + {routes.map((route) => ( + + ))} + } /> + +
+
+ + ); +} + +export default App; diff --git a/src/main.tsx b/src/app/main.tsx similarity index 71% rename from src/main.tsx rename to src/app/main.tsx index 3cfac3b..d87b7fe 100644 --- a/src/main.tsx +++ b/src/app/main.tsx @@ -1,8 +1,8 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import "./index.css"; +import "@/assets/styles/globals.css"; import App from "./App.tsx"; -import { AppWrapper } from "./components/common/PageMeta.tsx"; +import { AppWrapper } from "@/components/layout/PageMeta"; createRoot(document.getElementById("root")!).render( diff --git a/src/routes.tsx b/src/app/routes.tsx similarity index 72% rename from src/routes.tsx rename to src/app/routes.tsx index fb0b4e4..4a272b6 100644 --- a/src/routes.tsx +++ b/src/app/routes.tsx @@ -1,10 +1,10 @@ -import Dashboard from "./pages/Dashboard"; -import Projects from "./pages/Projects"; -import ProjectDetail from "./pages/ProjectDetail"; -import InstantAnalysis from "./pages/InstantAnalysis"; -import AuditTasks from "./pages/AuditTasks"; -import TaskDetail from "./pages/TaskDetail"; -import AdminDashboard from "./pages/AdminDashboard"; +import Dashboard from "@/pages/Dashboard"; +import Projects from "@/pages/Projects"; +import ProjectDetail from "@/pages/ProjectDetail"; +import InstantAnalysis from "@/pages/InstantAnalysis"; +import AuditTasks from "@/pages/AuditTasks"; +import TaskDetail from "@/pages/TaskDetail"; +import AdminDashboard from "@/pages/AdminDashboard"; import type { ReactNode } from 'react'; export interface RouteConfig { diff --git a/src/assets/styles/globals.css b/src/assets/styles/globals.css new file mode 100644 index 0000000..2bd9458 --- /dev/null +++ b/src/assets/styles/globals.css @@ -0,0 +1,221 @@ +/* stylelint-disable */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Definition of the design system. All colors, gradients, fonts, etc should be defined here. +All colors MUST be HSL. +*/ + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + + --sidebar-background: 0 0% 98%; + + --sidebar-foreground: 240 5.3% 26.1%; + + --sidebar-primary: 240 5.9% 10%; + + --sidebar-primary-foreground: 0 0% 98%; + + --sidebar-accent: 240 4.8% 95.9%; + + --sidebar-accent-foreground: 240 5.9% 10%; + + --sidebar-border: 220 13% 91%; + + --sidebar-ring: 217.2 91.2% 59.8%; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + --sidebar-background: 240 5.9% 10%; + --sidebar-foreground: 240 4.8% 95.9%; + --sidebar-primary: 224.3 76.3% 48%; + --sidebar-primary-foreground: 0 0% 100%; + --sidebar-accent: 240 3.7% 15.9%; + --sidebar-accent-foreground: 240 4.8% 95.9%; + --sidebar-border: 240 3.7% 15.9%; + --sidebar-ring: 217.2 91.2% 59.8%; + } +} + +@layer base { + * { + @apply border-border; + } + + body { + @apply bg-background text-foreground; + font-feature-settings: "rlig" 1, "calt" 1; + } +} + +@layer components { + /* 页面标题样式 */ + .page-title { + @apply text-2xl md:text-3xl font-bold text-gray-900 tracking-tight; + } + + .page-subtitle { + @apply text-sm md:text-base text-gray-600 mt-1; + } + + /* 现代化卡片样式 */ + .card-modern { + @apply bg-white rounded-xl border border-gray-200/60 shadow-sm hover:shadow-md transition-all duration-200; + } + + /* 统计卡片样式 */ + .stat-card { + @apply bg-white rounded-xl border border-gray-200/60 shadow-sm hover:shadow-lg transition-all duration-300 hover:border-gray-300/60; + } + + .stat-label { + @apply text-xs font-medium text-gray-500 uppercase tracking-wide; + } + + .stat-value { + @apply text-2xl md:text-3xl font-bold text-gray-900 mt-1; + } + + .stat-icon { + @apply w-12 h-12 rounded-lg bg-gradient-to-br flex items-center justify-center shadow-sm; + } + + /* 按钮样式 */ + .btn-primary { + @apply bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white shadow-sm hover:shadow-md transition-all duration-200; + } + + .btn-secondary { + @apply border-gray-300 hover:border-gray-400 hover:bg-gray-50 transition-all duration-200; + } + + /* 空状态样式 */ + .empty-state { + @apply flex flex-col items-center justify-center text-center; + } + + .empty-icon { + @apply w-16 h-16 rounded-full bg-gray-100 flex items-center justify-center mb-4; + } + + /* 动画 */ + .animate-fade-in { + animation: fadeIn 0.5s ease-out; + } + + @keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + /* 渐变背景 */ + .gradient-bg { + @apply bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50; + } + + /* 响应式容器 */ + .container-responsive { + @apply container mx-auto px-4 sm:px-6 lg:px-8; + } + + /* 文本截断 */ + .line-clamp-2 { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + } + + /* 毛玻璃效果 */ + .backdrop-blur-md { + backdrop-filter: blur(12px); + } + + /* 平滑滚动 */ + html { + scroll-behavior: smooth; + } + + /* 自定义滚动条 */ + ::-webkit-scrollbar { + width: 6px; + height: 6px; + } + + ::-webkit-scrollbar-track { + background: transparent; + } + + ::-webkit-scrollbar-thumb { + background: rgba(156, 163, 175, 0.5); + border-radius: 3px; + } + + ::-webkit-scrollbar-thumb:hover { + background: rgba(156, 163, 175, 0.8); + } +} diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx deleted file mode 100644 index 7326cad..0000000 --- a/src/components/common/Footer.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from "react"; - -const Footer: React.FC = () => { - const currentYear = new Date().getFullYear(); - - return ( -
-
-
- {/* ================= 关于我们 ================= */} -
- {/* 标题:改成你们项目的“关于我们” */} -

- {/* 关于我们 */} -

-

- {/* 在这里填写“关于我们”的介绍,比如:致力于xxx,让xxx更加xxx */} -

-
- - {/* ================= 联系信息 ================= */} -
- {/* 标题:联系信息 */} -

- {/* 联系信息 */} -

-
-

- {/* 地址:XXX省XXX市XXX区XXX路XXX号 */} -

-

- {/* 电话:010-XXXXXXX */} -

-

- {/* 邮箱:info@example.com */} -

-
-
- - {/* ================= 开放时间 / 其他信息 / 也可删除 ================= */} -
- {/* 标题:可改成“开放时间”或者“服务时间” */} -

- {/* 开放时间 */} -

-
-

- {/* 周一至周五:9:00-18:00 */} -

-

- {/* 周末及法定节假日请注意公告 */} -

-

- {/* 其他说明,比如“需要提前预约” */} -

-
-
-
- - {/* ================= 版权区域 ================= */} -
-

- {/* © {currentYear} 你的公司或组织名称 */} -

-
-
-
- ); -}; - -export default Footer; diff --git a/src/components/common/PageMeta.tsx b/src/components/common/PageMeta.tsx deleted file mode 100644 index 007a806..0000000 --- a/src/components/common/PageMeta.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { HelmetProvider, Helmet } from "react-helmet-async"; - -const PageMeta = ({ - title, - description, -}: { - title: string; - description: string; -}) => ( - - {title} - - -); - -export const AppWrapper = ({ children }: { children: React.ReactNode }) => ( - {children} -); - -export default PageMeta; diff --git a/src/components/debug/DatabaseTest.tsx b/src/components/debug/DatabaseTest.tsx index 5f136ae..97fba8e 100644 --- a/src/components/debug/DatabaseTest.tsx +++ b/src/components/debug/DatabaseTest.tsx @@ -1,114 +1,152 @@ import { useState } from "react"; -import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; -import { api, supabase } from "@/db/supabase"; -import { Database, CheckCircle, AlertTriangle, RefreshCw } from "lucide-react"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { + Database, + CheckCircle, + AlertTriangle, + Loader2, + RefreshCw +} from "lucide-react"; +import { api } from "@/shared/config/database"; import { toast } from "sonner"; +interface TestResult { + name: string; + status: 'success' | 'error' | 'pending'; + message: string; + duration?: number; +} + export default function DatabaseTest() { const [testing, setTesting] = useState(false); - const [results, setResults] = useState(null); + const [results, setResults] = useState([]); - const testConnection = async (): Promise => { - try { - const { data, error } = await supabase - .from('profiles') - .select('count', { count: 'exact', head: true }); - - if (error) { - console.error('Database connection test failed:', error); - return false; + const runTests = async () => { + setTesting(true); + setResults([]); + + const tests: Array<{ name: string; test: () => Promise }> = [ + { + name: "数据库连接测试", + test: async () => { + const start = Date.now(); + await api.getProjectStats(); + return { duration: Date.now() - start }; + } + }, + { + name: "项目数据查询", + test: async () => { + const start = Date.now(); + const projects = await api.getProjects(); + return { + duration: Date.now() - start, + count: projects.length + }; + } + }, + { + name: "审计任务查询", + test: async () => { + const start = Date.now(); + const tasks = await api.getAuditTasks(); + return { + duration: Date.now() - start, + count: tasks.length + }; + } + }, + { + name: "用户配置查询", + test: async () => { + const start = Date.now(); + const count = await api.getProfilesCount(); + return { + duration: Date.now() - start, + count + }; + } + } + ]; + + for (const { name, test } of tests) { + try { + // 添加pending状态 + setResults(prev => [...prev, { name, status: 'pending', message: '测试中...' }]); + + const result = await test(); + + // 更新为成功状态 + setResults(prev => prev.map(r => + r.name === name + ? { + name, + status: 'success', + message: `测试通过 (${result.duration}ms)${result.count !== undefined ? ` - 数据量: ${result.count}` : ''}`, + duration: result.duration + } + : r + )); + } catch (error: any) { + // 更新为错误状态 + setResults(prev => prev.map(r => + r.name === name + ? { + name, + status: 'error', + message: `测试失败: ${error.message || '未知错误'}` + } + : r + )); } - console.log('Database connection successful'); - return true; - } catch (error) { - console.error('Database connection error:', error); - return false; + // 添加延迟避免过快执行 + await new Promise(resolve => setTimeout(resolve, 500)); + } + + setTesting(false); + + const successCount = results.filter(r => r.status === 'success').length; + const totalCount = tests.length; + + if (successCount === totalCount) { + toast.success("所有数据库测试通过!"); + } else { + toast.error(`${totalCount - successCount} 个测试失败`); } }; - const runDatabaseTest = async () => { - setTesting(true); - const testResults: any = { - connection: false, - tables: {}, - sampleData: {}, - errors: [] - }; + const getStatusIcon = (status: TestResult['status']) => { + switch (status) { + case 'success': + return ; + case 'error': + return ; + case 'pending': + return ; + default: + return null; + } + }; - try { - // 测试基本连接 - console.log('测试数据库连接...'); - testResults.connection = await testConnection(); - - // 测试各个表 - const tables = ['profiles', 'projects', 'audit_tasks', 'audit_issues', 'instant_analyses']; - - for (const table of tables) { - try { - console.log(`测试表: ${table}`); - const { data, error, count } = await supabase - .from(table) - .select('*', { count: 'exact', head: true }); - - testResults.tables[table] = { - accessible: !error, - count: count || 0, - error: error?.message - }; - - if (error) { - testResults.errors.push(`${table}: ${error.message}`); - } - } catch (err) { - testResults.tables[table] = { - accessible: false, - count: 0, - error: (err as Error).message - }; - testResults.errors.push(`${table}: ${(err as Error).message}`); - } - } - - // 测试示例数据获取 - try { - console.log('测试项目数据获取...'); - const projects = await api.getProjects(); - testResults.sampleData.projects = { - success: true, - count: projects.length, - data: projects.slice(0, 2) // 只显示前2个 - }; - } catch (err) { - testResults.sampleData.projects = { - success: false, - error: (err as Error).message - }; - testResults.errors.push(`项目数据: ${(err as Error).message}`); - } - - setResults(testResults); - - if (testResults.connection && testResults.errors.length === 0) { - toast.success("数据库测试通过!"); - } else { - toast.error(`数据库测试发现 ${testResults.errors.length} 个问题`); - } - - } catch (error) { - console.error('数据库测试失败:', error); - testResults.errors.push(`总体测试失败: ${(error as Error).message}`); - setResults(testResults); - toast.error("数据库测试失败"); - } finally { - setTesting(false); + const getStatusBadge = (status: TestResult['status']) => { + switch (status) { + case 'success': + return 通过; + case 'error': + return 失败; + case 'pending': + return 测试中; + default: + return null; } }; return ( - + @@ -116,105 +154,67 @@ export default function DatabaseTest() { -
- - - {results && ( - - {results.connection && results.errors.length === 0 ? ( - - ) : ( - - )} - {results.connection && results.errors.length === 0 ? '连接正常' : '存在问题'} - - )}
- {results && ( -
- {/* 连接状态 */} -
-

基础连接

-
- {results.connection ? ( - - ) : ( - - )} - - {results.connection ? '数据库连接成功' : '数据库连接失败'} - -
-
- - {/* 表状态 */} -
-

数据表状态

-
- {Object.entries(results.tables).map(([tableName, tableInfo]: [string, any]) => ( -
-
- {tableInfo.accessible ? ( - - ) : ( - - )} - {tableName} -
- - {tableInfo.count} 条记录 - + {results.length > 0 && ( +
+ {results.map((result, index) => ( +
+
+ {getStatusIcon(result.status)} +
+

{result.name}

+

{result.message}

- ))} +
+ {getStatusBadge(result.status)}
-
- - {/* 示例数据 */} - {results.sampleData.projects && ( -
-

示例数据

- {results.sampleData.projects.success ? ( -
-

- ✅ 成功获取 {results.sampleData.projects.count} 个项目 -

- {results.sampleData.projects.data.map((project: any, index: number) => ( -
- {project.name} - {project.description || '无描述'} -
- ))} -
- ) : ( -

- ❌ 获取项目数据失败: {results.sampleData.projects.error} -

- )} -
- )} - - {/* 错误信息 */} - {results.errors.length > 0 && ( -
-

发现的问题

-
    - {results.errors.map((error: string, index: number) => ( -
  • - • {error} -
  • - ))} -
-
- )} + ))}
)} + + {results.length > 0 && !testing && ( + + + + 测试完成!成功: {results.filter(r => r.status === 'success').length} / + 总计: {results.length} + + + )} + + {results.length === 0 && !testing && ( + + + + 点击"开始测试"按钮来检查数据库连接状态 + + + )} ); diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx new file mode 100644 index 0000000..243c658 --- /dev/null +++ b/src/components/layout/Footer.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { Code } from "lucide-react"; + +const Footer: React.FC = () => { + const currentYear = new Date().getFullYear(); + + return ( +
+
+
+
+
+ +
+ XCodeReviewer +
+

+ © {currentYear} XCodeReviewer. 致力于提升代码质量,保障软件安全. +

+
+
+
+ ); +}; + +export default Footer; \ No newline at end of file diff --git a/src/components/common/Header.tsx b/src/components/layout/Header.tsx similarity index 73% rename from src/components/common/Header.tsx rename to src/components/layout/Header.tsx index 7550b7c..fa8c056 100644 --- a/src/components/common/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,13 +1,12 @@ import { useState } from "react"; import { Link, useLocation } from "react-router-dom"; import { Button } from "@/components/ui/button"; -import { Badge } from "@/components/ui/badge"; import { Menu, X, Code } from "lucide-react"; -import routes from "@/routes"; +import routes from "@/app/routes"; export default function Header() { const location = useLocation(); @@ -15,30 +14,28 @@ export default function Header() { const visibleRoutes = routes.filter(route => route.visible !== false); - const user = null; - return ( -
-
+
+
{/* Logo */} - -
+ +
- 智能代码审计 + XCodeReviewer {/* Desktop Navigation */} -