返回 AiToEarn
index.tsx
1 /**
2 * AgentFeatures - AI Agent 功能亮点轮播展示(用于首页)
3 * 使用 Swiper 实现自动轮播效果,支持无缝滚动
4 */
5 'use client'
6
7 import type { FC } from 'react'
8 import type { Swiper as SwiperType } from 'swiper'
9 import {
10 Activity,
11 BarChart3,
12 Calendar,
13 ChevronLeft,
14 ChevronRight,
15 Download,
16 FileText,
17 Frame,
18 Hash,
19 Image as ImageIcon,
20 Languages,
21 Layers,
22 Lightbulb,
23 ListTodo,
24 MessageSquare,
25 MonitorSmartphone,
26 PanelTop,
27 ScanEye,
28 Scissors,
29 Search,
30 Send,
31 Timer,
32 Users,
33 Video,
34 Workflow,
35 } from 'lucide-react'
36 import { useCallback, useRef } from 'react'
37 import { Autoplay, Pagination } from 'swiper/modules'
38 import { Swiper, SwiperSlide } from 'swiper/react'
39 import { useTransClient } from '@/app/i18n/client'
40 import { Button } from '@/components/ui/button'
41 import { cn } from '@/utils/className'
42
43 import 'swiper/css'
44 import 'swiper/css/pagination'
45 import './style.css'
46
47 interface AgentFeaturesProps {
48 className?: string
49 }
50
51 // 图标映射 - 每个功能使用不同的图标
52 const iconMap = {
53 inspiration: Lightbulb, // 创意灵感 - 灯泡
54 oneClickScript: FileText, // 一键生成脚本 - 文档
55 multiTemplates: Layers, // 多风格模板 - 图层
56 imageGenerate: ImageIcon, // 图片生成 - 图片
57 videoGenerate: Video, // 视频生成 - 视频
58 highlight: Scissors, // 高光剪辑 - 剪刀
59 storyboard: PanelTop, // 分镜设计 - 面板
60 coverSuggestion: Frame, // 封面建议 - 相框
61 download: Download, // 素材下载 - 下载
62 videoTranslation: Languages, // 视频翻译 - 语言
63 platformAdapt: MonitorSmartphone, // 平台适配 - 多设备
64 topicTag: Hash, // 话题标签 - 标签
65 seo: Search, // SEO优化 - 搜索
66 schedule: Calendar, // 定时发布 - 日历
67 multiPlatform: Send, // 多平台分发 - 发送
68 smartTime: Timer, // 智能发布时间 - 计时器
69 sse: Activity, // 流式任务 - 活动/脉冲
70 taskManagement: ListTodo, // 任务管理 - 待办列表
71 workflow: Workflow, // 可扩展工作流 - 工作流
72 videoUnderstanding: ScanEye, // 视频理解 - 扫描眼睛
73 report: BarChart3, // 运营报告 - 柱状图
74 commentAssistant: MessageSquare, // 评论助手 - 消息
75 audienceInsight: Users, // 用户画像 - 用户组
76 } as const
77
78 // 所有功能项
79 const allFeatures = [
80 'inspiration',
81 'oneClickScript',
82 'multiTemplates',
83 'imageGenerate',
84 'videoGenerate',
85 'highlight',
86 'storyboard',
87 'coverSuggestion',
88 'download',
89 'videoTranslation',
90 'platformAdapt',
91 'topicTag',
92 'seo',
93 'schedule',
94 'multiPlatform',
95 'smartTime',
96 'sse',
97 'taskManagement',
98 'workflow',
99 'videoUnderstanding',
100 'report',
101 'commentAssistant',
102 'audienceInsight',
103 ]
104
105 /**
106 * 功能卡片组件 - icon 和 title 同行布局
107 */
108 interface FeatureCardProps {
109 itemKey: string
110 t: (key: string) => string
111 }
112
113 const FeatureCard: FC<FeatureCardProps> = ({ itemKey, t }) => {
114 const Icon = iconMap[itemKey as keyof typeof iconMap]
115 const title = t(`agentFeatures.items.${itemKey}.title`)
116 const desc = t(`agentFeatures.items.${itemKey}.desc`)
117
118 return (
119 <div className="h-full rounded-xl border border-border bg-card p-4 transition-colors duration-200 hover:border-primary/30">
120 {/* icon + title 同行 */}
121 <div className="flex items-center gap-3 mb-2">
122 {/* 带渐变动画的图标容器 */}
123 <div
124 className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-muted animate-pulse"
125 style={{ animationDuration: '3s' }}
126 >
127 <Icon className="h-[18px] w-[18px] text-muted-foreground" />
128 </div>
129 <h4 className="text-sm font-medium text-foreground line-clamp-1">{title}</h4>
130 </div>
131
132 {/* 描述 */}
133 <p className="text-xs leading-relaxed text-muted-foreground line-clamp-2">{desc}</p>
134 </div>
135 )
136 }
137
138 /**
139 * AgentFeatures 主组件
140 */
141 const AgentFeatures: FC<AgentFeaturesProps> = ({ className }) => {
142 const { t } = useTransClient('promptGallery')
143 const swiperRef = useRef<SwiperType | null>(null)
144
145 // 处理 Swiper 实例
146 const onSwiper = useCallback((swiper: SwiperType) => {
147 swiperRef.current = swiper
148 }, [])
149
150 // 导航按钮点击
151 const handlePrev = useCallback(() => {
152 swiperRef.current?.slidePrev()
153 }, [])
154
155 const handleNext = useCallback(() => {
156 swiperRef.current?.slideNext()
157 }, [])
158
159 return (
160 <section className={cn('py-10 px-4 md:px-6 lg:px-8', className)}>
161 <div className="w-full max-w-5xl mx-auto">
162 {/* 标题区域 */}
163 <div className="mb-8 text-center sm:mb-8">
164 <h2 className="mb-2 text-2xl font-bold text-foreground sm:text-3xl">
165 {t('agentFeatures.title')}
166 </h2>
167 <p className="text-sm text-muted-foreground sm:text-base">
168 {t('agentFeatures.subtitle')}
169 </p>
170 </div>
171 <div className="flex flex-col gap-3 mb-8 md:flex-row md:items-end md:justify-between">
172 <div />
173 {/* 桌面端导航按钮 */}
174 <div className="hidden md:flex items- center gap-2">
175 <Button
176 variant="ghost"
177 size="icon"
178 className="h-8 w-8 rounded-full cursor-pointer"
179 onClick={handlePrev}
180 >
181 <ChevronLeft className="h-4 w-4" />
182 </Button>
183 <Button
184 variant="ghost"
185 size="icon"
186 className="h-8 w-8 rounded-full cursor-pointer"
187 onClick={handleNext}
188 >
189 <ChevronRight className="h-4 w-4" />
190 </Button>
191 </div>
192 </div>
193
194 {/* Swiper 轮播 - 移动端分页器在两侧 */}
195 <div className="flex items-center gap-2">
196 {/* 移动端左箭头 */}
197 <Button
198 variant="ghost"
199 size="icon"
200 className="md:hidden h-8 w-8 shrink-0 rounded-full cursor-pointer"
201 onClick={handlePrev}
202 >
203 <ChevronLeft className="h-4 w-4" />
204 </Button>
205
206 {/* Swiper 内容 */}
207 <div className="flex-1 min-w-0 agent-features-swiper">
208 <Swiper
209 modules={[Autoplay, Pagination]}
210 onSwiper={onSwiper}
211 spaceBetween={12}
212 slidesPerView={1}
213 loop
214 autoplay={{
215 delay: 3000,
216 disableOnInteraction: false,
217 pauseOnMouseEnter: true,
218 }}
219 pagination={{
220 clickable: true,
221 }}
222 breakpoints={{
223 // 移动端:1 个卡片
224 0: {
225 slidesPerView: 1,
226 spaceBetween: 12,
227 },
228 // 小屏幕:2 个卡片
229 480: {
230 slidesPerView: 2,
231 spaceBetween: 12,
232 },
233 // 平板:3 个卡片
234 768: {
235 slidesPerView: 3,
236 spaceBetween: 16,
237 },
238 // 桌面:4 个卡片
239 1024: {
240 slidesPerView: 4,
241 spaceBetween: 16,
242 },
243 }}
244 >
245 {allFeatures.map(itemKey => (
246 <SwiperSlide key={itemKey} className="h-auto!">
247 <FeatureCard itemKey={itemKey} t={t} />
248 </SwiperSlide>
249 ))}
250 </Swiper>
251 </div>
252
253 {/* 移动端右箭头 */}
254 <Button
255 variant="ghost"
256 size="icon"
257 className="md:hidden h-8 w-8 shrink-0 rounded-full cursor-pointer"
258 onClick={handleNext}
259 >
260 <ChevronRight className="h-4 w-4" />
261 </Button>
262 </div>
263 </div>
264 </section>
265 )
266 }
267
268 export default AgentFeatures
269
269 lines Plain Text