Skip to content

Commit

Permalink
base for email sign up flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Winston-Hsiao committed Aug 9, 2024
1 parent 75e58e4 commit 676d3a6
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 3 deletions.
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Login from "pages/Login";
import Logout from "pages/Logout";
import NotFound from "pages/NotFound";
import Profile from "pages/Profile";
import Register from "pages/Register";

import Container from "components/Container";
import NotFoundRedirect from "components/NotFoundRedirect";
Expand All @@ -39,6 +40,7 @@ const App = () => {
<Route path="/profile" element={<Profile />} />
<Route path="/login" element={<Login />} />
<Route path="/logout" element={<Logout />} />
<Route path="/register/:token" element={<Register />} />
<Route path="/create" element={<Create />} />
<Route path="/browse/:page?" element={<Browse />} />
<Route path="/item/:id" element={<ListingDetails />} />
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/auth/AuthBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Spinner from "components/ui/Spinner";

import AuthProvider from "./AuthProvider";
import LoginForm from "./LoginForm";
import SignupForm from "./SignupForm";
import SignupWithEmail from "./SignupWithEmail";

export const AuthBlockInner = () => {
const auth = useAuthentication();
Expand Down Expand Up @@ -66,7 +66,9 @@ export const AuthBlockInner = () => {

return (
<>
<CardContent>{isSignup ? <SignupForm /> : <LoginForm />}</CardContent>
<CardContent>
{isSignup ? <SignupWithEmail /> : <LoginForm />}
</CardContent>
<CardFooter>
<AuthProvider handleGithubSubmit={handleGithubSubmit} />
</CardFooter>
Expand Down
48 changes: 48 additions & 0 deletions frontend/src/components/auth/SignupWithEmail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { SubmitHandler, useForm } from "react-hook-form";

import { zodResolver } from "@hookform/resolvers/zod";
import { EmailSignUpSchema, EmailSignUpType } from "types";

import { Button } from "components/ui/Button/Button";
import ErrorMessage from "components/ui/ErrorMessage";
import { Input } from "components/ui/Input/Input";

const SignupWithEmail = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<EmailSignupType>({
resolver: zodResolver(EmailSignUpSchema),
});

const onSubmit: SubmitHandler<EmailSignupType> = async (
data: EmailSignupType,
) => {
// TODO: Add an api endpoint to create EmailSignUpToken and send email to
// submitted email. User gets link in email to /register/{token}
// to finish sign up

console.log(data);
};

return (
<form
onSubmit={handleSubmit(onSubmit)}
className="grid grid-cols-1 space-y-6">
{/* Email Input */}
<div className="relative">
<Input placeholder="Email" type="text" {...register("email")} />
{errors?.email && <ErrorMessage>{errors?.email?.message}</ErrorMessage>}
</div>
{/* Signup Button */}
<Button
variant="outline"
className="w-full text-white bg-blue-600 hover:bg-opacity-70">
Sign up with email
</Button>
</form>
);
};

export default SignupWithEmail;
65 changes: 65 additions & 0 deletions frontend/src/pages/Register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";

import { paths } from "gen/api";
import { useAlertQueue } from "hooks/useAlertQueue";
import { useAuthentication } from "hooks/useAuth";

import SignupForm from "components/auth/SignupForm";
import { Button } from "components/ui/Button/Button";

type EmailSignUpResponse =
paths["/emailSignUp/{token}"]["get"]["responses"][200]["content"]["application/json"];

const Register = () => {
const { addErrorAlert } = useAlertQueue();
const { token } = useParams();
const [emailToken, setEmailToken] = useState<EmailSignUpResponse | null>(
null,
);
const auth = useAuthentication();

useEffect(() => {
const fetchListing = async () => {
if (token === undefined) {
return;
}

try {
const { data, error } = await auth.client.GET("/emailSignUp/{token}", {
params: {
path: { token },
},
});
if (error) {
addErrorAlert(error);
} else {
setEmailToken(data);
}
} catch (err) {
addErrorAlert(err);
}
};
fetchListing();
}, [token]);

if (!emailToken) {
return (
<div>
<h1>Invalid Sign Up Link</h1>
<Button
variant="outline"
className="w-full text-white bg-blue-600 hover:bg-opacity-70">
Login / Signup
</Button>
</div>
);
}
return (
<div>
<SignupForm />
</div>
);
};

export default Register;
11 changes: 11 additions & 0 deletions frontend/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ export const LoginSchema = z.object({

export type LoginType = z.infer<typeof LoginSchema>;

export const EmailSignUpSchema = z.object({
email: z
.string({
required_error: "Email required.",
})
.min(3, { message: "Email required." })
.email("Invalid email."),
});

export type EmailSignUpType = z.infer<typeof EmailSignUpSchema>;

export const SignUpSchema = z
.object({
email: z
Expand Down
15 changes: 14 additions & 1 deletion store/app/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class User(RobolistBaseModel):
permissions: set[UserPermission] | None = None
created_at: int
updated_at: int
email_verified_at: int | None = None
github_id: str | None = None
google_id: str | None = None

Expand Down Expand Up @@ -74,6 +73,20 @@ def verify_email(self) -> None:
self.email_verified_at = int(time.time())


class EmailSignUpToken(RobolistBaseModel):
"""
Object created when user attempts to sign up with email.
Will be checked by register dynamic route
"""

token: str

@classmethod
def create(cls) -> Self:
return cls(token=new_uuid())


class OAuthKey(RobolistBaseModel):
"""Keys for OAuth providers which identify users."""

Expand Down

0 comments on commit 676d3a6

Please sign in to comment.