Register.jsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { useState } from 'react';
  2. import { useSearchParams, useNavigate } from 'react-router-dom';
  3. import { useLanguage } from '../context/LanguageContext';
  4. function Register() {
  5. const [searchParams] = useSearchParams();
  6. const navigate = useNavigate();
  7. const { t } = useLanguage();
  8. const [email, setEmail] = useState('');
  9. const [name, setName] = useState('');
  10. const [surname, setSurname] = useState('');
  11. const [isLoading, setIsLoading] = useState(false);
  12. const [error, setError] = useState('');
  13. const selectedPlan = searchParams.get('plan') || 'starter';
  14. const handleSubmit = async (e) => {
  15. e.preventDefault();
  16. setIsLoading(true);
  17. setError('');
  18. try {
  19. // Generate a random ID and token (you might want to handle this differently)
  20. const id = Math.random().toString(36).substr(2, 9);
  21. const token = Math.random().toString(36).substr(2, 9);
  22. const response = await fetch('http://192.168.1.35:8080/api/v1/check-email', {
  23. method: 'POST',
  24. headers: {
  25. 'Content-Type': 'application/json',
  26. },
  27. body: JSON.stringify({
  28. id,
  29. name,
  30. surname,
  31. email,
  32. token,
  33. plan: selectedPlan,
  34. status: true
  35. }),
  36. });
  37. if (!response.ok) {
  38. throw new Error('Registration failed');
  39. }
  40. // Show success message and redirect
  41. navigate('/registration-success');
  42. } catch (err) {
  43. setError(err.message);
  44. } finally {
  45. setIsLoading(false);
  46. }
  47. };
  48. return (
  49. <div className="min-h-screen flex items-center justify-center px-4 relative">
  50. {/* Background elements */}
  51. <div className="absolute inset-0 pointer-events-none overflow-hidden">
  52. <div className="absolute top-1/4 left-1/4 w-64 h-64 bg-brand-purple/10 rounded-full blur-3xl transform -translate-x-1/2 -translate-y-1/2"></div>
  53. <div className="absolute bottom-1/4 right-1/4 w-64 h-64 bg-brand-pink/10 rounded-full blur-3xl transform translate-x-1/2 translate-y-1/2"></div>
  54. </div>
  55. <div className="w-full max-w-md">
  56. <div className="bg-white/80 backdrop-blur-sm shadow-xl rounded-3xl p-8">
  57. <div className="text-center">
  58. <h2 className="text-[40px] font-light tracking-tight text-gray-900 relative inline-block">
  59. Create Account
  60. <span className="absolute -top-1 -right-1 w-2 h-2 bg-brand-purple rounded-full"></span>
  61. </h2>
  62. <p className="mt-2 text-sm text-gray-600">
  63. Selected plan: <span className="font-medium capitalize">{selectedPlan}</span>
  64. </p>
  65. </div>
  66. {error && (
  67. <div className="mt-4 p-4 bg-red-50 rounded-2xl text-red-600 text-sm">
  68. {error}
  69. </div>
  70. )}
  71. <form onSubmit={handleSubmit} className="mt-8 space-y-6">
  72. <div className="space-y-4">
  73. <div>
  74. <label htmlFor="name" className="sr-only">First Name</label>
  75. <input
  76. id="name"
  77. name="name"
  78. type="text"
  79. required
  80. value={name}
  81. onChange={(e) => setName(e.target.value)}
  82. placeholder="First Name"
  83. className="block w-full rounded-full border-0 px-6 py-4 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-brand-purple transition-all"
  84. />
  85. </div>
  86. <div>
  87. <label htmlFor="surname" className="sr-only">Last Name</label>
  88. <input
  89. id="surname"
  90. name="surname"
  91. type="text"
  92. required
  93. value={surname}
  94. onChange={(e) => setSurname(e.target.value)}
  95. placeholder="Last Name"
  96. className="block w-full rounded-full border-0 px-6 py-4 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-brand-purple transition-all"
  97. />
  98. </div>
  99. <div>
  100. <label htmlFor="email" className="sr-only">Email address</label>
  101. <input
  102. id="email"
  103. name="email"
  104. type="email"
  105. required
  106. value={email}
  107. onChange={(e) => setEmail(e.target.value)}
  108. placeholder="Email address"
  109. className="block w-full rounded-full border-0 px-6 py-4 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-brand-purple transition-all"
  110. />
  111. </div>
  112. </div>
  113. <div>
  114. <button
  115. type="submit"
  116. disabled={isLoading}
  117. className="relative flex w-full justify-center items-center rounded-full bg-brand-purple px-6 py-4 text-sm font-semibold text-white shadow-sm hover:bg-brand-purple/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-purple transition-all gap-2 disabled:opacity-70"
  118. >
  119. {isLoading ? (
  120. <>
  121. <div className="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
  122. <span>Creating account...</span>
  123. </>
  124. ) : (
  125. <>
  126. <span>Create account</span>
  127. <span className="transform group-hover:translate-x-1 transition-transform">→</span>
  128. </>
  129. )}
  130. </button>
  131. </div>
  132. <p className="mt-4 text-center text-sm text-gray-500">
  133. Already have an account?{' '}
  134. <a href="/login" className="font-medium text-brand-purple hover:text-brand-purple/80 relative inline-block group">
  135. Sign in
  136. <span className="absolute bottom-0 left-0 w-full h-0.5 bg-brand-purple transform scale-x-0 transition-transform group-hover:scale-x-100"></span>
  137. </a>
  138. </p>
  139. </form>
  140. </div>
  141. </div>
  142. </div>
  143. );
  144. }
  145. export default Register;