|
@@ -53,25 +53,48 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="style-selector">
|
|
<div class="style-selector">
|
|
|
- <div class="label">视觉方向</div>
|
|
|
|
|
- <div class="style-options">
|
|
|
|
|
|
|
+ <div class="template-selector-head">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div class="label">场景模板</div>
|
|
|
|
|
+ <div class="template-help">生成大纲后系统会按年级和课程内容推荐,你也可以直接指定。</div>
|
|
|
|
|
+ </div>
|
|
|
<button
|
|
<button
|
|
|
|
|
+ v-if="templateSelectionMode === 'manual'"
|
|
|
type="button"
|
|
type="button"
|
|
|
- :class="['style-option', { active: selectedStyle === 'cartoon' }]"
|
|
|
|
|
|
|
+ class="auto-template-button"
|
|
|
:disabled="working"
|
|
:disabled="working"
|
|
|
- @click="selectedStyle = 'cartoon'"
|
|
|
|
|
|
|
+ @click="useRecommendedTemplate"
|
|
|
>
|
|
>
|
|
|
- <strong>卡通课堂</strong>
|
|
|
|
|
- <span>适合小学和互动课堂</span>
|
|
|
|
|
|
|
+ 恢复智能推荐
|
|
|
</button>
|
|
</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="outline" class="template-recommendation">
|
|
|
|
|
+ <span>系统推荐</span>
|
|
|
|
|
+ <strong>{{ recommendedTemplate.name }}</strong>
|
|
|
|
|
+ <span>{{ templateRecommendation.reason }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="style-options">
|
|
|
<button
|
|
<button
|
|
|
|
|
+ v-for="template in coursewareTemplates"
|
|
|
|
|
+ :key="template.id"
|
|
|
type="button"
|
|
type="button"
|
|
|
- :class="['style-option', { active: selectedStyle === 'clean' }]"
|
|
|
|
|
|
|
+ :class="['style-option', { active: selectedTemplateId === template.id }]"
|
|
|
:disabled="working"
|
|
:disabled="working"
|
|
|
- @click="selectedStyle = 'clean'"
|
|
|
|
|
|
|
+ @click="selectTemplate(template.id)"
|
|
|
>
|
|
>
|
|
|
- <strong>简洁教学</strong>
|
|
|
|
|
- <span>适合高年级和知识讲解</span>
|
|
|
|
|
|
|
+ <span class="template-mini" :style="templateCardStyle(template)">
|
|
|
|
|
+ <i class="mini-band"></i>
|
|
|
|
|
+ <i class="mini-title"></i>
|
|
|
|
|
+ <i class="mini-content first"></i>
|
|
|
|
|
+ <i class="mini-content second"></i>
|
|
|
|
|
+ <i class="mini-accent"></i>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span class="template-card-title">
|
|
|
|
|
+ <strong>{{ template.name }}</strong>
|
|
|
|
|
+ <em v-if="outline && templateRecommendation.id === template.id">推荐</em>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span>{{ template.description }}</span>
|
|
|
|
|
+ <small>{{ template.scene }}</small>
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -172,6 +195,35 @@
|
|
|
<div class="sample-title">第{{ samplePageNo }}页 · {{ samplePageTitle }}</div>
|
|
<div class="sample-title">第{{ samplePageNo }}页 · {{ samplePageTitle }}</div>
|
|
|
<div class="sample-hint">{{ samplePageReason }}。你可以切换任意页面查看,也可以只重新生成当前页样张。</div>
|
|
<div class="sample-hint">{{ samplePageReason }}。你可以切换任意页面查看,也可以只重新生成当前页样张。</div>
|
|
|
|
|
|
|
|
|
|
+ <div class="current-template-card">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <span>当前模板</span>
|
|
|
|
|
+ <strong>{{ selectedTemplate.name }}</strong>
|
|
|
|
|
+ <small>切换模板只重绘视觉,不改变大纲和教学内容</small>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button type="button" :disabled="working" @click="templatePickerExpanded = !templatePickerExpanded">
|
|
|
|
|
+ {{ templatePickerExpanded ? "收起模板" : "更换模板" }}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="templatePickerExpanded" class="sample-template-picker">
|
|
|
|
|
+ <button
|
|
|
|
|
+ v-for="template in coursewareTemplates"
|
|
|
|
|
+ :key="template.id"
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ :class="['sample-template-option', { active: selectedTemplateId === template.id }]"
|
|
|
|
|
+ :disabled="working"
|
|
|
|
|
+ @click="selectTemplate(template.id, true)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="template-swatches">
|
|
|
|
|
+ <i v-for="color in templateSwatches(template)" :key="color" :style="{ background: color }"></i>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span
|
|
|
|
|
+ ><strong>{{ template.name }}</strong
|
|
|
|
|
+ ><small>{{ template.scene }}</small></span
|
|
|
|
|
+ >
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<div class="sample-page-control">
|
|
<div class="sample-page-control">
|
|
|
<button type="button" :disabled="working || samplePageIndex <= 0" @click="previewPreviousPage">上一页</button>
|
|
<button type="button" :disabled="working || samplePageIndex <= 0" @click="previewPreviousPage">上一页</button>
|
|
|
<select v-model.number="selectedPageNo" :disabled="working">
|
|
<select v-model.number="selectedPageNo" :disabled="working">
|
|
@@ -371,6 +423,13 @@ import {
|
|
|
} from "@/api/aiCourseware"
|
|
} from "@/api/aiCourseware"
|
|
|
import { aiCoursewareToSlides } from "@/utils/aiCoursewareToSlides"
|
|
import { aiCoursewareToSlides } from "@/utils/aiCoursewareToSlides"
|
|
|
import { inspectAiPptQuality, type AiPptQualityReport } from "@/utils/aiPptQuality"
|
|
import { inspectAiPptQuality, type AiPptQualityReport } from "@/utils/aiPptQuality"
|
|
|
|
|
+import {
|
|
|
|
|
+ AI_COURSEWARE_TEMPLATES,
|
|
|
|
|
+ getAiCoursewareTemplate,
|
|
|
|
|
+ recommendAiCoursewareTemplate,
|
|
|
|
|
+ type AiCoursewareTemplate,
|
|
|
|
|
+ type AiCoursewareTemplateId
|
|
|
|
|
+} from "@/config/aiCoursewareTemplates"
|
|
|
import type { Slide, SlideTheme } from "@/types/slides"
|
|
import type { Slide, SlideTheme } from "@/types/slides"
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
@@ -395,7 +454,10 @@ const workflowSteps = [
|
|
|
{ value: 3, label: "全稿预览" }
|
|
{ value: 3, label: "全稿预览" }
|
|
|
] as const
|
|
] as const
|
|
|
const taskMode = ref<"full" | "sample">("full")
|
|
const taskMode = ref<"full" | "sample">("full")
|
|
|
-const selectedStyle = ref<"cartoon" | "clean">("cartoon")
|
|
|
|
|
|
|
+const coursewareTemplates = AI_COURSEWARE_TEMPLATES
|
|
|
|
|
+const selectedTemplateId = ref<AiCoursewareTemplateId>("fresh-education")
|
|
|
|
|
+const templateSelectionMode = ref<"auto" | "manual">("auto")
|
|
|
|
|
+const templatePickerExpanded = ref(false)
|
|
|
const paletteVariant = ref(0)
|
|
const paletteVariant = ref(0)
|
|
|
const pageRange = ref("9-12")
|
|
const pageRange = ref("9-12")
|
|
|
const preferences = reactive<AiCoursewarePreferences>({
|
|
const preferences = reactive<AiCoursewarePreferences>({
|
|
@@ -419,6 +481,14 @@ const pollTimer = ref<number>()
|
|
|
const selectedPageNo = ref(1)
|
|
const selectedPageNo = ref(1)
|
|
|
const outlineLoading = ref(false)
|
|
const outlineLoading = ref(false)
|
|
|
const working = computed(() => outlineLoading.value || taskInfo.value?.status === "PENDING" || taskInfo.value?.status === "RUNNING")
|
|
const working = computed(() => outlineLoading.value || taskInfo.value?.status === "PENDING" || taskInfo.value?.status === "RUNNING")
|
|
|
|
|
+const selectedTemplate = computed(() => getAiCoursewareTemplate(selectedTemplateId.value))
|
|
|
|
|
+const selectedStyle = computed(() => selectedTemplate.value.baseStyle)
|
|
|
|
|
+const templateRecommendation = computed(() =>
|
|
|
|
|
+ outline.value
|
|
|
|
|
+ ? recommendAiCoursewareTemplate(outline.value)
|
|
|
|
|
+ : { id: "fresh-education" as AiCoursewareTemplateId, reason: "生成大纲后将根据课程内容自动推荐" }
|
|
|
|
|
+)
|
|
|
|
|
+const recommendedTemplate = computed(() => getAiCoursewareTemplate(templateRecommendation.value.id))
|
|
|
const progressValue = computed(() => taskInfo.value?.progress || 0)
|
|
const progressValue = computed(() => taskInfo.value?.progress || 0)
|
|
|
const progressSteps = [
|
|
const progressSteps = [
|
|
|
{ threshold: 0, label: "准备中" },
|
|
{ threshold: 0, label: "准备中" },
|
|
@@ -464,9 +534,11 @@ const samplePageReason = computed(() => {
|
|
|
const sampleSlide = computed(() => {
|
|
const sampleSlide = computed(() => {
|
|
|
if (!outline.value?.pages.length) return undefined
|
|
if (!outline.value?.pages.length) return undefined
|
|
|
const previewOutline = { ...outline.value, style: selectedStyle.value }
|
|
const previewOutline = { ...outline.value, style: selectedStyle.value }
|
|
|
- return aiCoursewareToSlides(previewOutline, { enableAnimations: preferences.enableAnimations, paletteVariant: paletteVariant.value }).slides[
|
|
|
|
|
- samplePageIndex.value
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ return aiCoursewareToSlides(previewOutline, {
|
|
|
|
|
+ enableAnimations: preferences.enableAnimations,
|
|
|
|
|
+ paletteVariant: paletteVariant.value,
|
|
|
|
|
+ templateId: selectedTemplateId.value
|
|
|
|
|
+ }).slides[samplePageIndex.value]
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const layoutOptions = [
|
|
const layoutOptions = [
|
|
@@ -495,9 +567,9 @@ const layoutOptions = [
|
|
|
{ value: "homework_list", label: "课后任务" }
|
|
{ value: "homework_list", label: "课后任务" }
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
-watch(selectedStyle, style => {
|
|
|
|
|
|
|
+watch(selectedTemplateId, () => {
|
|
|
paletteVariant.value = 0
|
|
paletteVariant.value = 0
|
|
|
- if (outline.value) outline.value.style = style
|
|
|
|
|
|
|
+ if (outline.value) outline.value.style = selectedStyle.value
|
|
|
invalidateVisualApproval()
|
|
invalidateVisualApproval()
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -541,6 +613,7 @@ async function handleOutline() {
|
|
|
})
|
|
})
|
|
|
if (res.code === 200) {
|
|
if (res.code === 200) {
|
|
|
outline.value = res.data as AiCoursewareOutline
|
|
outline.value = res.data as AiCoursewareOutline
|
|
|
|
|
+ if (templateSelectionMode.value === "auto") selectedTemplateId.value = recommendAiCoursewareTemplate(outline.value).id
|
|
|
outline.value.style = selectedStyle.value
|
|
outline.value.style = selectedStyle.value
|
|
|
selectedPageNo.value = outline.value.pages[0]?.pageNo || 1
|
|
selectedPageNo.value = outline.value.pages[0]?.pageNo || 1
|
|
|
sampleFeedbackTags.value = []
|
|
sampleFeedbackTags.value = []
|
|
@@ -675,7 +748,8 @@ function rebuildDraftPreview() {
|
|
|
draftOutline.value.style = selectedStyle.value
|
|
draftOutline.value.style = selectedStyle.value
|
|
|
draftConverted.value = aiCoursewareToSlides(draftOutline.value, {
|
|
draftConverted.value = aiCoursewareToSlides(draftOutline.value, {
|
|
|
enableAnimations: preferences.enableAnimations,
|
|
enableAnimations: preferences.enableAnimations,
|
|
|
- paletteVariant: paletteVariant.value
|
|
|
|
|
|
|
+ paletteVariant: paletteVariant.value,
|
|
|
|
|
+ templateId: selectedTemplateId.value
|
|
|
})
|
|
})
|
|
|
draftQuality.value = inspectAiPptQuality(draftOutline.value, draftConverted.value.slides, preferences)
|
|
draftQuality.value = inspectAiPptQuality(draftOutline.value, draftConverted.value.slides, preferences)
|
|
|
}
|
|
}
|
|
@@ -798,6 +872,37 @@ function previewNextPage() {
|
|
|
if (page) selectedPageNo.value = page.pageNo
|
|
if (page) selectedPageNo.value = page.pageNo
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function selectTemplate(templateId: AiCoursewareTemplateId, fromSample = false) {
|
|
|
|
|
+ templateSelectionMode.value = "manual"
|
|
|
|
|
+ selectedTemplateId.value = templateId
|
|
|
|
|
+ if (fromSample) {
|
|
|
|
|
+ templatePickerExpanded.value = false
|
|
|
|
|
+ ElMessage.success(`已切换为${getAiCoursewareTemplate(templateId).name},教学内容未改变`)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function useRecommendedTemplate() {
|
|
|
|
|
+ templateSelectionMode.value = "auto"
|
|
|
|
|
+ selectedTemplateId.value = templateRecommendation.value.id
|
|
|
|
|
+ ElMessage.success(`已使用系统推荐的${recommendedTemplate.value.name}`)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function templateCardStyle(template: AiCoursewareTemplate): Record<string, string> {
|
|
|
|
|
+ const palette = template.palettes[0]
|
|
|
|
|
+ return {
|
|
|
|
|
+ "--template-primary": palette.primary,
|
|
|
|
|
+ "--template-secondary": palette.secondary,
|
|
|
|
|
+ "--template-accent": palette.accent,
|
|
|
|
|
+ "--template-background": palette.background,
|
|
|
|
|
+ "--template-surface": palette.surface
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function templateSwatches(template: AiCoursewareTemplate) {
|
|
|
|
|
+ const palette = template.palettes[0]
|
|
|
|
|
+ return [palette.primary, palette.secondary, palette.accent]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function updateStudentHeadline(page: AiCoursewarePage, event: Event) {
|
|
function updateStudentHeadline(page: AiCoursewarePage, event: Event) {
|
|
|
if (!page.studentContent) page.studentContent = { headline: "", points: [] }
|
|
if (!page.studentContent) page.studentContent = { headline: "", points: [] }
|
|
|
page.studentContent.headline = (event.target as HTMLInputElement).value.trim()
|
|
page.studentContent.headline = (event.target as HTMLInputElement).value.trim()
|
|
@@ -842,10 +947,7 @@ function buildExtraPrompt() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function buildVisualPrompt() {
|
|
function buildVisualPrompt() {
|
|
|
- const base =
|
|
|
|
|
- selectedStyle.value === "clean"
|
|
|
|
|
- ? "简洁教学风格,层级清晰,避免装饰性卡片堆叠,保持大字号和明确视觉焦点。"
|
|
|
|
|
- : "卡通课堂风格,适合低龄学生,使用统一画风的具体人物、动作和场景,避免成人商务卡片风格。"
|
|
|
|
|
|
|
+ const base = selectedTemplate.value.visualPrompt
|
|
|
const asset =
|
|
const asset =
|
|
|
preferences.assetStyle === "illustration"
|
|
preferences.assetStyle === "illustration"
|
|
|
? "主视觉使用统一画风插画。"
|
|
? "主视觉使用统一画风插画。"
|
|
@@ -864,7 +966,7 @@ function buildVisualPrompt() {
|
|
|
: paletteVariant.value === 2
|
|
: paletteVariant.value === 2
|
|
|
? "配色使用柔和紫色与珊瑚色体系。"
|
|
? "配色使用柔和紫色与珊瑚色体系。"
|
|
|
: "配色保持明快且有清晰对比。"
|
|
: "配色保持明快且有清晰对比。"
|
|
|
- return `${base}${asset}${source}${palette}`
|
|
|
|
|
|
|
+ return `${base}模板场景:${selectedTemplate.value.scene}。${asset}${source}${palette}`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function formatPageNo(pageNo?: number) {
|
|
function formatPageNo(pageNo?: number) {
|
|
@@ -1103,13 +1205,56 @@ function resourceTypeName(type: string) {
|
|
|
.style-selector {
|
|
.style-selector {
|
|
|
margin-top: 12px;
|
|
margin-top: 12px;
|
|
|
}
|
|
}
|
|
|
-.style-options {
|
|
|
|
|
|
|
+.template-selector-head {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-end;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+.template-help {
|
|
|
|
|
+ margin-top: -3px;
|
|
|
|
|
+ color: #7b8794;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+.auto-template-button {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ padding: 5px 10px;
|
|
|
|
|
+ border: 1px solid #cfe0f6;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: #f5f9ff;
|
|
|
|
|
+ color: $themeColor;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+}
|
|
|
|
|
+.template-recommendation {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+ padding: 8px 10px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: #eef6ff;
|
|
|
|
|
+ color: #52616b;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ span:first-child {
|
|
|
|
|
+ padding: 2px 6px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ background: $themeColor;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ strong {
|
|
|
|
|
+ color: #1f2933;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.style-options {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
|
gap: 10px;
|
|
gap: 10px;
|
|
|
|
|
+ margin-top: 9px;
|
|
|
}
|
|
}
|
|
|
.style-option {
|
|
.style-option {
|
|
|
- width: 210px;
|
|
|
|
|
- padding: 10px 12px;
|
|
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ padding: 9px;
|
|
|
border: 1px solid #dfe5ec;
|
|
border: 1px solid #dfe5ec;
|
|
|
border-radius: 8px;
|
|
border-radius: 8px;
|
|
|
background: #fff;
|
|
background: #fff;
|
|
@@ -1117,18 +1262,91 @@ function resourceTypeName(type: string) {
|
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
|
}
|
|
}
|
|
|
.style-option strong,
|
|
.style-option strong,
|
|
|
-.style-option span {
|
|
|
|
|
|
|
+.style-option span,
|
|
|
|
|
+.style-option small {
|
|
|
display: block;
|
|
display: block;
|
|
|
}
|
|
}
|
|
|
-.style-option span {
|
|
|
|
|
|
|
+.style-option > span:not(.template-mini):not(.template-card-title) {
|
|
|
margin-top: 4px;
|
|
margin-top: 4px;
|
|
|
color: #7b8794;
|
|
color: #7b8794;
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
}
|
|
}
|
|
|
|
|
+.style-option small {
|
|
|
|
|
+ margin-top: 6px;
|
|
|
|
|
+ color: #52616b;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
.style-option.active {
|
|
.style-option.active {
|
|
|
border-color: $themeColor;
|
|
border-color: $themeColor;
|
|
|
box-shadow: 0 0 0 2px rgba($themeColor, 0.12);
|
|
box-shadow: 0 0 0 2px rgba($themeColor, 0.12);
|
|
|
}
|
|
}
|
|
|
|
|
+.template-mini {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ height: 66px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: var(--template-background);
|
|
|
|
|
+ box-shadow: inset 0 0 0 1px rgba(31, 41, 51, 0.06);
|
|
|
|
|
+ i {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-band {
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ width: 32%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ background: var(--template-primary);
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-title {
|
|
|
|
|
+ left: 38%;
|
|
|
|
|
+ top: 13px;
|
|
|
|
|
+ width: 42%;
|
|
|
|
|
+ height: 7px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ background: var(--template-primary);
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-content {
|
|
|
|
|
+ left: 38%;
|
|
|
|
|
+ width: 52%;
|
|
|
|
|
+ height: 14px;
|
|
|
|
|
+ border-radius: 3px;
|
|
|
|
|
+ background: var(--template-surface);
|
|
|
|
|
+ box-shadow: 0 2px 5px rgba(31, 41, 51, 0.08);
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-content.first {
|
|
|
|
|
+ top: 29px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-content.second {
|
|
|
|
|
+ top: 47px;
|
|
|
|
|
+ width: 37%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .mini-accent {
|
|
|
|
|
+ right: 7%;
|
|
|
|
|
+ bottom: 6px;
|
|
|
|
|
+ width: 11px;
|
|
|
|
|
+ height: 11px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: var(--template-accent);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.template-card-title {
|
|
|
|
|
+ display: flex !important;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ em {
|
|
|
|
|
+ padding: 2px 5px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ background: #eaf7f4;
|
|
|
|
|
+ color: #168f86;
|
|
|
|
|
+ font-size: 10px;
|
|
|
|
|
+ font-style: normal;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
.label {
|
|
.label {
|
|
|
margin-bottom: 8px;
|
|
margin-bottom: 8px;
|
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
@@ -1169,6 +1387,98 @@ function resourceTypeName(type: string) {
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
line-height: 1.6;
|
|
line-height: 1.6;
|
|
|
}
|
|
}
|
|
|
|
|
+.current-template-card {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ padding: 9px 10px;
|
|
|
|
|
+ border: 1px solid #dbe7f5;
|
|
|
|
|
+ border-radius: 7px;
|
|
|
|
|
+ background: #f5f9ff;
|
|
|
|
|
+ span,
|
|
|
|
|
+ small {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ }
|
|
|
|
|
+ span {
|
|
|
|
|
+ color: #7b8794;
|
|
|
|
|
+ font-size: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ strong {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ margin: 2px 0;
|
|
|
|
|
+ color: #1f2933;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ }
|
|
|
|
|
+ small {
|
|
|
|
|
+ color: #7b8794;
|
|
|
|
|
+ font-size: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ button {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ padding: 0 10px;
|
|
|
|
|
+ border: 1px solid $themeColor;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: $themeColor;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.sample-template-picker {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+ margin: -2px 0 10px;
|
|
|
|
|
+}
|
|
|
|
|
+.sample-template-option {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ padding: 7px 8px;
|
|
|
|
|
+ border: 1px solid #dfe5ec;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ &.active {
|
|
|
|
|
+ border-color: $themeColor;
|
|
|
|
|
+ background: #f5f9ff;
|
|
|
|
|
+ }
|
|
|
|
|
+ > span:last-child {
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ strong,
|
|
|
|
|
+ small {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ }
|
|
|
|
|
+ strong {
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ color: #33404d;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ small {
|
|
|
|
|
+ margin-top: 2px;
|
|
|
|
|
+ color: #8a96a3;
|
|
|
|
|
+ font-size: 9px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.template-swatches {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ width: 34px;
|
|
|
|
|
+ height: 28px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ i {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
.sample-page-control {
|
|
.sample-page-control {
|
|
|
display: grid;
|
|
display: grid;
|
|
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
grid-template-columns: auto minmax(0, 1fr) auto;
|