Files
geo/apps/admin-web/src/components/ArticleSourceMeta.vue
T
root 162abdc97c
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Failing after 1m39s
chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports)
- Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier
- Add root scripts: format, format:check, lint, lint:fix
- Reformat 257 files across admin-web, ops-web, desktop-client, packages
- Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters
- Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex
- Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:39:09 +08:00

171 lines
3.9 KiB
Vue

<script setup lang="ts">
import {
AppstoreOutlined,
CalendarOutlined,
ClockCircleOutlined,
CopyOutlined,
EditOutlined,
TeamOutlined,
ThunderboltOutlined,
} from '@ant-design/icons-vue'
import { computed, type Component } from 'vue'
import { formatDateTime, getSourceTypeLabel } from '@/lib/display'
const props = defineProps<{
sourceType?: string | null
generationMode?: string | null
createdAt?: string | null
}>()
const sourceLabel = computed(() => getSourceTypeLabel(props.sourceType, props.generationMode))
const createdAtLabel = computed(() => formatDateTime(props.createdAt))
const sourceVariant = computed<
'template' | 'custom' | 'instant' | 'schedule' | 'free-create' | 'imitation' | 'kol' | 'default'
>(() => {
if (props.sourceType === 'template') {
return 'template'
}
if (props.sourceType === 'free_create') {
return 'free-create'
}
if (props.sourceType === 'imitation') {
return 'imitation'
}
if (props.sourceType === 'kol') {
return 'kol'
}
if (props.sourceType === 'custom_generation') {
if (props.generationMode === 'schedule') {
return 'schedule'
}
if (props.generationMode === 'instant') {
return 'instant'
}
return 'custom'
}
return 'default'
})
const badgeIcon = computed<Component>(() => {
switch (sourceVariant.value) {
case 'template':
return AppstoreOutlined
case 'instant':
return ThunderboltOutlined
case 'schedule':
return CalendarOutlined
case 'custom':
return ThunderboltOutlined
case 'free-create':
return EditOutlined
case 'imitation':
return CopyOutlined
case 'kol':
return TeamOutlined
default:
return AppstoreOutlined
}
})
</script>
<template>
<div class="article-source-meta">
<span
class="article-source-meta__badge"
:class="`article-source-meta__badge--${sourceVariant}`"
>
<component :is="badgeIcon" />
<span>{{ sourceLabel }}</span>
</span>
<span class="article-source-meta__time">
<ClockCircleOutlined />
<span>{{ createdAtLabel }}</span>
</span>
</div>
</template>
<style scoped>
.article-source-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px 14px;
}
.article-source-meta__badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: 6px;
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
font-size: 12px;
font-weight: 600;
line-height: 1;
}
.article-source-meta__badge--template {
border: 1px solid #d9e5ff;
background: linear-gradient(180deg, #fbfcff 0%, #f3f7ff 100%);
color: #225fd1;
}
.article-source-meta__badge--custom {
border: 1px solid #d9ccff;
background: linear-gradient(180deg, #f7f4ff 0%, #efe9ff 100%);
color: #6941c6;
}
.article-source-meta__badge--instant {
border: 1px solid #f3c796;
background: linear-gradient(180deg, #fff5e9 0%, #ffe9d2 100%);
color: #b54708;
}
.article-source-meta__badge--schedule {
border: 1px solid #a7ddd3;
background: linear-gradient(180deg, #eefaf7 0%, #def3ee 100%);
color: #0b6b61;
}
.article-source-meta__badge--free-create {
border: 1px solid #d4ead8;
background: linear-gradient(180deg, #f7fcf8 0%, #eef8f1 100%);
color: #18794e;
}
.article-source-meta__badge--imitation {
border: 1px solid #bfdbfe;
background: linear-gradient(180deg, #f8fbff 0%, #e6f0ff 100%);
color: #1d4ed8;
}
.article-source-meta__badge--kol {
border: 1px solid #d6e4ff;
background: linear-gradient(180deg, #f5f8ff 0%, #eaf1ff 100%);
color: #1d4ed8;
}
.article-source-meta__badge--default {
border: 1px solid #dde3ea;
background: linear-gradient(180deg, #fbfcfd 0%, #f4f6f8 100%);
color: #44546a;
}
.article-source-meta__time {
display: inline-flex;
align-items: center;
gap: 6px;
color: #667085;
font-size: 12px;
line-height: 1;
}
.article-source-meta :deep(.anticon) {
font-size: 12px;
}
</style>