Register.jsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { useState } from 'react';
  2. import { useSearchParams, useNavigate, Link } from 'react-router-dom';
  3. import { useLanguage } from '../context/LanguageContext';
  4. import Footer from '../components/Footer';
  5. import { API_HOST } from '../config';
  6. function Register() {
  7. const [searchParams] = useSearchParams();
  8. const navigate = useNavigate();
  9. const { t } = useLanguage();
  10. const [email, setEmail] = useState('');
  11. const [name, setName] = useState('');
  12. const [surname, setSurname] = useState('');
  13. const [isLoading, setIsLoading] = useState(false);
  14. const [error, setError] = useState('');
  15. const selectedPlan = searchParams.get('plan') || 'starter';
  16. const handleSubmit = async (e) => {
  17. e.preventDefault();
  18. setIsLoading(true);
  19. setError('');
  20. try {
  21. // Generate a random ID and token (you might want to handle this differently)
  22. const id = Math.random().toString(36).substr(2, 9);
  23. const token = Math.random().toString(36).substr(2, 9);
  24. const response = await fetch(`${API_HOST}/api/v1/onboard/check-email`, {
  25. method: 'POST',
  26. headers: {
  27. 'Content-Type': 'application/json',
  28. },
  29. body: JSON.stringify({
  30. id,
  31. name,
  32. surname,
  33. email,
  34. token,
  35. plan: selectedPlan,
  36. status: true
  37. }),
  38. });
  39. if (!response.ok) {
  40. throw new Error('Registration failed');
  41. }
  42. // Navigate to registration success page instead of verify-email
  43. navigate('/registration-success');
  44. } catch (err) {
  45. setError(err.message);
  46. } finally {
  47. setIsLoading(false);
  48. }
  49. };
  50. return (
  51. <div className="relative min-h-screen bg-white">
  52. {/* Technical grid background */}
  53. <div className="fixed inset-0 technical-grid opacity-50 pointer-events-none"></div>
  54. <div className="max-w-[1600px] mx-auto px-8 sm:px-12 lg:px-16 pt-32">
  55. {/* Header section */}
  56. <div className="grid-layout mb-16">
  57. <div className="col-span-12 md:col-span-8">
  58. <h1 className="brutalist-heading relative">
  59. Create Account
  60. <div className="absolute -right-8 -top-8 w-16 h-16">
  61. <div className="geometric-shape diamond w-full h-full bg-black"></div>
  62. </div>
  63. </h1>
  64. <p className="monospace text-xl md:text-2xl font-medium tracking-tight max-w-2xl">
  65. Selected plan: <span className="uppercase font-bold">{selectedPlan}</span>
  66. </p>
  67. </div>
  68. </div>
  69. <div className="geometric-divider mb-16"></div>
  70. {/* Registration Form */}
  71. <div className="grid-layout">
  72. <div className="col-span-12 md:col-span-6 lg:col-span-4">
  73. <div className="brutalist-card">
  74. {error && (
  75. <div className="p-4 border-2 border-black bg-red-100 monospace">
  76. {error}
  77. </div>
  78. )}
  79. <form onSubmit={handleSubmit} className="p-6 space-y-8">
  80. <div className="space-y-6">
  81. <div>
  82. <label htmlFor="name" className="block text-sm font-black uppercase mb-2">
  83. First Name
  84. </label>
  85. <input
  86. id="name"
  87. name="name"
  88. type="text"
  89. required
  90. value={name}
  91. onChange={(e) => setName(e.target.value)}
  92. placeholder="Enter your first name"
  93. className="w-full border-2 border-black bg-white px-4 py-3 monospace placeholder:text-gray-500 focus:outline-none focus:ring-2 focus:ring-black"
  94. />
  95. </div>
  96. <div>
  97. <label htmlFor="surname" className="block text-sm font-black uppercase mb-2">
  98. Last Name
  99. </label>
  100. <input
  101. id="surname"
  102. name="surname"
  103. type="text"
  104. required
  105. value={surname}
  106. onChange={(e) => setSurname(e.target.value)}
  107. placeholder="Enter your last name"
  108. className="w-full border-2 border-black bg-white px-4 py-3 monospace placeholder:text-gray-500 focus:outline-none focus:ring-2 focus:ring-black"
  109. />
  110. </div>
  111. <div>
  112. <label htmlFor="email" className="block text-sm font-black uppercase mb-2">
  113. Email Address
  114. </label>
  115. <input
  116. id="email"
  117. name="email"
  118. type="email"
  119. required
  120. value={email}
  121. onChange={(e) => setEmail(e.target.value)}
  122. placeholder="Enter your email"
  123. className="w-full border-2 border-black bg-white px-4 py-3 monospace placeholder:text-gray-500 focus:outline-none focus:ring-2 focus:ring-black"
  124. />
  125. </div>
  126. </div>
  127. <div className="section-divider"></div>
  128. <button
  129. type="submit"
  130. disabled={isLoading}
  131. className="brutalist-button w-full disabled:opacity-50"
  132. >
  133. {isLoading ? (
  134. <span className="monospace">Creating account...</span>
  135. ) : (
  136. <span>Create account →</span>
  137. )}
  138. </button>
  139. </form>
  140. </div>
  141. <div className="mt-8 text-center">
  142. <p className="monospace">
  143. Already have an account?{' '}
  144. <Link to="/login" className="underline font-bold hover:text-gray-600 transition-colors">
  145. Sign in
  146. </Link>
  147. </p>
  148. </div>
  149. </div>
  150. </div>
  151. </div>
  152. <Footer />
  153. </div>
  154. );
  155. }
  156. export default Register;