feat(ui): optimize CTA buttons with contextual copy and fix static export build issues

CTA Optimization:

- Implement scenario-based CTA text across 6 key locations

- Add responsive Header CTA with icon+compact design

- Enhance CTA Section with vision-driven copy

Bug Fixes:

- Fix useSearchParams() build failure with dynamic import wrapper

- Remove useSearchParams() from PageTransition component

- Fix React 19 useEffect lint errors via useSyncExternalStore

UI Enhancements:

- Add ripple effects and gradient animations to Button

- Enhance loading skeleton with branded pulse animation
This commit is contained in:
张翔
2026-05-11 19:03:37 +08:00
parent c474394237
commit f08874f5c4
20 changed files with 794 additions and 112 deletions
+48
View File
@@ -0,0 +1,48 @@
'use client';
import { motion, AnimatePresence } from 'framer-motion';
import { usePathname } from 'next/navigation';
import { ReactNode, useSyncExternalStore } from 'react';
import { useReducedMotion } from '@/hooks/use-reduced-motion';
interface PageTransitionProps {
children: ReactNode;
}
function useIsMounted() {
return useSyncExternalStore(
(callback) => {
window.addEventListener('resize', callback);
return () => window.removeEventListener('resize', callback);
},
() => true,
() => false
);
}
export function PageTransition({ children }: PageTransitionProps) {
const pathname = usePathname();
const shouldReduceMotion = useReducedMotion();
const mounted = useIsMounted();
if (shouldReduceMotion || !mounted) {
return <>{children}</>;
}
return (
<AnimatePresence mode="wait">
<motion.div
key={pathname}
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -8 }}
transition={{
duration: 0.3,
ease: [0.16, 1, 0.3, 1],
}}
>
{children}
</motion.div>
</AnimatePresence>
);
}