From 7a3bb08d484ba28113127b290db2c837f22fa88a Mon Sep 17 00:00:00 2001 From: vinland100 Date: Mon, 5 Jan 2026 09:50:51 +0800 Subject: [PATCH] feat: Introduce reusable AppLogo component and update project activity timestamp to UTC. --- backend/app/services/ci_service.py | 7 +- frontend/src/components/common/AppLogo.tsx | 178 +++++++++++ frontend/src/components/layout/Sidebar.tsx | 40 +-- .../pages/AgentAudit/components/Header.tsx | 26 +- .../AgentAudit/components/SplashScreen.tsx | 278 ++++++++---------- frontend/src/pages/AgentAudit/constants.tsx | 2 +- frontend/src/pages/Login.tsx | 22 +- frontend/src/pages/Register.tsx | 22 +- frontend/src/pages/ci/CIProjects.tsx | 4 +- 9 files changed, 334 insertions(+), 245 deletions(-) create mode 100644 frontend/src/components/common/AppLogo.tsx diff --git a/backend/app/services/ci_service.py b/backend/app/services/ci_service.py index f53c080..47a7bca 100644 --- a/backend/app/services/ci_service.py +++ b/backend/app/services/ci_service.py @@ -11,7 +11,7 @@ import subprocess import json from typing import Dict, Any, List, Optional from pathlib import Path -from datetime import datetime +from datetime import datetime, timezone import asyncio import httpx @@ -164,7 +164,7 @@ class CIService: self.db.add(review_record) # Update project activity - project.latest_pr_activity = datetime.utcnow() + project.latest_pr_activity = datetime.now(timezone.utc) await self.db.commit() except Exception as e: @@ -300,6 +300,9 @@ class CIService: context_used=json.dumps([r.file_path for r in context_results]) ) self.db.add(review_record) + + # Update project activity + project.latest_pr_activity = datetime.now(timezone.utc) await self.db.commit() diff --git a/frontend/src/components/common/AppLogo.tsx b/frontend/src/components/common/AppLogo.tsx new file mode 100644 index 0000000..71b9718 --- /dev/null +++ b/frontend/src/components/common/AppLogo.tsx @@ -0,0 +1,178 @@ +import React from 'react'; + +/** + * AppLogo Component + * A professional SVG-based logo representing an AI Code Review Bot. + * Supports theme switching and various sizes. + */ + +interface AppLogoProps { + className?: string; + size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'; + showText?: boolean; + collapsed?: boolean; + theme?: 'dark' | 'light'; // Optional override + subtitle?: string; +} + +const AppLogo: React.FC = ({ + className = "", + size = 'md', + showText = true, + collapsed = false, + subtitle = "AI Code Review Bot" +}) => { + // Size mapping for both icon and text + const sizeMap = { + sm: { icon: 'w-6 h-6', text: 'text-lg', sub: 'text-[8px]', gap: 'gap-2' }, + md: { icon: 'w-10 h-10', text: 'text-xl', sub: 'text-[10px]', gap: 'gap-3' }, + lg: { icon: 'w-14 h-14', text: 'text-3xl', sub: 'text-sm', gap: 'gap-4' }, + xl: { icon: 'w-20 h-20', text: 'text-4xl', sub: 'text-base', gap: 'gap-5' }, + '2xl': { icon: 'w-24 h-24', text: 'text-5xl', sub: 'text-lg', gap: 'gap-6' } + }; + + const currentSize = sizeMap[size]; + + return ( +
+ {/* Logo Icon Container */} +
+ {/* SVG Logo */} + + + + + + + + + + + + + {/* Outer Hexagon Frame */} + + + {/* Circuit Like Lines */} + + + + {/* Brackets < > */} + + + + {/* Central AI Eye Entity */} + + + {/* Glowing Core */} + + + {/* Lens Highlight */} + + + {/* Scanline Effect across the icon */} + + + + + + {/* Outer Glow for Hover */} +
+
+ + {/* Text Section */} + {showText && !collapsed && ( +
+
+ DEEP + AUDIT +
+
+ {subtitle} +
+
+ )} +
+ ); +}; + +export default AppLogo; diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index d7ec7b8..ec8f205 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -26,6 +26,7 @@ import { ExternalLink, GitGraph, } from "lucide-react"; +import AppLogo from "@/components/common/AppLogo"; import routes from "@/app/routes"; import { version } from "../../../package.json"; @@ -123,41 +124,14 @@ export default function Sidebar({ collapsed, setCollapsed }: SidebarProps) { setMobileOpen(false)} > - {/* Logo Icon with enhanced styling */} -
-
- DeepAudit -
- {/* Glow effect */} -
-
- - {/* Logo Text with enhanced styling */} -
-
- DEEP - AUDIT -
-
- Security Agent -
-
+ {/* Collapse button with enhanced styling */} diff --git a/frontend/src/pages/AgentAudit/components/Header.tsx b/frontend/src/pages/AgentAudit/components/Header.tsx index ce1751d..c18426a 100644 --- a/frontend/src/pages/AgentAudit/components/Header.tsx +++ b/frontend/src/pages/AgentAudit/components/Header.tsx @@ -5,6 +5,7 @@ */ import { Square, Download, Play, Loader2, Radio, Cpu, Sparkles } from "lucide-react"; +import AppLogo from "@/components/common/AppLogo"; import { Button } from "@/components/ui/button"; import { StatusBadge } from "./StatusBadge"; import type { HeaderProps } from "../types"; @@ -26,27 +27,14 @@ export function Header({ {/* Left side - Brand and task info */}
- {/* Logo section with enhanced styling */}
-
- {/* Logo background glow */} -
-
- - {isRunning && ( - <> - - - - )} + + {isRunning && ( +
+ +
-
-
- - DEEPAUDIT - - Security Agent -
+ )}
{/* Task info with enhanced styling */} diff --git a/frontend/src/pages/AgentAudit/components/SplashScreen.tsx b/frontend/src/pages/AgentAudit/components/SplashScreen.tsx index 139053b..23c233c 100644 --- a/frontend/src/pages/AgentAudit/components/SplashScreen.tsx +++ b/frontend/src/pages/AgentAudit/components/SplashScreen.tsx @@ -6,6 +6,7 @@ import { useState, useEffect, useRef, useCallback } from "react"; import { Shield, Zap } from "lucide-react"; +import AppLogo from "@/components/common/AppLogo"; interface SplashScreenProps { onComplete: () => void; @@ -14,7 +15,7 @@ interface SplashScreenProps { // Enhanced boot sequence messages with icons const BOOT_SEQUENCE = [ { text: "[INIT] Loading DeepAudit Core...", delay: 0, type: 'init' }, - { text: "[SCAN] Neural Analysis Engine v3.0", delay: 200, type: 'scan' }, + { text: "[SCAN] AI Code Review Engine v3.0", delay: 200, type: 'scan' }, { text: "[LOAD] Vulnerability Pattern Database", delay: 400, type: 'load' }, { text: "[SYNC] Agent Orchestration Module", delay: 600, type: 'sync' }, { text: "[READY] System Online", delay: 800, type: 'ready' }, @@ -229,175 +230,148 @@ export function SplashScreen({ onComplete }: SplashScreenProps) {
{/* Logo with adaptive styling */}
- {/* Logo text - light mode: clean, dark mode: neon glow */} -
-
- DEEP - AUDIT -
- {/* Glitch layers - dark mode only, opacity controlled by CSS */} -
- DEEP - AUDIT -
-
- DEEP - AUDIT -
+
+
- {/* Subtitle - adaptive styling */} -
-
- - Autonomous Security Agent - -
+
+ {/* Version tag */} +
+ [ v3.0.0 // NEURAL_CORE ] +
+
+ + {/* Terminal window - adaptive styling */} +
+ {/* Terminal border glow - dark mode only */} +
+
+ + {/* Terminal header - adaptive */} +
+ {/* Window dots */} +
+
+
+
- {/* Version tag */} -
- [ v3.0.0 // NEURAL_CORE ] + {/* Terminal title */} +
+ + + root@deepaudit:~# + + +
+ {/* Status indicator */} +
+ + LIVE
- {/* Terminal window - adaptive styling */} + {/* Terminal content - adaptive */}
- {/* Terminal border glow - dark mode only */} -
-
- - {/* Terminal header - adaptive */} -
- {/* Window dots */} -
-
-
-
-
- {/* Terminal title */} -
- - - root@deepaudit:~# - - -
- {/* Status indicator */} -
- - LIVE -
-
- - {/* Terminal content - adaptive */} -
- {/* Boot logs - adaptive styling */} - {bootLogs.map((log, i) => ( -
( +
- $ - + $ + - {log} -
- ))} + {log} +
+ ))} - {/* Welcome message - adaptive */} - {bootComplete && ( -
-
- - // SYSTEM READY -
-
- Execute 'audit' to initialize security scan protocol -
-
- [ Type 'help' for available commands ] -
+ {/* Welcome message - adaptive */} + {bootComplete && ( +
+
+ + // SYSTEM READY
- )} - - {/* Command history */} - {commandHistory.map((entry, i) => ( -
-
- $ - {entry.input} -
- {entry.output && ( -
- {entry.output} -
- )} +
+ Execute 'audit' to initialize security scan protocol
- ))} +
+ [ Type 'help' for available commands ] +
+
+ )} - {/* Current input line */} - {bootComplete && ( + {/* Command history */} + {commandHistory.map((entry, i) => ( +
$ -
- setCurrentInput(e.target.value)} - onKeyDown={handleKeyDown} - className="absolute inset-0 w-full bg-transparent text-transparent outline-none border-none" - style={{ caretColor: "transparent" }} - spellCheck={false} - autoComplete="off" - autoFocus - /> - {currentInput} - -
+ {entry.input}
- )} -
-
+ {entry.output && ( +
+ {entry.output} +
+ )} +
+ ))} - {/* Hint */} -
-
-
- PRESS ENTER TO EXECUTE -
-
+ {/* Current input line */} + {bootComplete && ( +
+ $ +
+ setCurrentInput(e.target.value)} + onKeyDown={handleKeyDown} + className="absolute inset-0 w-full bg-transparent text-transparent outline-none border-none" + style={{ caretColor: "transparent" }} + spellCheck={false} + autoComplete="off" + autoFocus + /> + {currentInput} + +
+
+ )} +
+
+ + {/* Hint */} +
+
+
+ PRESS ENTER TO EXECUTE +
@@ -572,7 +546,7 @@ export function SplashScreen({ onComplete }: SplashScreenProps) { text-shadow: 0 0 10px rgba(52,211,153,0.8), 0 0 20px rgba(52,211,153,0.4); } `} -
+
); } diff --git a/frontend/src/pages/AgentAudit/constants.tsx b/frontend/src/pages/AgentAudit/constants.tsx index bd5378f..514a46e 100644 --- a/frontend/src/pages/AgentAudit/constants.tsx +++ b/frontend/src/pages/AgentAudit/constants.tsx @@ -241,6 +241,6 @@ export const DEEPAUDIT_ASCII = ` ║ | |_| | |___| |___| __/ ___ \\ |_| | |_| | | | | ║ ║ |____/|_____|_____|_| /_/ \\_\\___/|____/___| |_| ║ ║ ║ -║ [ Autonomous Security Agent ] ║ +║ [ AI Code Review Bot ] ║ ║ ║ ╚═══════════════════════════════════════════════════════════════╝`; diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 2ea6db2..734cc27 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -13,6 +13,7 @@ import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { toast } from "sonner"; import { Lock, Mail, Terminal, Shield, Fingerprint, Cpu } from "lucide-react"; +import AppLogo from "@/components/common/AppLogo"; import { version } from "../../package.json"; export default function Login() { @@ -143,29 +144,14 @@ export default function Login() {
{/* Logo & Title */}
-
- DeepAudit +
+
-
- DEEP - AUDIT -
-

- // Autonomous Security Agent -

{/* Login Form Card */}
+ style={{ boxShadow: '0 4px 30px rgba(0,0,0,0.5)' }}> {/* Card Header */}
diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx index e55b1a8..187a032 100644 --- a/frontend/src/pages/Register.tsx +++ b/frontend/src/pages/Register.tsx @@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { toast } from 'sonner'; import { User, Mail, Lock, Terminal, Shield, Cpu } from 'lucide-react'; +import AppLogo from '@/components/common/AppLogo'; import { version } from '../../package.json'; export default function Register() { @@ -112,29 +113,14 @@ export default function Register() {
{/* Logo & Title */}
-
- DeepAudit +
+
-
- DEEP - AUDIT -
-

- // Create New Account -

{/* Register Form Card */}
+ style={{ boxShadow: '0 4px 30px rgba(0,0,0,0.5)' }}> {/* Card Header */}
diff --git a/frontend/src/pages/ci/CIProjects.tsx b/frontend/src/pages/ci/CIProjects.tsx index 7031378..bad34cf 100644 --- a/frontend/src/pages/ci/CIProjects.tsx +++ b/frontend/src/pages/ci/CIProjects.tsx @@ -4,7 +4,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/com import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { GitGraph, ArrowRight, Trash2, Clock } from "lucide-react"; -import { formatDistanceToNow } from 'date-fns'; +import { formatDistanceToNowStrict } from 'date-fns'; import { zhCN } from 'date-fns/locale'; interface CIProject { @@ -102,7 +102,7 @@ const CIProjects: React.FC = () => {
- Latest: {project.latest_pr_activity ? formatDistanceToNow(new Date(project.latest_pr_activity), { addSuffix: true, locale: zhCN }) : 'Never'} + AI 最后回复: {project.latest_pr_activity ? formatDistanceToNowStrict(new Date(project.latest_pr_activity), { addSuffix: true, locale: zhCN }) : '从无回复'}