DataScope26/WEB
0
1import "./RegisterModal.css";2import { Eye, EyeOff, AtSign, Loader, CheckCircle } from "lucide-react";3import { useState, useEffect } from "react";4import { useAuth } from "../context/AuthContext.jsx";5import ButtonPrimary from "./ButtonPrimary.jsx";6import ButtonClose from "./ButtonClose.jsx";7 8export default function RegisterModal({ onClose, onOpenLogin }) {9 const [username, setUsername] = useState("");10 const [password, setPassword] = useState("");11 const [email, setEmail] = useState("");12 const [rememberMe, setRememberMe] = useState(false);13 const [showPassword, setShowPassword] = useState(false);14 const [isLoading, setIsLoading] = useState(false);15 const [isSuccess, setIsSuccess] = useState(false); // Nuevo estado para la lista de espera16 17 const [message, setMessage] = useState("");18 const [messageKey, setMessageKey] = useState(0);19 20 const [passwordChecklist, setPasswordChecklist] = useState({21 length: false,22 special: false,23 uppercaseLowercase: false24 });25 26 const { signup } = useAuth();27 28 useEffect(() => {29 const currentPassword = password || "";30 setPasswordChecklist({31 length: currentPassword.length >= 8,32 special: /[$&+,:;=?@#|'<>.-^*()%!]/.test(currentPassword),33 uppercaseLowercase:34 currentPassword !== currentPassword.toUpperCase() &&35 currentPassword !== currentPassword.toLowerCase()36 });37 }, [password]);38 39 const checkEmail = () => {40 setMessage("");41 if (email.length < 5) {42 setMessage("El correo debe tener al menos 5 caracteres");43 return false;44 }45 const parts = email.split("@");46 if (parts.length !== 2) {47 setMessage("Falta el símbolo @");48 return false;49 }50 const [localPart, domain] = parts;51 const localPartRegex = /^[A-Za-z0-9](?:[A-Za-z0-9._%+-]*[A-Za-z0-9])?$/;52 if (!localPartRegex.test(localPart)) {53 setMessage("Parte del correo antes del @ inválida");54 return false;55 }56 const domainRegex = /^[a-zA-Z]{2,10}\.[A-Za-z]{2,5}(\.[A-Za-z]{2,3})?$/;57 if (!domainRegex.test(domain)) {58 setMessage("Dominio del correo inválido");59 return false;60 }61 return true;62 };63 64 const checkPassword = () => {65 const currentPassword = password || "";66 if (currentPassword.length < 8) return false;67 if (!/[$&+,:;=?@#|'<>.-^*()%!]/.test(currentPassword)) return false;68 if (currentPassword === currentPassword.toUpperCase() || currentPassword === currentPassword.toLowerCase()) return false;69 return true;70 };71 72 const handleSubmit = async () => {73 setIsLoading(true);74 75 if (username.length < 3) {76 setMessage("El nombre de usuario debe tener al menos 3 caracteres");77 setMessageKey((prev) => prev + 1);78 setIsLoading(false);79 return;80 }81 82 try {83 if (checkEmail() && checkPassword()) {84 setMessage("");85 86 const result = await signup(username, email, password, rememberMe);87 88 if (result === true) {89 setIsSuccess(true);90 } else if (result?.status === 409) {91 setMessage("Ya estás registrado o en la lista de espera");92 setMessageKey((prev) => prev + 1);93 } else {94 setMessage("Hubo un error al procesar tu solicitud");95 setMessageKey((prev) => prev + 1);96 }97 } else {98 setMessageKey((prev) => prev + 1);99 }100 } catch (error) {101 console.error("Error durante el registro:", error);102 setMessage("Ocurrió un error al intentar registrarte");103 setMessageKey((prev) => prev + 1);104 } finally {105 setIsLoading(false);106 }107 };108 109 const getChecklistColor = (isValid) => {110 if (!password) return "#808080";111 return isValid ? "#22c55e" : "#ef4444";112 };113 114 return (115 <>116 <div className="modal-backdrop" onClick={onClose} />117 <div118 className="register-modal"119 onKeyDown={(e) => {120 if (e.key === "Enter" && !isSuccess) {121 handleSubmit();122 }123 }}124 >125 <ButtonClose onClick={onClose} />126 127 <div className="register-modal__layout">128 <aside className="register-modal__story">129 <p className="register-modal__eyebrow">Cupos limitados</p>130 <h1>Acceso Anticipado</h1>131 <p className="register-modal__copy">132 Datascope se lanza primero para un grupo reducido. Vas a poder usar el producto, opinar sobre lo que construimos y moldear la versión final antes que nadie más.133 </p>134 <ul className="register-modal__benefits">135 <li>Creá una compañía con el tier especial de <strong>Acceso Anticipado</strong>.</li>136 <li>Invitá hasta <strong>4 empleados adicionales</strong> a tu empresa.</li>137 <li>Accedé a todas las herramientas de nuestra <strong>extensión</strong>.</li>138 </ul>139 </aside>140 141 <div className="register-modal__form">142 {isSuccess ? (143 <div className="success-state" style={{ textAlign: "center", padding: "2rem 1rem" }}>144 <CheckCircle size={48} color="#22c55e" style={{ margin: "0 auto 1rem" }} />145 <h2>¡Solicitud enviada!</h2>146 <p>Estamos revisando tu pedido.</p>147 </div>148 ) : (149 <>150 <div className="input-group">151 <label>NOMBRE COMPLETO</label>152 <input153 type="text"154 placeholder="Ingresa tu nombre"155 value={username}156 onChange={(e) => setUsername(e.target.value)}157 maxLength={50}158 />159 </div>160 161 <div className="input-group">162 <label>EMAIL CORPORATIVO</label>163 <div className="input-icon">164 <input165 type="email"166 placeholder="nombre@compania.com"167 value={email}168 onChange={(e) => setEmail(e.target.value)}169 maxLength={50}170 />171 <AtSign size={18} className="icon" />172 </div>173 </div>174 175 <div className="input-group">176 <label>CONTRASEÑA</label>177 <div className="input-icon">178 <input179 type={showPassword ? "text" : "password"}180 placeholder="••••••••"181 value={password}182 onChange={(e) => setPassword(e.target.value)}183 maxLength={50}184 />185 {showPassword ? (186 <EyeOff size={18} className="icon" style={{ cursor: "pointer" }} onClick={() => setShowPassword(!showPassword)} />187 ) : (188 <Eye size={18} className="icon" style={{ cursor: "pointer" }} onClick={() => setShowPassword(!showPassword)} />189 )}190 </div>191 <div className="password-checklist">192 <div style={{ color: getChecklistColor(passwordChecklist.length) }}>193 {passwordChecklist.length ? "☑" : "☐"} Contraseña tiene al menos 8 caracteres194 </div>195 <div style={{ color: getChecklistColor(passwordChecklist.special) }}>196 {passwordChecklist.special ? "☑" : "☐"} Contraseña contiene al menos 1 caracter especial197 </div>198 <div style={{ color: getChecklistColor(passwordChecklist.uppercaseLowercase) }}>199 {passwordChecklist.uppercaseLowercase ? "☑" : "☐"} Contraseña tiene al menos 1 mayuscula y 1 minuscula200 </div>201 </div>202 </div>203 204 {message && (205 <p key={messageKey} className="error-text error-text--animated">206 {message}207 </p>208 )}209 210 {isLoading ? (211 <ButtonPrimary className="register-btn" type="button" style={{ cursor: "default" }}>212 <Loader size={18} className="loader-icon-animation" />213 </ButtonPrimary>214 ) : (215 <ButtonPrimary className="register-btn" onClick={() => handleSubmit()}>216 Quiero mi lugar217 </ButtonPrimary>218 )}219 220 <p className="bottom-text">221 ¿Ya tenes una cuenta?{" "}222 <span223 onClick={() => {224 onOpenLogin();225 onClose();226 }}227 >228 Inicia sesion229 </span>230 </p>231 <p className="copyright">© 2026 DataScope</p>232 </>233 )}234 </div>235 </div>236 </div>237 </>238 );239}