diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx index 096e5be..e71edf0 100644 --- a/frontend/src/pages/Register.tsx +++ b/frontend/src/pages/Register.tsx @@ -1,7 +1,8 @@ import { useState, useEffect, FormEvent } from 'react'; import { Button, TextInput, TextArea } from '@components'; +import { register, RegisterError, saveRefreshToken } from '@services'; -type RegistrationStep = +type RegistrationStep = | 'login-register' | 'verify-email' | 'signing-in' @@ -25,7 +26,8 @@ interface FormErrors { } const Register = () => { - const [currentStep, setCurrentStep] = useState('login-register'); + const [currentStep, setCurrentStep] = + useState('login-register'); const [formData, setFormData] = useState({ firstName: '', lastName: '', @@ -33,11 +35,12 @@ const Register = () => { bio: '', linkedIn: '', email: '', - password: '' + password: '', }); const [errors, setErrors] = useState({}); - const LINKEDIN_REGEX = /^(https?:\/\/)?([\w]+\.)?linkedin\.com\/(pub|in|profile)\/([-a-zA-Z0-9]+)\/?$/; + const LINKEDIN_REGEX = + /^(https?:\/\/)?([\w]+\.)?linkedin\.com\/(pub|in|profile)\/([-a-zA-Z0-9]+)\/?$/; const validateLinkedIn = (url: string): boolean => { if (!url) return false; @@ -46,42 +49,64 @@ const Register = () => { const handleLinkedInChange = (e: React.ChangeEvent) => { const { name, value } = e.target; - setFormData(prev => ({ + setFormData((prev) => ({ ...prev, - [name]: value + [name]: value, })); if (value && !validateLinkedIn(value)) { - setErrors(prev => ({ + setErrors((prev) => ({ ...prev, - linkedIn: "Please enter a valid LinkedIn profile URL" + linkedIn: 'Please enter a valid LinkedIn profile URL', })); } else { - setErrors(prev => ({ + setErrors((prev) => ({ ...prev, - linkedIn: undefined + linkedIn: undefined, })); } }; - const handleChange = (e: React.ChangeEvent) => { + const handleChange = ( + e: React.ChangeEvent + ) => { const { name, value } = e.target; - setFormData(prev => ({ + setFormData((prev) => ({ ...prev, - [name]: value + [name]: value, })); if (errors[name as keyof FormErrors]) { - setErrors(prev => ({ + setErrors((prev) => ({ ...prev, - [name]: undefined + [name]: undefined, })); } }; - const handleInitialSubmit = (e: FormEvent) => { + const handleInitialSubmit = async (e: FormEvent) => { e.preventDefault(); - setCurrentStep('verify-email'); + try { + // user information and access token should be stored in an auth provider + const regResp = await register(formData.email, formData.password); + console.log(regResp); + + // save the refresh token in local storage and use it to request a new + // access token later when the user reopens the web app. + // IMPORTANT: for now localstorage works, but by MVP we need a more proper + // way to handle authentication using HTTP-only cookies and adding + // fingerprint information to tokens to prevet XSS. + // for more info: https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html#token-storage-on-client-side + saveRefreshToken(regResp.refreshToken); + setCurrentStep('verify-email'); + } catch (error) { + if (error instanceof RegisterError) { + // TODO: handle error with some kind of notification + console.log('do something here', error.statusCode, error.body); + } else { + // TODO: handle error with some kind of notification + } + } }; const handleFormSubmit = (e: FormEvent) => { @@ -95,7 +120,7 @@ const Register = () => { formData.lastName.trim() !== '' && formData.position.trim() !== '' && formData.bio.trim() !== '' && - formData.linkedIn.trim() !== '' && + formData.linkedIn.trim() !== '' && !errors.linkedIn ); }; @@ -104,41 +129,35 @@ const Register = () => {

Register or Login


-

Register for Spur+Konfer

- +

+ Register for Spur+Konfer +

+
- - - - -
-

- Already have an account? -

+

Already have an account?

+
); @@ -188,29 +212,30 @@ const Register = () => {

Welcome to Spur+Konfer

- To begin your application, please enter your organization's details + To begin your application, please enter your organization's + details

- - - { />