Step3.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import { useState } from 'react';
  2. import { useNavigate } from 'react-router-dom';
  3. import { useTranslation } from 'react-i18next';
  4. import {
  5. Terminal,
  6. Cpu,
  7. Zap,
  8. Code,
  9. Server,
  10. ArrowRight,
  11. CheckCircle,
  12. Copy
  13. } from 'lucide-react';
  14. import SharedHeader from '../components/SharedHeader';
  15. import './step3.css';
  16. import StepProgress from '../components/StepProgress';
  17. import { useGlobalSettings } from '../hooks/useGlobalSettings';
  18. import { useEmailSubmission } from '../hooks/useEmailSubmission';
  19. const Step3 = () => {
  20. const { t } = useTranslation();
  21. // 使用统一的全局状态管理
  22. const { isDark, currentLang, toggleTheme, toggleLang } = useGlobalSettings();
  23. const navigate = useNavigate();
  24. // Code Snippet State
  25. const [copied, setCopied] = useState(false);
  26. const codeSnippet = `curl https://api.ccdw.xyz/v1/chat/completions \\
  27. -H "Content-Type: application/json" \\
  28. -H "Authorization: Bearer YOUR_API_KEY" \\
  29. -d '{
  30. "model": "gpt-4-turbo",
  31. "messages": [{"role": "user", "content": "Hello!"}]
  32. }'`;
  33. const handleCopy = () => {
  34. navigator.clipboard.writeText(codeSnippet);
  35. setCopied(true);
  36. setTimeout(() => setCopied(false), 2000);
  37. };
  38. // Theme-based classes
  39. const theme = {
  40. bg: isDark ? 'bg-[#0a0a0a]' : 'bg-white',
  41. bgSecondary: isDark ? 'bg-[#111]' : 'bg-stone-50',
  42. bgTertiary: isDark ? 'bg-[#0d0d0d]' : 'bg-stone-100',
  43. text: isDark ? 'text-white' : 'text-stone-900',
  44. textMuted: isDark ? 'text-gray-400' : 'text-stone-600',
  45. textLight: isDark ? 'text-gray-600' : 'text-stone-400',
  46. border: isDark ? 'border-[#222]' : 'border-stone-200',
  47. borderLight: isDark ? 'border-[#333]' : 'border-stone-300',
  48. accent: 'text-[#00f0ff]',
  49. accentBg: isDark ? 'bg-[#00f0ff]/10' : 'bg-cyan-50',
  50. cardBg: isDark ? 'bg-[#111]' : 'bg-white',
  51. cardBorder: isDark ? 'border-[#333]' : 'border-stone-200',
  52. inputBg: isDark ? 'bg-[#1a1a1a]' : 'bg-white',
  53. codeHeaderBg: isDark ? 'bg-[#1a1a1a]' : 'bg-stone-100',
  54. selection: isDark ? 'selection:bg-[#00f0ff] selection:text-black' : 'selection:bg-cyan-200 selection:text-cyan-900',
  55. };
  56. // Email Submission Logic - 使用统一的 hook
  57. const [email, setEmail] = useState('');
  58. const { submitEmail, status, message } = useEmailSubmission();
  59. const handleEmailSubmit = async () => {
  60. if (!email) return;
  61. const result = await submitEmail({
  62. email,
  63. source: 'Step3_Developer'
  64. });
  65. if (result.success) {
  66. setEmail('');
  67. }
  68. };
  69. return (
  70. <div className={`step3-page min-h-screen ${theme.bg} ${theme.text} ${theme.selection} font-sans transition-colors duration-300`}>
  71. <SharedHeader
  72. theme={isDark ? 'dark' : 'light'}
  73. onThemeToggle={toggleTheme}
  74. onLangToggle={toggleLang}
  75. currentLang={currentLang}
  76. />
  77. {/* Progress Indicator */}
  78. <div className={`pt-24 pb-8 max-w-5xl mx-auto px-6 ${theme.bg}`}>
  79. <StepProgress currentStep={3} theme={isDark ? 'dark' : 'light'} />
  80. </div>
  81. {/* Hero Section */}
  82. <section className={`relative pt-10 pb-32 px-6 border-b ${theme.border} overflow-hidden`}>
  83. {/* Background Grid */}
  84. <div className={`absolute inset-0 ${isDark ? 'bg-grid-cyan opacity-20' : 'bg-grid-cyan-light opacity-10'} pointer-events-none`}></div>
  85. <div className={`absolute top-0 left-0 w-full h-full ${isDark ? 'bg-gradient-to-b from-[#0a0a0a] via-transparent to-[#0a0a0a]' : 'bg-gradient-to-b from-white via-transparent to-white'} pointer-events-none`}></div>
  86. <div className="max-w-5xl mx-auto relative z-10 text-center">
  87. <div className={`inline-block px-3 py-1 mb-8 border ${theme.borderLight} rounded-full ${theme.bgSecondary} ${theme.accent} text-xs font-mono tracking-widest uppercase`}>
  88. {t('step3.label')}
  89. </div>
  90. <h1 className="text-5xl md:text-8xl font-black mb-8 leading-none tracking-tight">
  91. {t('step3.hero_title')}<br />
  92. <span className="text-transparent bg-clip-text bg-gradient-to-r from-[#00f0ff] to-[#00aaff]">
  93. {t('step3.hero_title_highlight')}
  94. </span>
  95. </h1>
  96. <p className={`max-w-2xl mx-auto text-lg md:text-xl ${theme.textMuted} mb-12 leading-relaxed`}>
  97. {t('step3.hero_desc')} <span className={`${theme.text} border-b border-[#00f0ff]`}>{t('step3.hero_desc_highlight')}</span>
  98. <br className="hidden md:block" />
  99. {t('step3.hero_subtitle')}
  100. </p>
  101. <div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
  102. <button className="px-8 py-4 bg-[#00f0ff] text-black font-bold text-lg rounded hover:bg-[#00ccee] transition-colors flex items-center gap-2 group">
  103. <Terminal className="w-5 h-5" />
  104. {t('step3.btn_get_key')}
  105. <ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
  106. </button>
  107. <button className={`px-8 py-4 border ${theme.borderLight} hover:border-[#00f0ff] ${theme.textMuted} hover:${theme.text} rounded transition-colors font-mono`}>
  108. {t('step3.btn_pricing')}
  109. </button>
  110. </div>
  111. </div>
  112. </section>
  113. {/* Services Grid */}
  114. <section className={`py-24 px-6 ${theme.bg}`}>
  115. <div className="max-w-6xl mx-auto">
  116. <div className="grid md:grid-cols-3 gap-8">
  117. {/* Token Relay */}
  118. <div className={`s3-card p-8 rounded-xl ${theme.cardBg} border ${theme.cardBorder} group`}>
  119. <div className={`w-12 h-12 ${theme.accentBg} rounded flex items-center justify-center mb-6 group-hover:scale-110 transition-transform`}>
  120. <Zap className="w-6 h-6 text-[#00f0ff]" />
  121. </div>
  122. <h3 className="text-2xl font-bold mb-4">{t('step3.services.token.title')}</h3>
  123. <p className={`${theme.textMuted} mb-6 leading-relaxed`}>
  124. {t('step3.services.token.desc')}
  125. </p>
  126. <div className="text-xs font-mono text-[#00f0ff] uppercase tracking-wider">
  127. {t('step3.services.token.highlight')}
  128. </div>
  129. </div>
  130. {/* Elastic Compute */}
  131. <div className={`s3-card p-8 rounded-xl ${theme.cardBg} border ${theme.cardBorder} group`}>
  132. <div className={`w-12 h-12 ${theme.accentBg} rounded flex items-center justify-center mb-6 group-hover:scale-110 transition-transform`}>
  133. <Cpu className="w-6 h-6 text-[#00f0ff]" />
  134. </div>
  135. <h3 className="text-2xl font-bold mb-4">{t('step3.services.compute.title')}</h3>
  136. <p className={`${theme.textMuted} mb-6 leading-relaxed`}>
  137. {t('step3.services.compute.desc')}
  138. </p>
  139. <div className="text-xs font-mono text-[#00f0ff] uppercase tracking-wider">
  140. {t('step3.services.compute.highlight')}
  141. </div>
  142. </div>
  143. {/* SaaS Kit */}
  144. <div className={`s3-card p-8 rounded-xl ${theme.cardBg} border ${theme.cardBorder} group`}>
  145. <div className={`w-12 h-12 ${theme.accentBg} rounded flex items-center justify-center mb-6 group-hover:scale-110 transition-transform`}>
  146. <Server className="w-6 h-6 text-[#00f0ff]" />
  147. </div>
  148. <h3 className="text-2xl font-bold mb-4">{t('step3.services.saas.title')}</h3>
  149. <p className={`${theme.textMuted} mb-6 leading-relaxed`}>
  150. {t('step3.services.saas.desc')}
  151. </p>
  152. <div className="text-xs font-mono text-[#00f0ff] uppercase tracking-wider">
  153. {t('step3.services.saas.highlight')}
  154. </div>
  155. </div>
  156. </div>
  157. </div>
  158. </section>
  159. {/* Code & Integration */}
  160. <section className={`py-24 px-6 border-y ${theme.border} ${theme.bgTertiary}`}>
  161. <div className="max-w-6xl mx-auto flex flex-col md:flex-row items-center gap-16">
  162. <div className="md:w-1/2">
  163. <div className="flex items-center gap-3 mb-6">
  164. <Code className="w-6 h-6 text-[#00f0ff]" />
  165. <h2 className="text-3xl font-bold">{t('step3.code_title')}</h2>
  166. </div>
  167. <div className="space-y-6">
  168. {(t('step3.features', { returnObjects: true }) as any[]).map((feature: any, idx: number) => (
  169. <div key={idx} className="flex gap-4">
  170. <div className="mt-1">
  171. <CheckCircle className="w-5 h-5 text-[#00f0ff]" />
  172. </div>
  173. <div>
  174. <h4 className={`font-bold ${theme.text} mb-1`}>{feature.title}</h4>
  175. <p className={`text-sm ${theme.textMuted}`}>{feature.desc}</p>
  176. </div>
  177. </div>
  178. ))}
  179. </div>
  180. </div>
  181. <div className="md:w-1/2 w-full">
  182. <div className={`code-window border ${theme.cardBorder} rounded-lg overflow-hidden shadow-xl`}>
  183. <div className={`code-header ${theme.codeHeaderBg} border-b ${theme.cardBorder}`}>
  184. <div className="dot red"></div>
  185. <div className="dot yellow"></div>
  186. <div className="dot green"></div>
  187. <div className={`ml-auto text-xs ${theme.textLight} font-mono`}>bash</div>
  188. </div>
  189. <div className={`p-6 overflow-x-auto relative group ${isDark ? 'bg-black' : 'bg-stone-900'}`}>
  190. <pre className="font-mono text-sm leading-relaxed text-[#00f0ff]">
  191. {codeSnippet}
  192. </pre>
  193. <button
  194. onClick={handleCopy}
  195. className="absolute top-4 right-4 p-2 bg-[#333] hover:bg-[#444] rounded text-white opacity-0 group-hover:opacity-100 transition-opacity"
  196. >
  197. {copied ? <CheckCircle className="w-4 h-4 text-green-400" /> : <Copy className="w-4 h-4" />}
  198. </button>
  199. </div>
  200. </div>
  201. </div>
  202. </div>
  203. </section>
  204. {/* CTA / Footer */}
  205. <footer className={`py-32 px-6 text-center ${theme.bg}`}>
  206. <div className="max-w-2xl mx-auto">
  207. <h2 className="text-4xl font-bold mb-6">{t('step3.cta_title')}</h2>
  208. <p className={`${theme.textMuted} mb-10 text-lg`}>
  209. {t('step3.cta_desc')}
  210. </p>
  211. <div className="flex flex-col sm:flex-row max-w-md mx-auto gap-4">
  212. <input
  213. type="email"
  214. value={email}
  215. onChange={(e) => setEmail(e.target.value)}
  216. disabled={status === 'loading' || status === 'success'}
  217. placeholder={t('step3.cta_input_placeholder')}
  218. className={`flex-1 ${theme.inputBg} border ${theme.borderLight} rounded px-4 py-3 ${theme.text} focus:outline-none focus:border-[#00f0ff] transition-colors disabled:opacity-50`}
  219. />
  220. <button
  221. onClick={handleEmailSubmit}
  222. disabled={status === 'loading' || status === 'success'}
  223. className="px-6 py-3 bg-[#00f0ff] text-black font-bold rounded hover:bg-[#00ccee] transition-colors whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed"
  224. >
  225. {status === 'loading' ? (currentLang === 'zh' ? '发送中...' : 'Sending...') : t('step3.cta_btn')}
  226. </button>
  227. </div>
  228. {/* Status Message */}
  229. {message && (
  230. <div className={`mt-4 text-sm font-medium ${status === 'success' ? 'text-green-500' : 'text-red-500'}`}>
  231. {message}
  232. </div>
  233. )}
  234. {/* Navigation buttons */}
  235. <div className="flex justify-center gap-4 mb-12">
  236. <button
  237. onClick={() => navigate('/step2')}
  238. className={`px-6 py-3 border ${theme.borderLight} hover:border-[#00f0ff] ${theme.textMuted} hover:text-[#00f0ff] rounded transition-colors font-mono`}
  239. >
  240. {t('step3.nav_prev')}
  241. </button>
  242. <button
  243. onClick={() => navigate('/')}
  244. className={`px-6 py-3 border ${theme.borderLight} hover:border-[#00f0ff] ${theme.textMuted} hover:text-[#00f0ff] rounded transition-colors font-mono`}
  245. >
  246. {t('step3.nav_home')}
  247. </button>
  248. </div>
  249. <div className={`pt-8 border-t ${theme.border} text-sm ${theme.textLight} font-mono`}>
  250. {t('step3.footer_rights')}
  251. </div>
  252. </div>
  253. </footer>
  254. </div>
  255. );
  256. };
  257. export default Step3;