Skip to content

Commit

Permalink
handle register form submission
Browse files Browse the repository at this point in the history
  • Loading branch information
juancwu committed Dec 5, 2024
1 parent b91b372 commit 25ba0ff
Showing 1 changed file with 89 additions and 58 deletions.
147 changes: 89 additions & 58 deletions frontend/src/pages/Register.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -25,19 +26,21 @@ interface FormErrors {
}

const Register = () => {
const [currentStep, setCurrentStep] = useState<RegistrationStep>('login-register');
const [currentStep, setCurrentStep] =
useState<RegistrationStep>('login-register');
const [formData, setFormData] = useState<FormData>({
firstName: '',
lastName: '',
position: '',
bio: '',
linkedIn: '',
email: '',
password: ''
password: '',
});
const [errors, setErrors] = useState<FormErrors>({});

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;
Expand All @@ -46,42 +49,64 @@ const Register = () => {

const handleLinkedInChange = (e: React.ChangeEvent<HTMLInputElement>) => {
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<HTMLInputElement | HTMLTextAreaElement>) => {
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
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) => {
Expand All @@ -95,7 +120,7 @@ const Register = () => {
formData.lastName.trim() !== '' &&
formData.position.trim() !== '' &&
formData.bio.trim() !== '' &&
formData.linkedIn.trim() !== '' &&
formData.linkedIn.trim() !== '' &&
!errors.linkedIn
);
};
Expand All @@ -104,41 +129,35 @@ const Register = () => {
<div className="w-full max-w-md mx-auto p-6 bg-white rounded-lg">
<h3 className="text-center mb-4 font-light">Register or Login</h3>
<hr className="border-gray-400" />
<h2 className="text-2xl mt-4 font-normal">Register for Spur+Konfer</h2>

<h2 className="text-2xl mt-4 font-normal">
Register for Spur+Konfer
</h2>

<form onSubmit={handleInitialSubmit} className="space-y-4 mt-4">
<TextInput
label="Email"
<TextInput
label="Email"
required
type="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
<TextInput
label="Password"

<TextInput
label="Password"
required
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>

<Button
type="submit"
size="lg"
liquid
variant="primary"
// TODO: onClick to handle register
>

<Button type="submit" size="lg" liquid variant="primary">
Register
</Button>

<div className="text-center mt-4">
<p className="text-md mb-3">
Already have an account?
</p>
<p className="text-md mb-3">Already have an account?</p>
<Button
type="button"
liquid
Expand All @@ -156,12 +175,17 @@ const Register = () => {
<div className="w-full max-w-md mx-auto p-6 bg-white rounded-lg">
<h2 className="text-2xl mb-4">Verify your account</h2>
<p className="font-light mb-6">
Your account and wallet has been linked. We just sent an email confirmation to <span className="font-semibold">{formData.email}</span>. Please verify your account to continue registering.
Your account and wallet has been linked. We just sent an email
confirmation to{' '}
<span className="font-semibold">{formData.email}</span>. Please
verify your account to continue registering.
</p>

<div className="font-light mt-4">
<span>Didn't get the email? </span>
<button className="text-blue-500 hover:underline">Resend Link</button>
<button className="text-blue-500 hover:underline">
Resend Link
</button>
</div>
</div>
);
Expand All @@ -188,45 +212,46 @@ const Register = () => {
<div className="text-center mb-8">
<h1 className="text-2xl font-bold">Welcome to Spur+Konfer</h1>
<p className="text-gray-600 mt-2">
To begin your application, please enter your organization's details
To begin your application, please enter your organization's
details
</p>
</div>

<form onSubmit={handleFormSubmit} className="space-y-4">
<TextInput
label="Your first name"
<TextInput
label="Your first name"
required
name="firstName"
value={formData.firstName}
onChange={handleChange}
/>

<TextInput
label="Your last name"
<TextInput
label="Your last name"
required
name="lastName"
value={formData.lastName}
onChange={handleChange}
/>

<TextInput
label="Your position/title"
<TextInput
label="Your position/title"
required
name="position"
value={formData.position}
onChange={handleChange}
/>

<TextArea
label="Your bio"
label="Your bio"
required
name="bio"
value={formData.bio}
onChange={handleChange}
/>

<TextInput
label="Link to your LinkedIn"
<TextInput
label="Link to your LinkedIn"
required
name="linkedIn"
value={formData.linkedIn}
Expand All @@ -235,20 +260,27 @@ const Register = () => {
/>

<div className="pt-4">
<Button
<Button
type="submit"
disabled={!isFormDetailsValid()}
liquid
size="lg"
variant="primary"
>
>
Register
</Button>
</div>

<p className="text-center text-sm mt-4">
By registering, you agree to Spur+Konfers'<br />
<a href="#" className="text-blue-500">Terms of Service</a> and <a href="#" className="text-blue-500">Privacy Policy</a>
By registering, you agree to Spur+Konfers'
<br />
<a href="#" className="text-blue-500">
Terms of Service
</a>{' '}
and{' '}
<a href="#" className="text-blue-500">
Privacy Policy
</a>
</p>
</form>
</div>
Expand All @@ -266,7 +298,8 @@ const Register = () => {
return (
<div className="w-full max-w-md mx-auto p-6 text-center">
<h2 className="text-xl mb-4">
Thank you for registering, you will now be redirected to the dashboard
Thank you for registering, you will now be redirected to the
dashboard
</h2>
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto" />
</div>
Expand All @@ -290,11 +323,9 @@ const Register = () => {

return (
<div className="min-h-screen bg-gray-50">
<div className="p-4">
{renderCurrentStep()}
</div>
<div className="p-4">{renderCurrentStep()}</div>
</div>
);
};

export { Register };
export { Register };

0 comments on commit 25ba0ff

Please sign in to comment.