6de1b3f6b2
用户要 agent.sundynix.cn/ 打开是营销官网、/admin 是后台,且只用一个前端。 把 sundynix-site/web 的营销落地页融进 sundynix-admin 这一个 Vite 工程(不挂两份 embed): - 拷官网到 src/site/:home(hero/功能/架构/快速上手/下载)+layout(header/footer) +terminal-demo/logo/reveal 等 + content/site.ts(文案本就是本产品)。去掉博客/posts/埋点/RSS (营销 only,零后端改动);use-release 改纯静态版本号。public/ 加 brand logo+favicon。 - Tailwind v4→v3 对齐:site 的 ink/ground/accent/term 等 token 加进 tailwind.config(var 引用) + :root/.dark 变量+keyframes 进 index.css;bg-ground/85 用 color-mix 还原。admin 自身用默认 gray/violet 调色板,不冲突;landing 的 bg-ground 只作用在 SiteLayout 容器、不改 body。 - 路由重构:App.tsx 换 BrowserRouter —— / 官网(公开)、/admin/* 后台(AdminGate 内做 me/Login/AppShell)。 routes.tsx path 改相对、AppShell 链接加 /admin 前缀。@ 别名指向 src/site。 - gateway/Dockerfile/nginx 零改动:单份 dist 挂根 + NoRoute SPA 兜底已支持 BrowserRouter 深链。 验证:tsc + vite build(Tailwind 编译过)+ vitest 41 过;gateway 二进制冒烟打真 serve—— / 返回官网 index.html、/admin 与 /admin/tasks SPA 兜底 200、/brand/*.webp 200、/api/v1 走 API 401; dist 里确认落地页文案已进 bundle。(注:MCP 浏览器当前断开,视觉渲染待部署后线上看。) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
interface RevealProps {
|
|
children: ReactNode
|
|
className?: string
|
|
/** 进场延迟(毫秒),用于同屏元素错峰 */
|
|
delay?: number
|
|
}
|
|
|
|
/** 滚动进场:进入视口后淡入上移一次;prefers-reduced-motion 时直接显示 */
|
|
export function Reveal({ children, className, delay = 0 }: RevealProps) {
|
|
const ref = useRef<HTMLDivElement>(null)
|
|
const [visible, setVisible] = useState(false)
|
|
|
|
useEffect(() => {
|
|
const el = ref.current
|
|
if (!el) return
|
|
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
setVisible(true)
|
|
return
|
|
}
|
|
const io = new IntersectionObserver(
|
|
([entry]) => {
|
|
if (entry.isIntersecting) {
|
|
setVisible(true)
|
|
io.disconnect()
|
|
}
|
|
},
|
|
{ threshold: 0.15, rootMargin: '0px 0px -40px 0px' },
|
|
)
|
|
io.observe(el)
|
|
return () => io.disconnect()
|
|
}, [])
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
style={delay ? { transitionDelay: `${delay}ms` } : undefined}
|
|
className={cn('reveal', visible && 'reveal-in', className)}
|
|
>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|