138 lines
5.8 KiB
TypeScript
138 lines
5.8 KiB
TypeScript
'use client'
|
||
|
||
import { useThemeStyles, cn } from '@/lib/ui-styles'
|
||
import type { BuiltinTemplateConfig } from './types'
|
||
|
||
interface BuiltInTemplateGridProps {
|
||
presets: BuiltinTemplateConfig[]
|
||
onPreview: (presetKey: string) => void
|
||
onQuickCreate: (presetKey: string) => void
|
||
canQuickCreate: boolean
|
||
onRequestUpgrade: () => void
|
||
onToggleEnabled?: (presetKey: string) => void
|
||
onEnableAll?: () => void
|
||
enabledTemplates?: Set<string>
|
||
allPresets?: BuiltinTemplateConfig[]
|
||
}
|
||
|
||
export default function BuiltInTemplateGrid({
|
||
presets,
|
||
onPreview,
|
||
onQuickCreate,
|
||
canQuickCreate,
|
||
onRequestUpgrade,
|
||
onToggleEnabled,
|
||
onEnableAll,
|
||
enabledTemplates = new Set(),
|
||
allPresets = [],
|
||
}: BuiltInTemplateGridProps) {
|
||
const styles = useThemeStyles()
|
||
const hasDisabledTemplates = allPresets.length > 0 && enabledTemplates.size < allPresets.length
|
||
|
||
return (
|
||
<div className="px-6 pt-5 pb-4 border-b border-slate-200/70 dark:border-slate-700/70">
|
||
<div className="flex items-center justify-between gap-4 mb-3">
|
||
<div>
|
||
<h3 className="text-sm font-semibold text-slate-900 dark:text-white">预制模板(推荐)</h3>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">常用场景一键启用,也可作为自定义模板的起点</p>
|
||
<p className="text-[11px] text-slate-400 dark:text-slate-500">
|
||
点击卡片仅预览示例,内容不可直接编辑,需复制为自定义模板后才可修改。
|
||
</p>
|
||
</div>
|
||
{hasDisabledTemplates && onEnableAll && (
|
||
<button
|
||
type="button"
|
||
onClick={() => onEnableAll()}
|
||
className={cn(
|
||
styles.buttonStyles.secondary,
|
||
styles.buttonModifiers.compactXs,
|
||
'text-xs',
|
||
'bg-white dark:bg-slate-800 border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-200' // 显式添加背景色和文字色
|
||
)}
|
||
>
|
||
启用所有模板 ({allPresets.length - enabledTemplates.size} 个已禁用)
|
||
</button>
|
||
)}
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||
{presets.map((preset) => {
|
||
const fieldCount = preset.getFields().length
|
||
return (
|
||
<div
|
||
key={preset.key}
|
||
className={cn(styles.cardStyles.hover, 'group relative overflow-hidden cursor-pointer')}
|
||
onClick={() => onPreview(preset.key)}
|
||
>
|
||
<div className="flex items-start justify-between gap-3">
|
||
<div className="space-y-1">
|
||
<p className="text-sm font-semibold text-slate-900 dark:text-white">{preset.name}</p>
|
||
<p className="text-xs text-slate-500 dark:text-slate-400 leading-snug">{preset.description}</p>
|
||
</div>
|
||
<span className="px-2.5 py-0.5 rounded-full text-[11px] font-medium text-slate-600 dark:text-slate-300 bg-slate-100 dark:bg-slate-800 border border-slate-200 dark:border-slate-700">
|
||
预制
|
||
</span>
|
||
</div>
|
||
<div className="mt-4 flex items-center justify-between gap-3">
|
||
<div className="flex items-center gap-1.5 text-[11px] text-slate-400 dark:text-slate-500">
|
||
<svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 7h16M4 12h10m-10 5h7" />
|
||
</svg>
|
||
<span>{fieldCount} 个字段</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
{onToggleEnabled && (
|
||
<button
|
||
type="button"
|
||
onClick={(e) => {
|
||
e.stopPropagation()
|
||
onToggleEnabled(preset.key)
|
||
}}
|
||
className={cn(
|
||
enabledTemplates.has(preset.key)
|
||
? styles.buttonStyles.secondary
|
||
: styles.buttonStyles.secondary,
|
||
styles.buttonModifiers.compactXs,
|
||
styles.buttonModifiers.pill,
|
||
'text-xs'
|
||
)}
|
||
title={enabledTemplates.has(preset.key) ? '禁用此模板' : '启用此模板'}
|
||
>
|
||
{enabledTemplates.has(preset.key) ? '禁用' : '启用'}
|
||
</button>
|
||
)}
|
||
<button
|
||
type="button"
|
||
onClick={(e) => {
|
||
e.stopPropagation()
|
||
if (!canQuickCreate) {
|
||
onRequestUpgrade()
|
||
return
|
||
}
|
||
onQuickCreate(preset.key)
|
||
}}
|
||
className={cn(
|
||
styles.buttonStyles.primary,
|
||
styles.buttonModifiers.compactXs,
|
||
styles.buttonModifiers.pill,
|
||
'inline-flex items-center gap-1.5 shadow-none',
|
||
!canQuickCreate && 'opacity-75'
|
||
)}
|
||
title={canQuickCreate ? '快速创建副本' : '当前许可证未包含自定义模板功能'}
|
||
>
|
||
<svg className="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor">
|
||
<path d="M10 3.5a.75.75 0 01.75.75v5h5a.75.75 0 010 1.5h-5v5a.75.75 0 01-1.5 0v-5h-5a.75.75 0 010-1.5h5v-5A.75.75 0 0110 3.5z" />
|
||
</svg>
|
||
{canQuickCreate ? '快速创建副本' : '授权后创建'}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
|