Initial CMPP frontend prototype

This commit is contained in:
hectorzhao
2026-06-30 16:09:46 +08:00
commit 2f3c274a30
98 changed files with 25255 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
+77
View File
@@ -0,0 +1,77 @@
import type { EChartsOption } from 'echarts';
import { chartPalette, themeColors } from '@/theme/tokens';
const axisStyle = {
axisLine: { lineStyle: { color: themeColors.border } },
axisTick: { show: false },
axisLabel: { color: themeColors.textMuted },
splitLine: { lineStyle: { color: '#EEF0F3' } },
};
export function createLineOption(params: {
labels: string[];
series: Array<{ name: string; data: number[] }>;
}): EChartsOption {
return {
color: [...chartPalette],
grid: { left: 12, right: 12, top: 36, bottom: 8, containLabel: true },
legend: { top: 0, right: 0, textStyle: { color: themeColors.textMuted } },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: params.labels, ...axisStyle },
yAxis: { type: 'value', ...axisStyle },
series: params.series.map((item) => ({
name: item.name,
data: item.data,
type: 'line',
smooth: true,
symbolSize: 7,
lineStyle: { width: 3 },
areaStyle: { opacity: 0.08 },
})),
};
}
export function createBarOption(params: {
labels: string[];
series: Array<{ name: string; data: number[] }>;
}): EChartsOption {
return {
color: [...chartPalette],
grid: { left: 12, right: 12, top: 36, bottom: 8, containLabel: true },
legend: { top: 0, right: 0, textStyle: { color: themeColors.textMuted } },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: params.labels, ...axisStyle },
yAxis: { type: 'value', ...axisStyle },
series: params.series.map((item) => ({
name: item.name,
data: item.data,
type: 'bar',
barMaxWidth: 28,
borderRadius: [6, 6, 0, 0],
})),
};
}
export function createPieOption(params: {
data: Array<{ name: string; value: number }>;
}): EChartsOption {
return {
color: [...chartPalette],
legend: {
bottom: 0,
left: 'center',
textStyle: { color: themeColors.textMuted },
},
tooltip: { trigger: 'item' },
series: [
{
type: 'pie',
radius: ['48%', '72%'],
center: ['50%', '44%'],
avoidLabelOverlap: true,
label: { color: themeColors.text },
data: params.data,
},
],
};
}
+53
View File
@@ -0,0 +1,53 @@
export const themeColors = {
brand: '#12121A',
brandHover: '#1C1C27',
accent: '#D9C3A0',
accentSoft: '#F6EFE4',
selected: '#2563EB',
selectedSoft: '#EFF6FF',
surface: '#FFFFFF',
background: '#F6F7F9',
border: '#E5E7EB',
text: '#1F2937',
textStrong: '#111827',
textMuted: '#6B7280',
success: '#16A34A',
warning: '#D97706',
danger: '#DC2626',
info: '#2563EB',
} as const;
export const chartPalette = [
themeColors.selected,
themeColors.accent,
themeColors.success,
themeColors.warning,
'#64748B',
'#0F766E',
] as const;
export const statusTone = {
success: {
color: themeColors.success,
background: '#ECFDF3',
},
warning: {
color: themeColors.warning,
background: '#FFFBEB',
},
danger: {
color: themeColors.danger,
background: '#FEF2F2',
},
info: {
color: themeColors.info,
background: themeColors.selectedSoft,
},
neutral: {
color: themeColors.textMuted,
background: '#F3F4F6',
},
} as const;
export type ThemeColorName = keyof typeof themeColors;
export type StatusToneName = keyof typeof statusTone;