¶Ô±ÈÐÂÎļþ |
| | |
| | | "use client"; |
| | | |
| | | import { useState, useEffect } from 'react'; |
| | | import Image from 'next/image'; |
| | | import { motion } from 'framer-motion'; |
| | | import Link from 'next/link'; |
| | | |
| | | export default function RegisterPage() { |
| | | const [username, setUsername] = useState(''); |
| | | const [password, setPassword] = useState(''); |
| | | const [confirmPassword, setConfirmPassword] = useState(''); |
| | | const [phone, setPhone] = useState(''); |
| | | const [verifyCode, setVerifyCode] = useState(''); |
| | | const [isLoading, setIsLoading] = useState(false); |
| | | const [mounted, setMounted] = useState(false); |
| | | const [countdown, setCountdown] = useState(0); |
| | | |
| | | // å计æ¶é»è¾ |
| | | useEffect(() => { |
| | | if (countdown > 0) { |
| | | const timer = setTimeout(() => setCountdown(countdown - 1), 1000); |
| | | return () => clearTimeout(timer); |
| | | } |
| | | }, [countdown]); |
| | | |
| | | // ç¡®ä¿ç»ä»¶æè½½ååæ¾ç¤ºå¨ç»ææ |
| | | useEffect(() => { |
| | | // ä½¿ç¨ requestAnimationFrame ç¡®ä¿å¨ä¸ä¸å¸§æ§è¡ï¼æé«å¨ç»æµç
度 |
| | | const animationFrame = requestAnimationFrame(() => { |
| | | setMounted(true); |
| | | }); |
| | | |
| | | return () => cancelAnimationFrame(animationFrame); |
| | | }, []); |
| | | |
| | | const sendVerifyCode = () => { |
| | | if (countdown > 0 || !phone || phone.length !== 11) return; |
| | | |
| | | // 模æåééªè¯ç |
| | | setCountdown(60); |
| | | // è¿éåºè¯¥æ·»å å®é
åééªè¯ç çé»è¾ |
| | | }; |
| | | |
| | | const handleSubmit = (e: React.FormEvent) => { |
| | | e.preventDefault(); |
| | | |
| | | // 表åéªè¯ |
| | | if (!username || !password || !confirmPassword || !phone || !verifyCode) { |
| | | alert("è¯·å¡«åææå¿
å¡«åæ®µ"); |
| | | return; |
| | | } |
| | | |
| | | if (password !== confirmPassword) { |
| | | alert("两次è¾å
¥çå¯ç ä¸ä¸è´"); |
| | | return; |
| | | } |
| | | |
| | | setIsLoading(true); |
| | | |
| | | // æ¨¡ææ³¨åè¯·æ± |
| | | setTimeout(() => { |
| | | setIsLoading(false); |
| | | // è¿éåºè¯¥æ·»å å®é
注åé»è¾ |
| | | alert("注åæåï¼å³å°è·³è½¬å°ç»å½é¡µ"); |
| | | // 注åæåå跳转å°ç»å½é¡µ |
| | | window.location.href = "/login"; |
| | | }, 2000); |
| | | }; |
| | | |
| | | return ( |
| | | <div className="h-screen w-full flex items-center justify-center relative overflow-hidden"> |
| | | {/* èæ¯ææ */} |
| | | <div className="fixed inset-0 bg-gradient-to-br from-[#0A1033] via-[#1E2B63] to-[#131C41] z-0"></div> |
| | | |
| | | {/* ç¥ç»ç½ç»çº¿æ¡èæ¯ */} |
| | | <div className="fixed inset-0 z-0 opacity-30"> |
| | | <div className="absolute top-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/70 to-transparent"></div> |
| | | <div className="absolute bottom-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/70 to-transparent"></div> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[1px] bg-gradient-to-b from-transparent via-[#6ADBFF]/70 to-transparent"></div> |
| | | <div className="absolute top-0 bottom-0 right-0 w-[1px] bg-gradient-to-b from-transparent via-[#6ADBFF]/70 to-transparent"></div> |
| | | |
| | | {/* ç¥ç»ç½ç»è¿æ¥ç¹ */} |
| | | <div className="absolute top-[20%] left-[15%] w-1.5 h-1.5 rounded-full bg-[#6ADBFF]/80 animate-pulse"></div> |
| | | <div className="absolute top-[60%] left-[75%] w-1.5 h-1.5 rounded-full bg-[#6ADBFF]/80 animate-pulse" style={{ animationDelay: '1.5s' }}></div> |
| | | |
| | | {/* è¿æ¥çº¿ */} |
| | | <div className="absolute top-[20%] left-[15%] w-[70%] h-[1px] bg-gradient-to-r from-[#6ADBFF]/80 to-transparent animate-pulse"></div> |
| | | |
| | | {/* æ°æ®ç¹èæ¯ */} |
| | | <div className="absolute inset-0" style={{ |
| | | backgroundImage: 'radial-gradient(circle, rgba(106, 219, 255, 0.15) 1px, transparent 1px)', |
| | | backgroundSize: '20px 20px' |
| | | }}></div> |
| | | |
| | | {/* æ«æçº¿ */} |
| | | <div className="absolute inset-0"> |
| | | <div className="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-transparent via-[#6ADBFF]/5 to-transparent animate-scanline" style={{ animationDuration: '12s' }}></div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* 注åå¡ç */} |
| | | <motion.div |
| | | initial={{ opacity: 0, y: 20 }} |
| | | animate={{ opacity: mounted ? 1 : 0, y: mounted ? 0 : 20 }} |
| | | transition={{ |
| | | duration: 0.5, |
| | | ease: [0.25, 0.1, 0.25, 1], |
| | | staggerChildren: 0.1 |
| | | }} |
| | | className="relative z-10 w-full max-w-3xl flex rounded-2xl backdrop-blur-lg bg-[#1E2B63]/40 border border-[#6ADBFF]/20 shadow-xl overflow-hidden gpu-accelerated" |
| | | > |
| | | {/* å¡çå
é¨è£
饰 */} |
| | | <div className="absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/50 to-transparent"></div> |
| | | <div className="absolute top-0 bottom-0 right-0 w-[1px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent"></div> |
| | | <div className="absolute bottom-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/50 to-transparent"></div> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[1px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent"></div> |
| | | |
| | | {/* 左侧Logoåå
¬å¸å */} |
| | | <div className="w-2/5 bg-[#131C41]/60 p-8 flex flex-col items-center justify-between"> |
| | | {/* Logoåå
¬å¸åé¨å */} |
| | | <div className="w-full flex flex-col items-center justify-start"> |
| | | <div className="mb-4 relative overflow-visible"> |
| | | <Link href="/" className="group flex items-center relative"> |
| | | <div className="relative w-16 h-16 transition-all duration-500 overflow-visible" style={{ isolation: 'isolate' }}> |
| | | {/* åºç¡èæ¯å */} |
| | | <div className="absolute inset-0 rounded-full bg-[#131C41] z-10"></div> |
| | | |
| | | {/* Logoèæ¯å
ç¯ */} |
| | | <div className="absolute inset-0 rounded-full border-2 border-[#6ADBFF]/70 animate-logo-pulse z-10"></div> |
| | | |
| | | {/* åºå±å
æææ */} |
| | | <div className="absolute -inset-2 rounded-full bg-[#6ADBFF]/10 blur-lg animate-pulse z-0"></div> |
| | | |
| | | {/* Logo */} |
| | | <Image |
| | | src="/images/logo.jpg" |
| | | alt="帷å¹åæLogo" |
| | | width={64} |
| | | height={64} |
| | | className="rounded-full object-cover relative z-30" |
| | | style={{ display: 'block', objectFit: 'cover', width: '100%', height: '100%' }} |
| | | priority |
| | | /> |
| | | |
| | | {/* æ¬åç¹æå®¹å¨ */} |
| | | <div className="absolute inset-0 rounded-full z-20 overflow-hidden pointer-events-none"> |
| | | {/* æ¬åæ¶çæ«æçº¿ */} |
| | | <div className="absolute inset-0 rounded-full overflow-hidden opacity-0 group-hover:opacity-100 transition-opacity duration-500"> |
| | | <div className="absolute top-0 -left-[100%] right-0 h-[2px] group-hover:left-full w-full bg-gradient-to-r from-transparent via-[#6ADBFF] to-transparent transition-all duration-1500 ease-in-out"></div> |
| | | <div className="absolute bottom-0 left-full right-0 h-[2px] group-hover:left-[-100%] w-full bg-gradient-to-r from-transparent via-[#6ADBFF] to-transparent transition-all duration-1500 ease-in-out delay-200"></div> |
| | | </div> |
| | | |
| | | {/* æ¬åæ¶çéåæ°æ®æµææ */} |
| | | <div className="absolute inset-0 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-500"> |
| | | <div className="w-[1px] h-0 group-hover:h-full bg-gradient-to-b from-transparent via-[#6ADBFF]/70 to-transparent transition-all duration-700 delay-300"></div> |
| | | <div className="h-[1px] w-0 group-hover:w-full bg-gradient-to-r from-transparent via-[#6ADBFF]/70 to-transparent transition-all duration-700 delay-400"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div className="ml-4 relative z-0 transition-transform duration-500"> |
| | | <h1 className="text-2xl font-bold text-white mb-1 relative inline-block group-hover:text-[#6ADBFF] transition-colors duration-500"> |
| | | 帷å¹åæ |
| | | <span className="absolute -bottom-1 left-0 w-full h-[2px] bg-gradient-to-r from-[#FF6A88] to-[#6ADBFF] group-hover:animate-pulse"></span> |
| | | </h1> |
| | | |
| | | <p className="text-[#6ADBFF]/80 text-xs group-hover:text-[#6ADBFF] transition-colors duration-500">AIåºæ¯æ¨¡æå¹³å° · æºæ
§èµè½æªæ¥</p> |
| | | </div> |
| | | </Link> |
| | | </div> |
| | | |
| | | {/* åé线 */} |
| | | <div className="w-full border-t border-[#6ADBFF]/20 my-3"></div> |
| | | </div> |
| | | |
| | | {/* 左侧信æ¯å
容 */} |
| | | <div className="w-full flex-1 flex flex-col justify-center space-y-6"> |
| | | <div className="text-center"> |
| | | <h2 className="text-lg font-semibold text-[#6ADBFF] mb-2">å·²æè´¦å·?</h2> |
| | | <Link href="/login" className="text-white hover:text-[#6ADBFF] transition-colors duration-300 px-6 py-2 border border-[#6ADBFF]/30 rounded-full inline-block relative group"> |
| | | <span className="relative z-10">ç«å³ç»å½</span> |
| | | <div className="absolute inset-0 rounded-full opacity-0 group-hover:opacity-100 bg-gradient-to-r from-[#6ADBFF]/10 to-[#5E72EB]/10 transition-opacity duration-300"></div> |
| | | <div className="absolute top-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/30 to-transparent"></div> |
| | | <div className="absolute bottom-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/30 to-transparent"></div> |
| | | </Link> |
| | | </div> |
| | | |
| | | <div className="text-white/70 text-sm space-y-3"> |
| | | <div className="flex items-center"> |
| | | <div className="w-2 h-2 rounded-full bg-[#6ADBFF]/50 mr-2"></div> |
| | | <p>éè¿æ³¨åè·å宿´å¹³å°åè½</p> |
| | | </div> |
| | | <div className="flex items-center"> |
| | | <div className="w-2 h-2 rounded-full bg-[#6ADBFF]/50 mr-2"></div> |
| | | <p>享åAIæºè½åæä¸åºæ¯æ¨¡æ</p> |
| | | </div> |
| | | <div className="flex items-center"> |
| | | <div className="w-2 h-2 rounded-full bg-[#6ADBFF]/50 mr-2"></div> |
| | | <p>å®å
¨å¯é çæ°æ®ä¿éæºå¶</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* 左侧è£
é¥°ç¹ */} |
| | | <div className="absolute bottom-4 left-4"> |
| | | <div className="relative w-2 h-2"> |
| | | <div className="absolute inset-0 rounded-full bg-[#6ADBFF]/30 animate-pulse"></div> |
| | | <div className="absolute inset-[2px] rounded-full bg-[#6ADBFF]/50"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* å³ä¾§æ³¨å表å */} |
| | | <div className="w-3/5 p-8"> |
| | | <div className="mb-6"> |
| | | <h2 className="text-xl font-semibold text-white mb-2">æ°ç¨æ·æ³¨å</h2> |
| | | <p className="text-[#6ADBFF]/80 text-sm">欢è¿å å
¥å¸·å¹åæï¼è¯·å¡«å以ä¸ä¿¡æ¯å®ææ³¨å</p> |
| | | </div> |
| | | |
| | | {/* 注å表å */} |
| | | <form onSubmit={handleSubmit} className="space-y-4"> |
| | | {/* ç¨æ·å */} |
| | | <div className="space-y-1"> |
| | | <label className="block text-xs text-[#6ADBFF]/80 mb-1">ç¨æ·å</label> |
| | | <div className="relative group"> |
| | | <input |
| | | type="text" |
| | | value={username} |
| | | onChange={(e) => setUsername(e.target.value)} |
| | | className="w-full px-4 py-2 bg-[#131C41]/70 border border-[#6ADBFF]/30 rounded-lg text-white focus:outline-none focus:border-[#6ADBFF]/70 transition-all" |
| | | required |
| | | /> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[2px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* å¯ç */} |
| | | <div className="space-y-1"> |
| | | <label className="block text-xs text-[#6ADBFF]/80 mb-1">å¯ç </label> |
| | | <div className="relative group"> |
| | | <input |
| | | type="password" |
| | | value={password} |
| | | onChange={(e) => setPassword(e.target.value)} |
| | | className="w-full px-4 py-2 bg-[#131C41]/70 border border-[#6ADBFF]/30 rounded-lg text-white focus:outline-none focus:border-[#6ADBFF]/70 transition-all" |
| | | required |
| | | /> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[2px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* 确认å¯ç */} |
| | | <div className="space-y-1"> |
| | | <label className="block text-xs text-[#6ADBFF]/80 mb-1">确认å¯ç </label> |
| | | <div className="relative group"> |
| | | <input |
| | | type="password" |
| | | value={confirmPassword} |
| | | onChange={(e) => setConfirmPassword(e.target.value)} |
| | | className="w-full px-4 py-2 bg-[#131C41]/70 border border-[#6ADBFF]/30 rounded-lg text-white focus:outline-none focus:border-[#6ADBFF]/70 transition-all" |
| | | required |
| | | /> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[2px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* ææºå·ç */} |
| | | <div className="space-y-1"> |
| | | <label className="block text-xs text-[#6ADBFF]/80 mb-1">ææºå·ç </label> |
| | | <div className="relative group"> |
| | | <input |
| | | type="tel" |
| | | value={phone} |
| | | onChange={(e) => setPhone(e.target.value)} |
| | | className="w-full px-4 py-2 bg-[#131C41]/70 border border-[#6ADBFF]/30 rounded-lg text-white focus:outline-none focus:border-[#6ADBFF]/70 transition-all" |
| | | pattern="[0-9]{11}" |
| | | required |
| | | /> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[2px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* éªè¯ç */} |
| | | <div className="space-y-1"> |
| | | <label className="block text-xs text-[#6ADBFF]/80 mb-1">éªè¯ç </label> |
| | | <div className="flex space-x-2"> |
| | | <div className="relative group flex-1"> |
| | | <input |
| | | type="text" |
| | | value={verifyCode} |
| | | onChange={(e) => setVerifyCode(e.target.value)} |
| | | className="w-full px-4 py-2 bg-[#131C41]/70 border border-[#6ADBFF]/30 rounded-lg text-white focus:outline-none focus:border-[#6ADBFF]/70 transition-all" |
| | | required |
| | | /> |
| | | <div className="absolute top-0 bottom-0 left-0 w-[2px] bg-gradient-to-b from-transparent via-[#6ADBFF]/50 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div> |
| | | </div> |
| | | <button |
| | | type="button" |
| | | onClick={sendVerifyCode} |
| | | disabled={countdown > 0 || !phone || phone.length !== 11} |
| | | className={`px-4 py-2 rounded-lg border text-sm transition-all duration-300 whitespace-nowrap ${ |
| | | countdown > 0 || !phone || phone.length !== 11 |
| | | ? 'border-[#6ADBFF]/20 text-[#6ADBFF]/40 bg-[#131C41]/20 cursor-not-allowed' |
| | | : 'border-[#6ADBFF]/40 text-[#6ADBFF] bg-[#131C41]/40 hover:bg-[#131C41]/70 hover:border-[#6ADBFF]/60' |
| | | }`} |
| | | > |
| | | {countdown > 0 ? `${countdown}ç§åéè¯` : 'è·åéªè¯ç '} |
| | | </button> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* éç§å£°æ */} |
| | | <div className="text-xs text-white/60 mt-4"> |
| | | 注åå³è¡¨ç¤ºæ¨åæå¸·å¹åæç |
| | | <span className="text-[#6ADBFF] cursor-pointer hover:underline mx-1">æå¡æ¡æ¬¾</span> |
| | | å |
| | | <span className="text-[#6ADBFF] cursor-pointer hover:underline ml-1">éç§æ¿ç</span> |
| | | </div> |
| | | |
| | | {/* 注åæé® */} |
| | | <div className="mt-6"> |
| | | <button |
| | | type="submit" |
| | | disabled={isLoading} |
| | | className="w-full relative overflow-hidden px-6 py-3 rounded-lg bg-gradient-to-r from-[#5E72EB] to-[#6ADBFF] text-white font-medium shadow-lg group" |
| | | > |
| | | <span className="relative z-10"> |
| | | {isLoading ? ( |
| | | <span className="flex items-center justify-center"> |
| | | <svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> |
| | | <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> |
| | | <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> |
| | | </svg> |
| | | 注åä¸... |
| | | </span> |
| | | ) : ( |
| | | 'ç«å³æ³¨å' |
| | | )} |
| | | </span> |
| | | <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300"> |
| | | <div className="h-full w-[1px] bg-white/20 transform rotate-[20deg] translate-x-[-30px] group-hover:translate-x-[350px] transition-all duration-1000"></div> |
| | | </div> |
| | | </button> |
| | | </div> |
| | | </form> |
| | | </div> |
| | | </motion.div> |
| | | </div> |
| | | ); |
| | | } |