diff --git a/apps/drive-web/src/auth/api.ts b/apps/drive-web/src/auth/api.ts
index 1b4bb74..bfa8d0c 100644
--- a/apps/drive-web/src/auth/api.ts
+++ b/apps/drive-web/src/auth/api.ts
@@ -1,14 +1,20 @@
import { mutationOptions } from "@tanstack/react-query"
import { type } from "arktype"
-import { accountsQuery } from "../account/api"
-import { fetchApi } from "../lib/api"
-import { currentUserQuery } from "../user/api"
-import { User } from "../user/user"
+import { Account } from "@/account/account"
+import { accountsQuery } from "@/account/api"
+import { fetchApi } from "@/lib/api"
+import { currentUserQuery } from "@/user/api"
+import { User } from "@/user/user"
const LoginResponseSchema = type({
user: User,
})
+const SignUpResponse = type({
+ account: Account,
+ user: User,
+})
+
export const loginMutation = mutationOptions({
mutationFn: async (data: { email: string; password: string }) => {
const [_, result] = await fetchApi("POST", "/auth/login", {
@@ -25,3 +31,24 @@ export const loginMutation = mutationOptions({
context.client.invalidateQueries(accountsQuery)
},
})
+
+export const signUpMutation = mutationOptions({
+ mutationFn: async (data: {
+ displayName: string
+ email: string
+ password: string
+ }) => {
+ const [_, result] = await fetchApi("POST", "/accounts", {
+ body: JSON.stringify({
+ ...data,
+ tokenDelivery: "cookie",
+ }),
+ returns: SignUpResponse,
+ })
+ return result
+ },
+ onSuccess: (data, _, __, context) => {
+ context.client.setQueryData(currentUserQuery.queryKey, data.user)
+ context.client.setQueryData(accountsQuery.queryKey, [data.account])
+ },
+})
diff --git a/apps/drive-web/src/routes/login.tsx b/apps/drive-web/src/routes/login.tsx
index f8a0cc9..6ef8475 100644
--- a/apps/drive-web/src/routes/login.tsx
+++ b/apps/drive-web/src/routes/login.tsx
@@ -165,7 +165,8 @@ function LoginForm() {
{isPending ? "Logging in…" : "Login"}
- Don't have an account? Sign up
+ Don't have an account?{" "}
+ Sign up
diff --git a/apps/drive-web/src/routes/sign-up.tsx b/apps/drive-web/src/routes/sign-up.tsx
index 5f50fde..e31a786 100644
--- a/apps/drive-web/src/routes/sign-up.tsx
+++ b/apps/drive-web/src/routes/sign-up.tsx
@@ -3,6 +3,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"
import { GalleryVerticalEnd } from "lucide-react"
import type React from "react"
import { toast } from "sonner"
+import { signUpMutation } from "@/auth/api"
import { Button } from "@/components/ui/button"
import {
Card,
@@ -14,34 +15,21 @@ import {
import {
Field,
FieldDescription,
- FieldError,
FieldGroup,
FieldLabel,
+ FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
-import { type AuthErrorCode, authClient, BetterAuthError } from "../auth"
+import { cn } from "@/lib/utils"
export const Route = createFileRoute("/sign-up")({
- component: SignupPage,
+ component: RouteComponent,
})
-type SignUpParams = {
- displayName: string
- email: string
- password: string
- confirmPassword: string
-}
-
-class PasswordMismatchError extends Error {
- constructor() {
- super("Passwords do not match")
- }
-}
-
-function SignupPage() {
+function RouteComponent() {
return (
-
)
}
-function SignUpFormContainer({ children }: React.PropsWithChildren) {
+function SignupFormCard({ className, ...props }: React.ComponentProps<"div">) {
return (
-
+
-
- Create your account
-
+ Create an account
- Enter your email below to create your account
+ Enter your information below to create your account
- {children}
+
+
+
+
+ By clicking continue, you agree to our{" "}
+ Terms of Service and{" "}
+ Privacy Policy.
+
)
}
@@ -84,20 +75,7 @@ function SignupForm() {
isPending,
error: signUpError,
} = useMutation({
- mutationFn: async (data: SignUpParams) => {
- if (data.password !== data.confirmPassword) {
- throw new PasswordMismatchError()
- }
- const { data: signUpData, error } = await authClient.signUp.email({
- name: data.displayName,
- email: data.email,
- password: data.password,
- })
- if (error) {
- throw new BetterAuthError(error.code as AuthErrorCode)
- }
- return signUpData
- },
+ ...signUpMutation,
onSuccess: () => {
navigate({
to: "/",
@@ -117,43 +95,62 @@ function SignupForm() {
displayName: formData.get("displayName") as string,
email: formData.get("email") as string,
password: formData.get("password") as string,
- confirmPassword: formData.get("confirmPassword") as string,
})
}
- let passwordFieldError = null
- let emailFieldError = null
- if (signUpError instanceof BetterAuthError) {
- switch (signUpError.errorCode) {
- case "PASSWORD_TOO_SHORT":
- passwordFieldError =
- "Password must be at least 8 characters long"
- break
- case "INVALID_EMAIL":
- emailFieldError = "Invalid email address"
- break
- default:
- passwordFieldError = null
- }
- } else if (signUpError instanceof PasswordMismatchError) {
- passwordFieldError = "Passwords do not match"
- }
-
return (