| |
| |
| |
| 'use strict'; |
|
|
| |
| (function(){ |
| const s = JSON.parse(localStorage.getItem('sf_session')||'null'); |
| if(s && s.loggedIn) window.location.href = 'index.html'; |
| })(); |
|
|
| |
| (function(){ |
| const c = document.getElementById('authParticles'); |
| for(let i=0;i<20;i++){ |
| const p=document.createElement('div');p.className='particle'; |
| const sz=Math.random()*5+2; |
| Object.assign(p.style,{width:sz+'px',height:sz+'px',left:Math.random()*100+'%',bottom:'-10px',animationDuration:(Math.random()*20+15)+'s',animationDelay:(Math.random()*10)+'s',opacity:Math.random()*.4+.1}); |
| c.appendChild(p); |
| } |
| })(); |
|
|
| |
| const form = document.getElementById('signupForm'); |
| const nameInp = document.getElementById('signupName'); |
| const emailInp = document.getElementById('signupEmail'); |
| const passInp = document.getElementById('signupPass'); |
| const confirmInp = document.getElementById('signupConfirm'); |
| const nameErr = document.getElementById('nameErr'); |
| const emailErr = document.getElementById('emailErr'); |
| const passErr = document.getElementById('passErr'); |
| const confirmErr = document.getElementById('confirmErr'); |
| const globalErr = document.getElementById('globalErr'); |
| const globalOk = document.getElementById('globalSuccess'); |
| const btnText = document.getElementById('signupBtnText'); |
| const btnLoader = document.getElementById('signupBtnLoader'); |
| const strengthFill = document.getElementById('strengthFill'); |
| const strengthLabel = document.getElementById('strengthLabel'); |
|
|
| |
| function toggleVis(inputEl, btn){ |
| btn.addEventListener('click',()=>{ |
| const show = inputEl.type==='password'; |
| inputEl.type = show?'text':'password'; |
| btn.querySelector('i').className = show?'fas fa-eye-slash':'fas fa-eye'; |
| }); |
| } |
| toggleVis(passInp, document.getElementById('togglePass1')); |
| toggleVis(confirmInp, document.getElementById('togglePass2')); |
|
|
| |
| passInp.addEventListener('input',()=>{ |
| const v = passInp.value; |
| let score = 0; |
| if(v.length>=8) score++; |
| if(/[A-Z]/.test(v)) score++; |
| if(/[0-9]/.test(v)) score++; |
| if(/[^A-Za-z0-9]/.test(v)) score++; |
| const levels = [ |
| {pct:0, color:'transparent', label:'Enter password'}, |
| {pct:25, color:'#EF4444', label:'Weak'}, |
| {pct:50, color:'#F59E0B', label:'Fair'}, |
| {pct:75, color:'#3B82F6', label:'Good'}, |
| {pct:100, color:'#10B981', label:'Strong'}, |
| ]; |
| const l = v.length===0 ? levels[0] : levels[Math.max(1,score)]; |
| strengthFill.style.width = l.pct+'%'; |
| strengthFill.style.background = l.color; |
| strengthLabel.textContent = l.label; |
| strengthLabel.style.color = l.color; |
| }); |
|
|
| |
| function setErr(el,fgId,msg){ |
| el.textContent=msg; |
| const fg=document.getElementById(fgId); |
| fg.classList.add('has-error');fg.classList.remove('has-ok'); |
| } |
| function setOk(el,fgId){ |
| el.textContent=''; |
| const fg=document.getElementById(fgId); |
| fg.classList.remove('has-error');fg.classList.add('has-ok'); |
| } |
| function clearState(el,fgId){ |
| el.textContent=''; |
| const fg=document.getElementById(fgId); |
| fg.classList.remove('has-error','has-ok'); |
| } |
|
|
| function validateEmail(e){return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);} |
|
|
| |
| form.addEventListener('submit',function(e){ |
| e.preventDefault(); |
| globalErr.textContent=''; globalOk.style.display='none'; |
| let valid=true; |
|
|
| const name = nameInp.value.trim(); |
| const email = emailInp.value.trim().toLowerCase(); |
| const pass = passInp.value; |
| const confirm = confirmInp.value; |
|
|
| |
| if(!name){setErr(nameErr,'fg-name','Full name is required.');valid=false;} |
| else if(name.length<2){setErr(nameErr,'fg-name','Name must be at least 2 characters.');valid=false;} |
| else setOk(nameErr,'fg-name'); |
|
|
| |
| if(!email){setErr(emailErr,'fg-email','Email is required.');valid=false;} |
| else if(!validateEmail(email)){setErr(emailErr,'fg-email','Enter a valid email address.');valid=false;} |
| else setOk(emailErr,'fg-email'); |
|
|
| |
| if(!pass){setErr(passErr,'fg-pass','Password is required.');valid=false;} |
| else if(pass.length<6){setErr(passErr,'fg-pass','Password must be at least 6 characters.');valid=false;} |
| else setOk(passErr,'fg-pass'); |
|
|
| |
| if(!confirm){setErr(confirmErr,'fg-confirm','Please confirm your password.');valid=false;} |
| else if(confirm!==pass){setErr(confirmErr,'fg-confirm','Passwords do not match.');valid=false;} |
| else setOk(confirmErr,'fg-confirm'); |
|
|
| if(!valid) return; |
|
|
| |
| if(email==='admin@speakflow.ai'){globalErr.textContent='β This email is reserved.';return;} |
|
|
| |
| const users = JSON.parse(localStorage.getItem('sf_users')||'[]'); |
| if(users.find(u=>u.email===email)){globalErr.textContent='β An account with this email already exists.';return;} |
|
|
| |
| btnText.style.display='none'; btnLoader.style.display='flex'; |
|
|
| setTimeout(()=>{ |
| const newUser = { |
| id: 'usr_'+Date.now(), |
| name, email, password:pass, |
| createdAt: new Date().toISOString() |
| }; |
| users.push(newUser); |
| localStorage.setItem('sf_users',JSON.stringify(users)); |
|
|
| |
| const session = {loggedIn:true, name, email, id:newUser.id}; |
| localStorage.setItem('sf_session',JSON.stringify(session)); |
|
|
| globalOk.textContent='β
Account created! Redirecting...'; |
| globalOk.style.display='block'; |
| btnText.style.display='flex'; btnLoader.style.display='none'; |
|
|
| setTimeout(()=>{ window.location.href='index.html'; },1000); |
| },900); |
| }); |
|
|
| |
| nameInp.addEventListener('blur',()=>{ if(!nameInp.value.trim()) setErr(nameErr,'fg-name','Full name is required.'); }); |
| emailInp.addEventListener('blur',()=>{ |
| const v=emailInp.value.trim(); |
| if(!v) setErr(emailErr,'fg-email','Email is required.'); |
| else if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) setErr(emailErr,'fg-email','Enter a valid email address.'); |
| }); |
| passInp.addEventListener('blur',()=>{ if(!passInp.value) setErr(passErr,'fg-pass','Password is required.'); }); |
| confirmInp.addEventListener('blur',()=>{ |
| if(confirmInp.value && confirmInp.value!==passInp.value) setErr(confirmErr,'fg-confirm','Passwords do not match.'); |
| else if(!confirmInp.value) setErr(confirmErr,'fg-confirm','Please confirm your password.'); |
| }); |
|
|