fix: 修复前端构建问题 - 恢复 develop 分支配置

- develop 分支已包含完整的 package.json、tsconfig.json、vite.config.ts
- develop 分支已包含完整的路由、useAuth、api/tasks 实现
- @/ 路径别名已在 tsconfig 和 vite 配置中正确设置

额外修复:
- 删除 Next.js 残留文件 (next.config.js, next-env.d.ts)
- 删除死代码:workspaceStore.ts(从未被引用)、QuotaDisplay.tsx(从未被使用)
- 删除 Vite 脚手架残留:App.tsx、App.css
- Header.tsx 添加 Header.css 导入,修复顶部导航无样式问题

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Audit Bot
2026-06-27 18:16:43 +08:00
parent 48d3754956
commit bad52fd1d0
7 changed files with 1 additions and 329 deletions
-4
View File
@@ -1,4 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// This file is auto-used by Next.js TypeScript projects.
-6
View File
@@ -1,6 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
module.exports = nextConfig;
-140
View File
@@ -1,140 +0,0 @@
/* V21 App Root Styles */
.xx-app-root {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f8fafc 0%, #eef2ff 100%);
padding: 24px;
}
.xx-app-container {
max-width: 480px;
width: 100%;
text-align: center;
}
/* Hero Section */
.xx-hero-section {
margin-bottom: 40px;
}
.xx-logo {
font-size: 72px;
margin-bottom: 24px;
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.xx-hero-section h1 {
font-size: 36px;
font-weight: 850;
color: #0f172a;
margin: 0 0 12px;
letter-spacing: -0.5px;
}
.xx-hero-section p {
font-size: 18px;
color: #64748b;
margin: 0;
}
.xx-status-badge {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 20px;
padding: 8px 16px;
background: #eef2ff;
color: #4f46e5;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
}
.xx-status-dot {
width: 8px;
height: 8px;
background: #4f46e5;
border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.2); }
}
/* Card */
.xx-card {
background: rgba(255,255,255,0.94);
border: 1px solid rgba(226,232,240,0.95);
border-radius: 22px;
box-shadow: 0 24px 70px rgba(15,23,42,0.09);
padding: 28px;
transition: all 0.25s;
}
.xx-card:hover {
box-shadow: 0 26px 64px rgba(15,23,42,0.14);
transform: translateY(-2px);
}
.xx-card h3 {
font-size: 18px;
font-weight: 700;
color: #0f172a;
margin: 0 0 20px;
text-align: left;
}
/* Quick Links */
.xx-link-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.xx-link-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
padding: 24px 16px;
background: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 16px;
text-decoration: none;
color: #0f172a;
font-weight: 600;
transition: all 0.2s;
}
.xx-link-item:hover {
background: #eef2ff;
border-color: #4f46e5;
color: #4f46e5;
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(79,70,229,0.15);
}
.xx-link-icon {
font-size: 32px;
}
/* Responsive */
@media (max-width: 480px) {
.xx-hero-section h1 {
font-size: 28px;
}
.xx-link-grid {
grid-template-columns: 1fr;
}
}
-37
View File
@@ -1,37 +0,0 @@
/**
* App Root Component - V21 UI
* 注意:此组件已被路由系统接管,仅作为默认展示
*/
import { Link } from 'react-router-dom';
import './App.css';
function App() {
return (
<div className="xx-app-root">
<div className="xx-app-container">
<div className="xx-hero-section">
<div className="xx-logo">🎬</div>
<h1> SaaS</h1>
<p></p>
<div className="xx-status-badge">
<span className="xx-status-dot"></span>
</div>
</div>
<div className="xx-card xx-quick-links">
<h3></h3>
<div className="xx-link-grid">
<span>Projects (Coming Soon)</span>
<Link to="/projects" className="xx-link-item">
<span className="xx-link-icon">📋</span>
<span></span>
</Link>
</div>
</div>
</div>
</div>
);
}
export default App;
@@ -1,99 +0,0 @@
/**
* 配额使用展示组件 - V21 UI
*/
import React from 'react';
import { Card, Progress, Row, Col, Tag, Space } from 'antd';
import { ProjectOutlined, CloudOutlined, WarningOutlined } from '@ant-design/icons';
import './business.css';
interface QuotaStatus {
projects: {
used: number;
limit: number;
status: string;
};
storage: {
used_gb: number;
limit_gb: number;
status: string;
};
}
interface QuotaDisplayProps {
quota: QuotaStatus;
}
const QuotaDisplay: React.FC<QuotaDisplayProps> = ({ quota }) => {
const getStatusTag = (status: string) => {
const config: Record<string, { color: string; text: string; className: string }> = {
normal: { color: 'success', text: '正常', className: 'xx-tag-success' },
warning: { color: 'warning', text: '接近上限', className: 'xx-tag-warning' },
critical: { color: 'error', text: '即将超限', className: 'xx-tag-error' },
exceeded: { color: 'error', text: '已超限', className: 'xx-tag-error' },
};
const item = config[status] || config.normal;
return (
<Tag color={item.color} icon={<WarningOutlined />} className={`xx-tag ${item.className}`}>
{item.text}
</Tag>
);
};
const getProgressColor = (status: string) => {
const colorMap: Record<string, string> = {
normal: '#16a34a',
warning: '#d97706',
critical: '#dc2626',
exceeded: '#dc2626',
};
return colorMap[status] || '#4f46e5';
};
return (
<Card title="配额使用情况" className="xx-card">
<Space direction="vertical" style={{ width: '100%' }} size="large">
<div className="xx-quota-item">
<Row justify="space-between" align="middle" style={{ marginBottom: 12 }}>
<Col>
<Space>
<ProjectOutlined style={{ fontSize: 18, color: '#4f46e5' }} />
<span style={{ fontWeight: 600, color: '#0f172a', fontSize: 15 }}></span>
</Space>
</Col>
<Col>{getStatusTag(quota.projects.status)}</Col>
</Row>
<div style={{ marginBottom: 8, color: '#64748b', fontSize: 14 }}>
{quota.projects.used} / {quota.projects.limit}
</div>
<Progress
percent={Math.round((quota.projects.used / quota.projects.limit) * 100)}
strokeColor={getProgressColor(quota.projects.status)}
trailColor="#f1f5f9"
/>
</div>
<div className="xx-quota-item">
<Row justify="space-between" align="middle" style={{ marginBottom: 12 }}>
<Col>
<Space>
<CloudOutlined style={{ fontSize: 18, color: '#4f46e5' }} />
<span style={{ fontWeight: 600, color: '#0f172a', fontSize: 15 }}></span>
</Space>
</Col>
<Col>{getStatusTag(quota.storage.status)}</Col>
</Row>
<div style={{ marginBottom: 8, color: '#64748b', fontSize: 14 }}>
{quota.storage.used_gb.toFixed(2)} / {quota.storage.limit_gb} GB
</div>
<Progress
percent={Math.round((quota.storage.used_gb / quota.storage.limit_gb) * 100)}
strokeColor={getProgressColor(quota.storage.status)}
trailColor="#f1f5f9"
/>
</div>
</Space>
</Card>
);
};
export default QuotaDisplay;
@@ -5,6 +5,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { useAuthStore } from '@/store/authStore';
import { useLogout } from '@/hooks/useAuth';
import type { MenuProps } from 'antd';
import './Header.css';
const extractProjectId = (pathname: string) => {
const match = pathname.match(/^\/projects\/([^/]+)/);
-43
View File
@@ -1,43 +0,0 @@
/**
* 工作空间状态管理
*/
import { create } from 'zustand';
import { Workspace } from '@/api/workspace';
interface WorkspaceState {
currentWorkspace: Workspace | null;
workspaces: Workspace[];
// Actions
setCurrentWorkspace: (workspace: Workspace | null) => void;
setWorkspaces: (workspaces: Workspace[]) => void;
addWorkspace: (workspace: Workspace) => void;
removeWorkspace: (workspaceId: string) => void;
}
export const useWorkspaceStore = create<WorkspaceState>((set) => ({
currentWorkspace: null,
workspaces: [],
setCurrentWorkspace: (workspace) => {
set({ currentWorkspace: workspace });
},
setWorkspaces: (workspaces) => {
set({ workspaces });
},
addWorkspace: (workspace) => {
set((state) => ({
workspaces: [...state.workspaces, workspace],
}));
},
removeWorkspace: (workspaceId) => {
set((state) => ({
workspaces: state.workspaces.filter((w) => w.id !== workspaceId),
currentWorkspace:
state.currentWorkspace?.id === workspaceId ? null : state.currentWorkspace,
}));
},
}));