diff --git a/apps/web/src/pages/admin/Admin.css b/apps/web/src/pages/admin/Admin.css new file mode 100644 index 000000000..ea535aaf5 --- /dev/null +++ b/apps/web/src/pages/admin/Admin.css @@ -0,0 +1,517 @@ +/* V21 Admin 页面样式 */ + +/* 页面容器 */ +.dashboard-page, +.analytics-page, +.user-management-page, +.log-viewer-page, +.system-monitor-page, +.admin-coming-soon-page { + padding: 32px; + max-width: 1400px; + margin: 0 auto; +} + +/* 页面头部 */ +.xx-page-head { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15, 23, 42, 0.09); + padding: 32px 40px; + margin-bottom: 32px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.xx-page-head-content { + display: flex; + flex-direction: column; + gap: 8px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 900; + color: var(--slate, #0f172a); + margin: 0; + letter-spacing: -0.02em; +} + +.xx-page-head p { + font-size: 15px; + color: var(--muted, #64748b); + margin: 0; +} + +.xx-page-head-actions { + display: flex; + gap: 12px; + align-items: center; +} + +/* 简化页面头部(无操作按钮) */ +.xx-page-head-simple { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15, 23, 42, 0.09); + padding: 32px 40px; + margin-bottom: 32px; +} + +.xx-page-head-simple h2 { + font-size: 28px; + font-weight: 900; + color: var(--slate, #0f172a); + margin: 0 0 8px; + letter-spacing: -0.02em; +} + +.xx-page-head-simple p { + font-size: 15px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 卡片 */ +.xx-card { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + padding: 24px; + transition: all 0.3s; +} + +.xx-card:hover { + box-shadow: 0 16px 40px rgba(15, 23, 42, 0.08); +} + +.xx-card .ant-card-head { + border-bottom: 1px solid rgba(226, 232, 240, 0.8); + padding: 20px 24px; +} + +.xx-card .ant-card-head-title { + font-weight: 800; + font-size: 17px; + color: var(--slate, #0f172a); +} + +.xx-card .ant-card-body { + padding: 24px; +} + +/* 统计卡片网格 - 4列 */ +.xx-grid-4 { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 24px; + margin-bottom: 32px; +} + +@media (max-width: 1200px) { + .xx-grid-4 { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .xx-grid-4 { + grid-template-columns: 1fr; + } +} + +/* 统计卡片 */ +.xx-stat-card { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + padding: 24px; + transition: all 0.3s; +} + +.xx-stat-card:hover { + transform: translateY(-2px); + box-shadow: 0 16px 40px rgba(15, 23, 42, 0.08); +} + +.xx-stat-card-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 16px; +} + +.xx-stat-card-icon { + width: 48px; + height: 48px; + border-radius: 14px; + display: flex; + align-items: center; + justify-content: center; + font-size: 22px; +} + +.xx-stat-card-icon.primary { + background: linear-gradient(135deg, #6366f1, #4f46e5); + color: white; +} + +.xx-stat-card-icon.success { + background: linear-gradient(135deg, #34d399, #10b981); + color: white; +} + +.xx-stat-card-icon.warning { + background: linear-gradient(135deg, #fbbf24, #f59e0b); + color: white; +} + +.xx-stat-card-icon.purple { + background: linear-gradient(135deg, #a78bfa, #8b5cf6); + color: white; +} + +.xx-stat-card-icon.info { + background: linear-gradient(135deg, #60a5fa, #3b82f6); + color: white; +} + +.xx-stat-card-icon.orange { + background: linear-gradient(135deg, #fb923c, #f97316); + color: white; +} + +.xx-stat-card-label { + font-size: 14px; + color: var(--muted, #64748b); + font-weight: 500; + margin-bottom: 8px; +} + +.xx-stat-card-value { + font-size: 32px; + font-weight: 900; + color: var(--slate, #0f172a); + line-height: 1.2; + letter-spacing: -0.02em; +} + +.xx-stat-card-value.primary { + color: var(--indigo, #4f46e5); +} + +.xx-stat-card-value.success { + color: var(--green, #10b981); +} + +.xx-stat-card-value.warning { + color: var(--amber, #f59e0b); +} + +.xx-stat-card-value.purple { + color: #8b5cf6; +} + +.xx-stat-card-growth { + font-size: 13px; + color: var(--green, #10b981); + font-weight: 600; + margin-top: 8px; + display: flex; + align-items: center; + gap: 4px; +} + +/* 数据表格 */ +.xx-table-wrapper { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + overflow: hidden; +} + +.xx-table-wrapper .ant-table { + background: transparent; +} + +.xx-table-wrapper .ant-table-thead > tr > th { + background: rgba(248, 250, 252, 0.8); + font-weight: 800; + font-size: 13px; + color: var(--slate, #0f172a); + text-transform: uppercase; + letter-spacing: 0.05em; + padding: 16px 20px; +} + +.xx-table-wrapper .ant-table-tbody > tr > td { + padding: 16px 20px; + font-size: 14px; +} + +.xx-table-wrapper .ant-table-tbody > tr:hover > td { + background: rgba(79, 70, 229, 0.03); +} + +/* V21 按钮 */ +.xx-primary-btn { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border: none !important; + border-radius: 14px !important; + font-weight: 700 !important; + box-shadow: 0 8px 20px rgba(79, 70, 229, 0.25) !important; + transition: all 0.2s !important; +} + +.xx-primary-btn:hover { + box-shadow: 0 12px 28px rgba(79, 70, 229, 0.3) !important; + transform: translateY(-1px); +} + +.xx-ghost-btn { + background: white !important; + border: 1px solid rgba(226, 232, 240, 0.95) !important; + color: var(--slate, #0f172a) !important; + border-radius: 14px !important; + font-weight: 600 !important; + transition: all 0.2s !important; +} + +.xx-ghost-btn:hover { + border-color: var(--indigo, #4f46e5) !important; + color: var(--indigo, #4f46e5) !important; +} + +/* V21 输入框 */ +.xx-search-input { + border-radius: 14px !important; + border: 1px solid rgba(226, 232, 240, 0.95) !important; + padding: 8px 16px !important; +} + +.xx-search-input:hover, +.xx-search-input:focus { + border-color: var(--indigo, #4f46e5) !important; + box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1) !important; +} + +/* V21 Select */ +.xx-select { + border-radius: 14px !important; +} + +.xx-select:hover, +.xx-select:focus { + border-color: var(--indigo, #4f46e5) !important; + box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1) !important; +} + +/* V21 Tag */ +.xx-tag { + border-radius: 8px !important; + font-weight: 600 !important; + font-size: 12px !important; + padding: 4px 10px !important; +} + +.xx-tag.info { + background: rgba(59, 130, 246, 0.1) !important; + color: #3b82f6 !important; + border: 1px solid rgba(59, 130, 246, 0.2) !important; +} + +.xx-tag.success { + background: rgba(16, 185, 129, 0.1) !important; + color: #10b981 !important; + border: 1px solid rgba(16, 185, 129, 0.2) !important; +} + +.xx-tag.warning { + background: rgba(245, 158, 11, 0.1) !important; + color: #f59e0b !important; + border: 1px solid rgba(245, 158, 11, 0.2) !important; +} + +.xx-tag.error { + background: rgba(239, 68, 68, 0.1) !important; + color: #ef4444 !important; + border: 1px solid rgba(239, 68, 68, 0.2) !important; +} + +.xx-tag.debug { + background: rgba(100, 116, 139, 0.1) !important; + color: #64748b !important; + border: 1px solid rgba(100, 116, 139, 0.2) !important; +} + +/* V21 Progress */ +.xx-progress-primary .ant-progress-circle .ant-progress-text { + color: var(--indigo, #4f46e5) !important; + font-weight: 700 !important; +} + +.xx-progress-success .ant-progress-circle .ant-progress-text { + color: var(--green, #10b981) !important; + font-weight: 700 !important; +} + +.xx-progress-warning .ant-progress-circle .ant-progress-text { + color: var(--amber, #f59e0b) !important; + font-weight: 700 !important; +} + +/* 图表容器 */ +.xx-chart-container { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + padding: 24px; +} + +.xx-chart-container .ant-card-head { + border-bottom: 1px solid rgba(226, 232, 240, 0.8); + padding: 20px 24px; +} + +.xx-chart-container .ant-card-head-title { + font-weight: 800; + font-size: 17px; + color: var(--slate, #0f172a); +} + +/* 筛选器区域 */ +.xx-filter-bar { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + padding: 20px 24px; + margin-bottom: 24px; + display: flex; + flex-wrap: wrap; + gap: 16px; + align-items: center; +} + +/* 资源监控卡片 */ +.xx-resource-card { + background: rgba(255, 255, 255, 0.94); + border: 1px solid rgba(226, 232, 240, 0.95); + border-radius: 22px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); + padding: 24px; + text-align: center; +} + +.xx-resource-card-icon { + width: 64px; + height: 64px; + border-radius: 18px; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 16px; + font-size: 28px; +} + +.xx-resource-card-label { + font-size: 14px; + color: var(--muted, #64748b); + font-weight: 600; + margin-bottom: 16px; +} + +/* 日期选择器 */ +.xx-date-picker { + border-radius: 14px !important; +} + +/* Drawer */ +.xx-drawer .ant-drawer-header { + border-bottom: 1px solid rgba(226, 232, 240, 0.8); + padding: 20px 24px; +} + +.xx-drawer .ant-drawer-title { + font-weight: 800; + font-size: 18px; + color: var(--slate, #0f172a); +} + +/* 日志详情 */ +.xx-log-detail { + padding: 4px 0; +} + +.xx-log-detail-label { + font-size: 13px; + font-weight: 700; + color: var(--slate, #0f172a); + margin-bottom: 4px; +} + +.xx-log-detail-value { + font-size: 14px; + color: var(--muted, #64748b); + background: rgba(248, 250, 252, 0.8); + padding: 12px; + border-radius: 10px; + margin-bottom: 16px; +} + +.xx-log-detail-code { + font-family: 'JetBrains Mono', 'Fira Code', monospace; + background: rgba(248, 250, 252, 0.8); + padding: 12px; + border-radius: 10px; + white-space: pre-wrap; + word-break: break-all; +} + +/* Result 页面居中 */ +.xx-result-center { + display: flex; + justify-content: center; + align-items: center; + min-height: 400px; +} + +.xx-result-center .ant-result { + padding: 48px; +} + +/* 刷新时间显示 */ +.xx-refresh-time { + font-size: 13px; + color: var(--muted, #64748b); + margin-right: 12px; +} + +/* 图表配色覆盖 */ +.recharts-text { + fill: #64748b !important; + font-size: 12px !important; +} + +.recharts-cartesian-grid-horizontal line, +.recharts-cartesian-grid-vertical line { + stroke: rgba(226, 232, 240, 0.8) !important; +} + +/* 图表 Legend */ +.recharts-legend-wrapper { + padding-top: 16px !important; +} + +.recharts-legend-item-text { + color: #64748b !important; + font-size: 13px !important; +} diff --git a/apps/web/src/pages/admin/AdminComingSoon.tsx b/apps/web/src/pages/admin/AdminComingSoon.tsx index 33c52e335..e2a8abd46 100644 --- a/apps/web/src/pages/admin/AdminComingSoon.tsx +++ b/apps/web/src/pages/admin/AdminComingSoon.tsx @@ -1,24 +1,32 @@ import React from 'react'; import { Button, Card, Result } from 'antd'; import { useNavigate } from 'react-router-dom'; +import './Admin.css'; const AdminComingSoon: React.FC = () => { const navigate = useNavigate(); return ( -
用户增长、营收趋势与留存分析
+系统数据总览与关键指标
+系统日志查询与监控
+管理系统用户与账户状态
+