Refactor email sign up form

pull/3813/head
Kamran Ahmed 2 years ago
parent 9c8cd71ed2
commit 1ea66824d0
  1. 116
      src/components/Login/EmailSignupForm.tsx
  2. 2
      src/components/SocialAuth/GitHubButton.tsx
  3. 5
      src/components/SocialAuth/GoogleButton.tsx

@ -1,27 +1,32 @@
import Cookies from 'js-cookie';
import type { FunctionComponent } from 'preact';
import { useState } from 'preact/hooks';
import { TOKEN_COOKIE_NAME } from '../../lib/constants';
import Spinner from '../Spinner';
const EmailSignupForm: FunctionComponent<{}> = () => {
const [email, setEmail] = useState<string>('');
const [password, setPassword] = useState<string>('');
const [name, setName] = useState<string>('');
const EmailSignupForm: FunctionComponent = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [name, setName] = useState('');
const [isLoading, setIsLoading] = useState<boolean>(false);
const [message, setMessage] = useState<{
type: 'success' | 'error' | 'verification' | 'warning';
message: string;
} | null>(null);
const [error, setError] = useState('');
const [isLoading, setIsLoading] = useState(false);
return (
<form
className="w-full"
onSubmit={(e) => {
const handleRegisterResponse = async (res: Response) => {
const json = await res.json();
if (!res.ok) {
setError(json.message || 'Something went wrong. Please try again later.');
setIsLoading(false);
return;
}
window.location.href = `/verify?email=${email}`;
};
const onSubmit = (e: Event) => {
e.preventDefault();
setIsLoading(true);
fetch('http://localhost:8080/v1-register', {
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@ -32,45 +37,27 @@ const EmailSignupForm: FunctionComponent<{}> = () => {
name,
}),
})
.then(async (res) => {
const json = await res.json();
if (res.status === 200) {
window.location.href = `/verify?email=${email}`;
setName('');
setEmail('');
setPassword('');
setMessage({
type: 'success',
message:
'We have sent you an email with the verification link. Please follow the instructions to login.',
});
} else {
const error = new Error(json.message) as any;
error.status = res.status;
throw error;
}
setIsLoading(false);
})
.then(handleRegisterResponse)
.catch((err) => {
setIsLoading(false);
setMessage({
type: 'error',
message: err.message,
});
setError('Something went wrong. Please try again later.');
});
}}
>
};
return (
<form className="flex w-full flex-col gap-2" onSubmit={onSubmit}>
<label htmlFor="name" className="sr-only">
Name
</label>
<input
id="name"
name="name"
type="name"
type="text"
autoComplete="name"
min={3}
max={50}
required
className="block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="John Doe"
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="Full Name"
value={name}
onInput={(e) => setName(String((e.target as any).value))}
/>
@ -78,13 +65,12 @@ const EmailSignupForm: FunctionComponent<{}> = () => {
Email address
</label>
<input
id="email"
name="email"
type="email"
autoComplete="email"
required
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="john@example.com"
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="Email Address"
value={email}
onInput={(e) => setEmail(String((e.target as any).value))}
/>
@ -92,42 +78,28 @@ const EmailSignupForm: FunctionComponent<{}> = () => {
Password
</label>
<input
id="password"
name="password"
type="password"
autoComplete="current-password"
min={6}
max={50}
required
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="Enter you password"
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="Password"
value={password}
onInput={(e) => setPassword(String((e.target as any).value))}
/>
{message && (
<div
className={`mt-2 rounded-lg p-2 ${
message.type === 'error'
? 'bg-red-100 text-red-700'
: message.type === 'success'
? 'bg-green-100 text-green-700'
: 'bg-blue-100 text-blue-700'
}`}
>
{message.message}
</div>
{error && (
<p className="rounded-lg bg-red-100 p-2 text-red-700">{error}.</p>
)}
<button
type="submit"
disabled={
email.length === 0 ||
password.length === 0 ||
name.length === 0 ||
isLoading
}
className="mt-3 inline-flex h-10 w-full items-center justify-center rounded-lg border border-slate-300 bg-black p-2 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:opacity-60"
disabled={isLoading}
className="inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-none focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
>
{isLoading ? <Spinner className="text-white" /> : 'Continue'}
{isLoading ? 'Please wait...' : 'Continue to Verify Email'}
</button>
</form>
);

@ -73,7 +73,7 @@ export function GitHubButton(props: GitHubButtonProps) {
return (
<>
<button
class="inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
class="inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
disabled={isLoading}
onClick={handleClick}
>

@ -1,9 +1,8 @@
import { useEffect, useState } from 'preact/hooks';
import Cookies from 'js-cookie';
import GoogleIcon from '../../icons/google.svg';
import SpinnerIcon from '../../icons/spinner.svg';
import { TOKEN_COOKIE_NAME } from '../../lib/constants';
import Cookies from 'js-cookie';
type GoogleButtonProps = {};
@ -73,7 +72,7 @@ export function GoogleButton(props: GoogleButtonProps) {
return (
<>
<button
class="inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
class="inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
disabled={isLoading}
onClick={handleClick}
>

Loading…
Cancel
Save