refactor(frontend): 优化公共组件和布局组件

- 更新 Logo 相关组件 (AetherLogo, HeaderLogo, RippleLogo 等)
- 优化图表组件 (BarChart, LineChart, ScatterChart)
- 改进公共组件 (AlertDialog, EmptyState, LoadingState)
- 调整布局组件 (AppShell, SidebarNav, PageHeader 等)
- 优化 ActivityHeatmap 统计组件
This commit is contained in:
fawney19
2025-12-12 16:15:16 +08:00
parent 44e7117d4a
commit e9a6233655
21 changed files with 1130 additions and 517 deletions

View File

@@ -1,11 +1,21 @@
<template>
<Dialog :modelValue="modelValue" @update:modelValue="handleClose" :zIndex="80">
<Dialog
:model-value="modelValue"
:z-index="80"
@update:model-value="handleClose"
>
<template #header>
<div class="border-b border-border px-6 py-4">
<div class="flex items-center gap-3">
<component :is="icon" class="h-5 w-5 flex-shrink-0" :class="iconColorClass" />
<component
:is="icon"
class="h-5 w-5 flex-shrink-0"
:class="iconColorClass"
/>
<div class="flex-1 min-w-0">
<h3 class="text-lg font-semibold text-foreground leading-tight">{{ title }}</h3>
<h3 class="text-lg font-semibold text-foreground leading-tight">
{{ title }}
</h3>
</div>
</div>
</div>
@@ -14,22 +24,26 @@
<template #default>
<!-- 描述 -->
<div class="space-y-3">
<p v-for="(line, index) in descriptionLines" :key="index" :class="getLineClass(index)">
<p
v-for="(line, index) in descriptionLines"
:key="index"
:class="getLineClass(index)"
>
{{ line }}
</p>
</div>
<!-- 自定义内容插槽 -->
<slot></slot>
<slot />
</template>
<template #footer>
<!-- 取消按钮 -->
<Button
variant="outline"
@click="handleCancel"
:disabled="loading"
class="h-10 px-5"
@click="handleCancel"
>
{{ cancelText }}
</Button>
@@ -37,11 +51,14 @@
<!-- 确认按钮 -->
<Button
:variant="confirmVariant"
@click="handleConfirm"
:disabled="loading"
class="h-10 px-5"
@click="handleConfirm"
>
<Loader2 v-if="loading" class="animate-spin h-4 w-4 mr-2" />
<Loader2
v-if="loading"
class="animate-spin h-4 w-4 mr-2"
/>
{{ confirmText }}
</Button>
</template>

View File

@@ -3,49 +3,68 @@
<!-- 图标 -->
<div :class="iconContainerClasses">
<component
v-if="icon"
:is="icon"
v-if="icon"
:class="iconClasses"
/>
<component
v-else
:is="defaultIcon"
v-else
:class="iconClasses"
/>
</div>
<!-- 标题 -->
<h3 v-if="title" :class="titleClasses">
<h3
v-if="title"
:class="titleClasses"
>
{{ title }}
</h3>
<!-- 描述 -->
<p v-if="description" :class="descriptionClasses">
<p
v-if="description"
:class="descriptionClasses"
>
{{ description }}
</p>
<!-- 自定义内容插槽 -->
<div v-if="$slots.default" class="mt-4">
<div
v-if="$slots.default"
class="mt-4"
>
<slot />
</div>
<!-- 操作按钮 -->
<div v-if="$slots.actions || actionText" class="mt-6 flex flex-wrap items-center justify-center gap-3">
<div
v-if="$slots.actions || actionText"
class="mt-6 flex flex-wrap items-center justify-center gap-3"
>
<slot name="actions">
<Button
v-if="actionText"
@click="handleAction"
:variant="actionVariant"
:size="actionSize"
@click="handleAction"
>
<component v-if="actionIcon" :is="actionIcon" class="mr-2 h-4 w-4" />
<component
:is="actionIcon"
v-if="actionIcon"
class="mr-2 h-4 w-4"
/>
{{ actionText }}
</Button>
</slot>
</div>
<!-- 次要操作 -->
<div v-if="$slots.secondary" class="mt-3">
<div
v-if="$slots.secondary"
class="mt-3"
>
<slot name="secondary" />
</div>
</div>

View File

@@ -1,22 +1,34 @@
<template>
<div :class="containerClasses">
<div class="flex flex-col items-center gap-4">
<Skeleton v-if="variant === 'skeleton'" :class="skeletonClasses" />
<Skeleton
v-if="variant === 'skeleton'"
:class="skeletonClasses"
/>
<div v-else-if="variant === 'spinner'" class="relative">
<div class="h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary"></div>
<div
v-else-if="variant === 'spinner'"
class="relative"
>
<div class="h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary" />
</div>
<div v-else-if="variant === 'pulse'" class="flex gap-2">
<div
v-else-if="variant === 'pulse'"
class="flex gap-2"
>
<div
v-for="i in 3"
:key="i"
class="h-3 w-3 animate-pulse rounded-full bg-primary"
:style="{ animationDelay: `${i * 150}ms` }"
></div>
/>
</div>
<div v-if="message" class="text-sm text-muted-foreground">
<div
v-if="message"
class="text-sm text-muted-foreground"
>
{{ message }}
</div>
</div>