返回 AiToEarn
PluginGuideContent.tsx
根目录 / project / aitoearn-web / src / app / [lng] / websit / plugin-guide / PluginGuideContent.tsx
1 /**
2 * PluginGuideContent - 浏览器插件图文教学内容组件
3 * 客户端组件,包含图片预览交互和国际化翻译
4 */
5 'use client'
6
7 import {
8 CheckCircle2,
9 ChevronRight,
10 Download,
11 HelpCircle,
12 Puzzle,
13 Shield,
14 Smartphone,
15 ZoomIn,
16 } from 'lucide-react'
17 import Image from 'next/image'
18 import Link from 'next/link'
19 import { useCallback, useState } from 'react'
20 import { useTransClient } from '@/app/i18n/client'
21 import { MediaPreview } from '@/components/common/MediaPreview'
22 import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
23 import { Card } from '@/components/ui/card'
24 import { cn } from '@/utils/className'
25
26 interface PublicImageAsset {
27 src: string
28 width: number
29 height: number
30 }
31
32 const pluginGuideImages = {
33 pluginGuideImg1: { src: '/assets/plugin-guide-images/pluginGuideImg1.png', width: 1917, height: 941 },
34 pluginGuideImg3: { src: '/assets/plugin-guide-images/pluginGuideImg3.png', width: 1912, height: 1026 },
35 pluginGuideImg4: { src: '/assets/plugin-guide-images/pluginGuideImg4.png', width: 1912, height: 1032 },
36 pluginGuideImg8: { src: '/assets/plugin-guide-images/pluginGuideImg8.png', width: 1912, height: 976 },
37 pluginGuideImg10: { src: '/assets/plugin-guide-images/pluginGuideImg10.png', width: 398, height: 885 },
38 pluginGuideImg11: { src: '/assets/plugin-guide-images/pluginGuideImg11.png', width: 1908, height: 1024 },
39 pluginGuideImg12: { src: '/assets/plugin-guide-images/pluginGuideImg12.png', width: 1910, height: 926 },
40 pluginGuideImg13: { src: '/assets/plugin-guide-images/pluginGuideImg13.png', width: 1908, height: 939 },
41 pluginGuideImg14: { src: '/assets/plugin-guide-images/pluginGuideImg14.png', width: 1905, height: 937 },
42 pluginGuideImg15: { src: '/assets/plugin-guide-images/pluginGuideImg15.png', width: 1896, height: 936 },
43 pluginGuideImg16: { src: '/assets/plugin-guide-images/pluginGuideImg16.png', width: 1915, height: 922 },
44 pluginGuideImg17: { src: '/assets/plugin-guide-images/pluginGuideImg17.png', width: 1897, height: 896 },
45 pluginGuideImg18: { src: '/assets/plugin-guide-images/pluginGuideImg18.png', width: 407, height: 905 },
46 pluginGuideImg19: { src: '/assets/plugin-guide-images/pluginGuideImg19.png', width: 411, height: 904 },
47 pluginGuideImg1_1: { src: '/assets/plugin-guide-images/pluginGuideImg1-1.png', width: 1618, height: 827 },
48 pluginGuideImg1_2: { src: '/assets/plugin-guide-images/pluginGuideImg1-2.png', width: 1878, height: 1015 },
49 pluginGuideImg1_3: { src: '/assets/plugin-guide-images/pluginGuideImg1-3.png', width: 1893, height: 935 },
50 pluginGuideImg1_4: { src: '/assets/plugin-guide-images/pluginGuideImg1-4.png', width: 1789, height: 975 },
51 pluginGuideImg1_5: { src: '/assets/plugin-guide-images/pluginGuideImg1-5.png', width: 1850, height: 940 },
52 } satisfies Record<string, PublicImageAsset>
53
54 const {
55 pluginGuideImg1,
56 pluginGuideImg3,
57 pluginGuideImg4,
58 pluginGuideImg8,
59 pluginGuideImg10,
60 pluginGuideImg11,
61 pluginGuideImg12,
62 pluginGuideImg13,
63 pluginGuideImg14,
64 pluginGuideImg15,
65 pluginGuideImg16,
66 pluginGuideImg17,
67 pluginGuideImg18,
68 pluginGuideImg19,
69 pluginGuideImg1_1,
70 pluginGuideImg1_2,
71 pluginGuideImg1_3,
72 pluginGuideImg1_4,
73 pluginGuideImg1_5,
74 } = pluginGuideImages
75
76 // 所有图片列表,用于 MediaPreview
77 const ALL_IMAGES = [
78 pluginGuideImg1,
79 pluginGuideImg3,
80 pluginGuideImg4,
81 pluginGuideImg1_1,
82 pluginGuideImg1_2,
83 pluginGuideImg1_3,
84 pluginGuideImg1_4,
85 pluginGuideImg1_5,
86 pluginGuideImg8,
87 pluginGuideImg18,
88 pluginGuideImg19,
89 pluginGuideImg10,
90 pluginGuideImg11,
91 pluginGuideImg12,
92 pluginGuideImg13,
93 pluginGuideImg14,
94 pluginGuideImg15,
95 pluginGuideImg16,
96 pluginGuideImg17,
97 ]
98
99 /**
100 * 步骤卡片组件
101 */
102 interface StepCardProps {
103 stepNumber: number
104 title: string
105 children: React.ReactNode
106 icon?: React.ReactNode
107 }
108
109 function StepCard({ stepNumber, title, children, icon }: StepCardProps) {
110 return (
111 <div className="relative">
112 {/* 步骤连接线 */}
113 <div className="absolute left-[18px] top-14 bottom-0 w-[2px] bg-gradient-to-b from-[#c565ef]/30 to-[#55D9ED]/15" />
114
115 <div className="flex gap-4 md:gap-6">
116 {/* 步骤编号 */}
117 <div className="shrink-0 w-9 h-9 rounded-full bg-gradient-to-br from-[#c565ef] to-[#55D9ED] text-white flex items-center justify-center font-semibold text-sm z-10 shadow-md shadow-[#c565ef]/20">
118 {stepNumber}
119 </div>
120
121 {/* 步骤内容 */}
122 <div className="flex-1 pb-8 md:pb-12">
123 <div className="flex items-center gap-2 mb-3">
124 {icon}
125 <h3 className="text-lg md:text-xl font-semibold">{title}</h3>
126 </div>
127 <div className="space-y-4">{children}</div>
128 </div>
129 </div>
130 </div>
131 )
132 }
133
134 /**
135 * 图片展示组件
136 */
137 interface GuideImageProps {
138 src: PublicImageAsset
139 alt: string
140 caption?: string
141 className?: string
142 onClick?: () => void
143 }
144
145 function GuideImage({ src, alt, caption, className, onClick }: GuideImageProps) {
146 return (
147 <figure className={cn('my-4', className)}>
148 <div
149 className="group relative overflow-hidden rounded-xl border border-border/50 bg-card p-1.5 shadow-sm cursor-pointer transition-all duration-300 hover:shadow-lg hover:ring-2 hover:ring-[#c565ef]/15 hover:-translate-y-0.5"
150 onClick={onClick}
151 >
152 <Image
153 src={src.src}
154 alt={alt}
155 className="w-full h-auto max-h-[500px] object-contain rounded-md"
156 width={src.width}
157 height={src.height}
158 priority={false}
159 quality={100}
160 />
161 {/* 点击放大提示 */}
162 <div className="absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/20 transition-all rounded-md">
163 <div className="opacity-0 scale-90 group-hover:opacity-100 group-hover:scale-100 transition-all bg-white/90 dark:bg-black/80 rounded-full p-2 shadow-lg">
164 <ZoomIn className="w-5 h-5 text-[#c565ef]" />
165 </div>
166 </div>
167 </div>
168 {caption && (
169 <figcaption className="mt-2 text-sm text-muted-foreground text-center">
170 {caption}
171 </figcaption>
172 )}
173 </figure>
174 )
175 }
176
177 /**
178 * 目录导航组件
179 */
180 function TableOfContents({ t }: { t: (key: string) => string }) {
181 const sections = [
182 { id: 'installation', label: t('sections.installation') },
183 { id: 'manual-install', label: t('sections.manualInstall') },
184 { id: 'authorize', label: t('sections.authorize') },
185 { id: 'login-account', label: t('sections.loginAccount') },
186 { id: 'sync-account', label: t('sections.syncAccount') },
187 { id: 'faq', label: t('faq.title') },
188 ]
189
190 return (
191 <Card className="relative h-fit overflow-hidden border-border/50 p-4 shadow-sm">
192 <div className="absolute top-0 left-0 right-0 h-0.5 bg-gradient-to-r from-[#c565ef] to-[#55D9ED]" />
193 <h4 className="font-semibold mb-3 text-sm text-muted-foreground uppercase tracking-wide">
194 {t('tableOfContents')}
195 </h4>
196 <nav className="space-y-1">
197 {sections.map(section => (
198 <a
199 key={section.id}
200 href={`#${section.id}`}
201 className="flex items-center gap-2 px-2 py-1.5 text-sm rounded-md border-l-2 border-transparent hover:border-[#c565ef]/50 hover:bg-gradient-to-r hover:from-[#c565ef]/5 hover:to-transparent transition-all cursor-pointer"
202 >
203 <ChevronRight className="w-3 h-3" />
204 {section.label}
205 </a>
206 ))}
207 </nav>
208 </Card>
209 )
210 }
211
212 export default function PluginGuideContent() {
213 const { t } = useTransClient('pluginGuide')
214 const [previewOpen, setPreviewOpen] = useState(false)
215 const [previewIndex, setPreviewIndex] = useState(0)
216
217 // 打开图片预览
218 const openPreview = useCallback((index: number) => {
219 setPreviewIndex(index)
220 setPreviewOpen(true)
221 }, [])
222
223 // 关闭图片预览
224 const closePreview = useCallback(() => {
225 setPreviewOpen(false)
226 }, [])
227
228 // 将图片转换为 MediaPreview 所需的格式
229 const previewItems = ALL_IMAGES.map((img, index) => ({
230 type: 'image' as const,
231 src: img.src,
232 title: `${t('title')} - ${index + 1}`,
233 }))
234
235 return (
236 <div className="relative min-h-screen bg-background">
237 {/* 装饰光晕 */}
238 <div className="pointer-events-none absolute inset-0 overflow-hidden">
239 <div className="absolute top-[30%] -right-40 w-80 h-80 bg-[#c565ef]/3 rounded-full blur-3xl" />
240 <div className="absolute top-[60%] -left-40 w-80 h-80 bg-[#55D9ED]/3 rounded-full blur-3xl" />
241 </div>
242
243 {/* 图片预览组件 */}
244 <MediaPreview
245 open={previewOpen}
246 items={previewItems}
247 initialIndex={previewIndex}
248 onClose={closePreview}
249 />
250
251 {/* 页头区域 */}
252 <div className="relative overflow-hidden bg-gradient-to-b from-[#c565ef]/5 via-[#55D9ED]/3 to-background">
253 {/* 页头装饰光晕 */}
254 <div className="pointer-events-none absolute -top-20 -left-20 w-60 h-60 bg-[#c565ef]/8 rounded-full blur-3xl" />
255 <div className="pointer-events-none absolute -top-10 -right-20 w-60 h-60 bg-[#55D9ED]/8 rounded-full blur-3xl" />
256 <div className="container mx-auto px-4 py-12 md:py-16">
257 <div className="max-w-3xl mx-auto text-center">
258 <div className="mb-4 inline-flex items-center gap-2 rounded-full border border-[#c565ef]/10 bg-gradient-to-r from-[#c565ef]/5 to-[#55D9ED]/5 px-3 py-1.5 backdrop-blur-sm">
259 <div className="flex h-5 w-5 items-center justify-center rounded-md bg-gradient-to-br from-[#c565ef] to-[#55D9ED]">
260 <Puzzle className="w-3 h-3 text-white" />
261 </div>
262 <span className="text-sm font-medium text-foreground/80">Browser Extension</span>
263 </div>
264 <h1 className="text-3xl md:text-4xl font-bold mb-4">
265 <span className="bg-gradient-to-r from-[#c565ef] to-[#55D9ED] bg-clip-text text-transparent">
266 {t('title')}
267 </span>
268 </h1>
269 <p className="text-lg text-muted-foreground">{t('introduction')}</p>
270 <Alert className="mx-auto mt-6 max-w-2xl border-border/60 bg-background/85 text-left shadow-sm backdrop-blur-sm">
271 <HelpCircle className="h-4 w-4 text-primary" />
272 <div className="min-w-0 flex-1">
273 <AlertTitle>{t('recommendedBrowser.title')}</AlertTitle>
274 <AlertDescription>{t('recommendedBrowser.content')}</AlertDescription>
275 </div>
276 </Alert>
277 </div>
278 </div>
279 {/* 渐变分隔线 */}
280 <div className="h-px bg-gradient-to-r from-transparent via-[#c565ef]/20 to-transparent" />
281 </div>
282
283 {/* 主体内容 */}
284 <div className="container mx-auto px-4 py-8 md:py-12">
285 <div className="flex flex-col lg:flex-row gap-8">
286 {/* 目录 - 桌面端侧边栏 */}
287 <aside className="hidden w-64 shrink-0 self-start lg:sticky lg:top-0 lg:block">
288 <TableOfContents t={t} />
289 </aside>
290
291 {/* 教程内容 */}
292 <main className="flex-1 max-w-4xl">
293 {/* ===== 第一部分:安装插件 ===== */}
294 <section id="installation" className="mb-12">
295 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-primary/5 to-transparent border-l-4 border-primary/40">
296 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-primary/15 to-primary/10 flex items-center justify-center">
297 <Download className="w-5 h-5 text-primary" />
298 </div>
299 <h2 className="text-2xl md:text-3xl font-bold">{t('sections.installation')}</h2>
300 </div>
301
302 <StepCard
303 stepNumber={1}
304 title={t('steps.step1.title')}
305 icon={<Puzzle className="w-5 h-5 text-muted-foreground" />}
306 >
307 <p className="text-muted-foreground">{t('steps.step1.content')}</p>
308 <GuideImage
309 src={pluginGuideImg1}
310 alt={t('steps.step1.caption')}
311 caption={t('steps.step1.caption')}
312 onClick={() => openPreview(0)}
313 />
314 </StepCard>
315
316 <StepCard stepNumber={2} title={t('steps.step2.title')}>
317 <p className="text-muted-foreground">{t('steps.step2.content')}</p>
318 <GuideImage
319 src={pluginGuideImg1_1}
320 alt={t('steps.step2.caption')}
321 caption={t('steps.step2.caption')}
322 onClick={() => openPreview(3)}
323 />
324
325 <Alert className="bg-blue-50 dark:bg-blue-950/30 border-blue-200 dark:border-blue-800">
326 <HelpCircle className="h-4 w-4 text-blue-600" />
327 <div className="min-w-0 flex-1">
328 <AlertTitle className="mb-2 leading-snug text-blue-800 dark:text-blue-300">
329 {t('steps.step2.note')}
330 </AlertTitle>
331 <AlertDescription className="text-blue-700 dark:text-blue-400">
332 <ul className="mt-0 list-disc space-y-3 pl-5">
333 <li>
334 <span className="font-medium">{t('steps.step2.channels.chrome.title')}</span>
335 {t('steps.step2.channels.chrome.content')}
336 </li>
337 <li>
338 <span className="font-medium">{t('steps.step2.channels.github.title')}</span>
339 {t('steps.step2.channels.github.content')}
340 </li>
341 <li>
342 <span className="font-medium">{t('steps.step2.channels.china.title')}</span>
343 {t('steps.step2.channels.china.content')}
344 </li>
345 </ul>
346 <p className="mt-3">
347 {t('steps.step2.updateNote.prefix')}
348 <Link
349 href="/websit/plugin-update-docs"
350 className="mx-1 font-medium text-blue-800 underline underline-offset-4 dark:text-blue-300"
351 >
352 {t('steps.step2.updateNote.linkText')}
353 </Link>
354 {t('steps.step2.updateNote.suffix')}
355 </p>
356 </AlertDescription>
357 </div>
358 </Alert>
359 </StepCard>
360 </section>
361
362 {/* ===== 第二部分:手动安装(可选) ===== */}
363 <section id="manual-install" className="mb-12">
364 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-orange-500/5 to-transparent border-l-4 border-orange-500/40">
365 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-orange-500/15 to-orange-500/10 flex items-center justify-center">
366 <Smartphone className="w-5 h-5 text-orange-500" />
367 </div>
368 <div>
369 <h2 className="text-2xl md:text-3xl font-bold">{t('sections.manualInstall')}</h2>
370 <p className="text-sm text-muted-foreground">{t('sections.manualInstallDesc')}</p>
371 </div>
372 </div>
373
374 <Alert className="mb-6 bg-amber-50 dark:bg-amber-950/30 border-amber-200 dark:border-amber-800">
375 <HelpCircle className="h-4 w-4 text-amber-600" />
376 <div className="min-w-0 flex-1">
377 <AlertTitle className="mb-2 leading-snug text-amber-800 dark:text-amber-300">
378 {t('manualInstall.tip')}
379 </AlertTitle>
380 <AlertDescription className="text-amber-700 dark:text-amber-400">
381 {t('manualInstall.tipPrefix')}
382 <a
383 href="#authorize"
384 className="mx-1 font-medium text-amber-800 underline underline-offset-4 dark:text-amber-300"
385 >
386 {t('manualInstall.tipLinkText')}
387 </a>
388 {t('manualInstall.tipSuffix')}
389 </AlertDescription>
390 </div>
391 </Alert>
392
393 <div className="space-y-6">
394 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
395 <h4 className="font-semibold mb-3 flex items-center gap-2">
396 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
397 1
398 </span>
399 {t('manualInstall.step1.title')}
400 </h4>
401 <p className="text-muted-foreground mb-4">{t('manualInstall.step1.content')}</p>
402 <GuideImage
403 src={pluginGuideImg3}
404 alt={t('manualInstall.step1.title')}
405 onClick={() => openPreview(1)}
406 />
407 </Card>
408
409 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
410 <h4 className="font-semibold mb-3 flex items-center gap-2">
411 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
412 2
413 </span>
414 {t('manualInstall.step2.title')}
415 </h4>
416 <p className="text-muted-foreground mb-4">{t('manualInstall.step2.content')}</p>
417 <GuideImage
418 src={pluginGuideImg4}
419 alt={t('manualInstall.step2.title')}
420 onClick={() => openPreview(2)}
421 />
422 </Card>
423
424 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
425 <h4 className="font-semibold mb-3 flex items-center gap-2">
426 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
427 3
428 </span>
429 {t('manualInstall.step3.title')}
430 </h4>
431 <p className="text-muted-foreground mb-4">{t('manualInstall.step3.content')}</p>
432 <GuideImage
433 src={pluginGuideImg1_2}
434 alt={t('manualInstall.step3.title')}
435 onClick={() => openPreview(4)}
436 />
437 </Card>
438
439 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
440 <h4 className="font-semibold mb-3 flex items-center gap-2">
441 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
442 4
443 </span>
444 {t('manualInstall.step4.title')}
445 </h4>
446 <p className="text-muted-foreground mb-4">{t('manualInstall.step4.content')}</p>
447 <GuideImage
448 src={pluginGuideImg1_3}
449 alt={t('manualInstall.step4.title')}
450 onClick={() => openPreview(5)}
451 />
452 </Card>
453
454 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
455 <h4 className="font-semibold mb-3 flex items-center gap-2">
456 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
457 5
458 </span>
459 {t('manualInstall.step5.title')}
460 </h4>
461 <p className="text-muted-foreground mb-4">{t('manualInstall.step5.content')}</p>
462 <GuideImage
463 src={pluginGuideImg1_4}
464 alt={t('manualInstall.step5.title')}
465 onClick={() => openPreview(6)}
466 />
467 </Card>
468
469 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:border-l-[#c565ef]/60 hover:shadow-md hover:-translate-y-0.5 transition-all duration-200">
470 <h4 className="font-semibold mb-3 flex items-center gap-2">
471 <span className="w-6 h-6 rounded-full bg-gradient-to-br from-[#c565ef]/20 to-[#55D9ED]/20 flex items-center justify-center text-xs font-semibold text-foreground">
472 6
473 </span>
474 {t('manualInstall.step6.title')}
475 </h4>
476 <p className="text-muted-foreground mb-4">{t('manualInstall.step6.content')}</p>
477 <GuideImage
478 src={pluginGuideImg1_5}
479 alt={t('manualInstall.step6.title')}
480 onClick={() => openPreview(7)}
481 />
482 </Card>
483 </div>
484 </section>
485
486 {/* ===== 第三部分:授权插件 ===== */}
487 <section id="authorize" className="mb-12">
488 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-green-500/5 to-transparent border-l-4 border-green-500/40">
489 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-green-500/15 to-green-500/10 flex items-center justify-center">
490 <Shield className="w-5 h-5 text-green-500" />
491 </div>
492 <h2 className="text-2xl md:text-3xl font-bold">{t('sections.authorize')}</h2>
493 </div>
494
495 <StepCard stepNumber={3} title={t('steps.step3.title')}>
496 <p className="text-muted-foreground">{t('steps.step3.content')}</p>
497 <GuideImage
498 src={pluginGuideImg8}
499 alt={t('steps.step3.caption')}
500 caption={t('steps.step3.caption')}
501 onClick={() => openPreview(8)}
502 />
503 </StepCard>
504
505 <StepCard stepNumber={4} title={t('steps.step5.title')}>
506 <p className="text-muted-foreground">{t('steps.step5.notLoggedInContent')}</p>
507 <GuideImage
508 src={pluginGuideImg18}
509 alt={t('steps.step5.notLoggedInCaption')}
510 caption={t('steps.step5.notLoggedInCaption')}
511 onClick={() => openPreview(9)}
512 />
513 <p className="text-muted-foreground">{t('steps.step5.loggedInContent')}</p>
514 <GuideImage
515 src={pluginGuideImg19}
516 alt={t('steps.step5.loggedInCaption')}
517 caption={t('steps.step5.loggedInCaption')}
518 onClick={() => openPreview(10)}
519 />
520 </StepCard>
521
522 <StepCard stepNumber={5} title={t('steps.step6.title')}>
523 <p className="text-muted-foreground">{t('steps.step6.content')}</p>
524 <GuideImage
525 src={pluginGuideImg10}
526 alt={t('steps.step6.caption1')}
527 caption={t('steps.step6.caption1')}
528 onClick={() => openPreview(11)}
529 />
530 <GuideImage
531 src={pluginGuideImg11}
532 alt={t('steps.step6.caption2')}
533 caption={t('steps.step6.caption2')}
534 onClick={() => openPreview(12)}
535 />
536 </StepCard>
537 </section>
538
539 {/* ===== 第四部分:登录账号 ===== */}
540 <section id="login-account" className="mb-12">
541 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-purple-500/5 to-transparent border-l-4 border-purple-500/40">
542 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-purple-500/15 to-purple-500/10 flex items-center justify-center">
543 <Smartphone className="w-5 h-5 text-purple-500" />
544 </div>
545 <h2 className="text-2xl md:text-3xl font-bold">{t('sections.loginAccount')}</h2>
546 </div>
547
548 <StepCard stepNumber={6} title={t('steps.step7.title')}>
549 <p className="text-muted-foreground">{t('steps.step7.loginContent')}</p>
550 <GuideImage
551 src={pluginGuideImg12}
552 alt={t('steps.step7.caption')}
553 caption={t('steps.step7.caption')}
554 onClick={() => openPreview(13)}
555 />
556 </StepCard>
557
558 <StepCard stepNumber={7} title={t('steps.step7b.title')}>
559 <p className="text-muted-foreground">{t('steps.step7b.content')}</p>
560 <GuideImage
561 src={pluginGuideImg13}
562 alt={t('steps.step7b.caption1')}
563 caption={t('steps.step7b.caption1')}
564 onClick={() => openPreview(14)}
565 />
566
567 <Alert className="bg-amber-50 dark:bg-amber-950/30 border-amber-200 dark:border-amber-800">
568 <HelpCircle className="h-4 w-4 text-amber-600" />
569 <div className="min-w-0 flex-1">
570 <AlertTitle className="mb-2 leading-snug text-amber-800 dark:text-amber-300">
571 {t('steps.step7b.importantNote')}
572 </AlertTitle>
573 <AlertDescription className="text-amber-700 dark:text-amber-400">
574 {t('steps.step7b.importantNoteContent')}
575 </AlertDescription>
576 </div>
577 </Alert>
578
579 <GuideImage
580 src={pluginGuideImg14}
581 alt={t('steps.step7b.caption2')}
582 caption={t('steps.step7b.caption2')}
583 onClick={() => openPreview(15)}
584 />
585 </StepCard>
586 </section>
587
588 {/* ===== 第五部分:同步账号 ===== */}
589 <section id="sync-account" className="mb-12">
590 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-blue-500/5 to-transparent border-l-4 border-blue-500/40">
591 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-blue-500/15 to-blue-500/10 flex items-center justify-center">
592 <CheckCircle2 className="w-5 h-5 text-blue-500" />
593 </div>
594 <h2 className="text-2xl md:text-3xl font-bold">{t('sections.syncAccount')}</h2>
595 </div>
596
597 <StepCard stepNumber={8} title={t('steps.step8.title')}>
598 <p className="text-muted-foreground">{t('steps.step8.content')}</p>
599 <GuideImage
600 src={pluginGuideImg15}
601 alt={t('steps.step8.caption')}
602 caption={t('steps.step8.caption')}
603 onClick={() => openPreview(16)}
604 />
605 </StepCard>
606
607 <StepCard stepNumber={9} title={t('steps.step9.title')}>
608 <p className="text-muted-foreground">{t('steps.step9.content')}</p>
609 <GuideImage
610 src={pluginGuideImg16}
611 alt={t('steps.step9.caption1')}
612 caption={t('steps.step9.caption1')}
613 onClick={() => openPreview(17)}
614 />
615 <GuideImage
616 src={pluginGuideImg17}
617 alt={t('steps.step9.caption2')}
618 caption={t('steps.step9.caption2')}
619 onClick={() => openPreview(18)}
620 />
621 </StepCard>
622
623 {/* 完成提示 */}
624 <div className="mt-8 p-6 rounded-2xl bg-gradient-to-r from-[#c565ef]/8 to-[#55D9ED]/8 border border-[#c565ef]/15 shadow-sm">
625 <div className="flex items-start gap-4">
626 <div className="w-12 h-12 rounded-full bg-gradient-to-br from-[#c565ef] to-[#55D9ED] flex items-center justify-center shrink-0 shadow-md shadow-[#c565ef]/20">
627 <CheckCircle2 className="w-6 h-6 text-white" />
628 </div>
629 <div>
630 <h3 className="text-xl font-bold text-foreground mb-2">
631 {t('steps.complete.title')}
632 </h3>
633 <p className="text-muted-foreground">
634 {t('steps.complete.content')}
635 </p>
636 </div>
637 </div>
638 </div>
639 </section>
640
641 {/* ===== FAQ 部分 ===== */}
642 <section id="faq" className="mb-12">
643 <div className="flex items-center gap-3 mb-6 p-4 rounded-xl bg-gradient-to-r from-violet-500/5 to-transparent border-l-4 border-violet-500/40">
644 <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-violet-500/15 to-violet-500/10 flex items-center justify-center">
645 <HelpCircle className="w-5 h-5 text-violet-500" />
646 </div>
647 <h2 className="text-2xl md:text-3xl font-bold">{t('faq.title')}</h2>
648 </div>
649
650 <div className="space-y-4">
651 <Card className="p-6 border-l-4 border-l-[#c565ef]/30 hover:shadow-md transition-shadow">
652 <h4 className="font-semibold mb-2 flex items-start gap-2">
653 <span className="bg-gradient-to-r from-[#c565ef] to-[#55D9ED] bg-clip-text text-transparent font-bold">Q:</span>
654 {t('faq.q1.question')}
655 </h4>
656 <p className="text-muted-foreground pl-6">
657 <span className="bg-gradient-to-r from-[#55D9ED] to-[#c565ef] bg-clip-text text-transparent font-semibold">A: </span>
658 {t('faq.q1.answer')}
659 </p>
660 </Card>
661 </div>
662 </section>
663 </main>
664 </div>
665 </div>
666 </div>
667 )
668 }
669
669 lines Plain Text