-
Notifications
You must be signed in to change notification settings - Fork 13
chore: enable credential auth #746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,9 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "use client"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { zodResolver } from "@hookform/resolvers/zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useForm } from "react-hook-form"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { z } from "zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { authClient } from "~/api/auth-client"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Button } from "~/components/ui/button"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -9,14 +13,104 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CardHeader, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CardTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from "~/components/ui/card"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Form, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FormControl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FormField, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FormItem, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FormLabel, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FormMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from "~/components/ui/form"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Input } from "~/components/ui/input"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Separator } from "~/components/ui/separator"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const signInGoogle = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void authClient.signIn.social({ provider: "google" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function LoginSeparator() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center gap-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Separator className="flex-1" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-sm text-muted-foreground">or</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Separator className="flex-1" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const signInEmailPasswordSchema = z.object({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| email: z.string().email(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| password: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function LoginEmailPassword() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const form = useForm<z.infer<typeof signInEmailPasswordSchema>>({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolver: zodResolver(signInEmailPasswordSchema), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultValues: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| email: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| password: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const onSubmit = (data: z.infer<typeof signInEmailPasswordSchema>) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void authClient.signIn.email({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...data, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rememberMe: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| callbackURL: "/workspaces", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Form {...form}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormField | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| control={form.control} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name="email" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| render={({ field }) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormLabel>Email</FormLabel> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormControl> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Input {...field} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </FormControl> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormMessage /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </FormItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormField | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| control={form.control} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name="password" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| render={({ field }) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormLabel>Password</FormLabel> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormControl> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Input {...field} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </FormControl> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+66
to
+87
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Password field renders as plain text. 🔒 Proposed fix- <Input {...field} />
+ <Input type="email" autoComplete="email" {...field} />
@@
- <Input {...field} />
+ <Input
+ type="password"
+ autoComplete="current-password"
+ {...field}
+ />📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <FormMessage /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </FormItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="space-y-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Button type="submit" className="w-full"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sign in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-xs text-muted-foreground"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Don't have an account?{" "} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| href="/sign-up" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className="cursor-pointer text-primary underline" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sign up | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Form> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function Login() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-background via-background to-muted/20 p-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="bg-linear-to-br flex min-h-screen items-center justify-center from-background via-background to-muted/20 p-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="mx-auto w-full" style={{ maxWidth: "400px" }}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* Logo */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="mb-6 flex items-center justify-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -75,6 +169,8 @@ export default function Login() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span>Continue with Google</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <LoginSeparator /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <LoginEmailPassword /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </CardContent> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Card> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,143 @@ | ||||||||||||||||||
| import { zodResolver } from "@hookform/resolvers/zod"; | ||||||||||||||||||
| import { useForm } from "react-hook-form"; | ||||||||||||||||||
| import { z } from "zod"; | ||||||||||||||||||
|
Comment on lines
+1
to
+3
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Find the signup and login files
fd -t f "signup\.(ts|tsx)" apps/web
fd -t f "login\.(ts|tsx)" apps/webRepository: ctrlplanedev/ctrlplane Length of output: 136 🏁 Script executed: # Check the signup file content
cat -n apps/web/app/routes/auth/signup.tsx | head -50
# Check the login file content for comparison
cat -n apps/web/app/routes/auth/login.tsx | head -50Repository: ctrlplanedev/ctrlplane Length of output: 3244 🏁 Script executed: # Get full signup.tsx to see if there are other client-side features
wc -l apps/web/app/routes/auth/signup.tsx
# Check what the Form component is and if it requires client
rg "export.*Form" apps/web/app/components/ui/form -A 3Repository: ctrlplanedev/ctrlplane Length of output: 194 🏁 Script executed: # Find the Form component
fd -t f "form\.(ts|tsx)" apps/web/app/components
# Also check the structure
ls -la apps/web/app/components/ui/ | head -20Repository: ctrlplanedev/ctrlplane Length of output: 1291 🏁 Script executed: # Check the form.tsx file
cat -n apps/web/app/components/ui/form.tsx | head -30Repository: ctrlplanedev/ctrlplane Length of output: 1115 🏁 Script executed: # Verify the structure - is signup.tsx in app router context?
cat -n apps/web/app/routes/auth/signup.tsx | tail -50
# Also check if signup is exported as a default component
grep -n "export" apps/web/app/routes/auth/signup.tsx | head -10Repository: ctrlplanedev/ctrlplane Length of output: 2135 🏁 Script executed: # Check if there's a pattern in the codebase - do other route components have "use client"?
fd -t f "\.tsx$" apps/web/app/routes --exec head -1 {} + | grep -B 1 "use client" | head -20
# Check the app structure - is there a layout.tsx?
cat -n apps/web/app/layout.tsx | head -20Repository: ctrlplanedev/ctrlplane Length of output: 6966 🏁 Script executed: # Check app structure
find apps/web/app -name "layout.tsx" -type f
# Also check for global configuration that might make routes client by default
rg "use client" apps/web/app --files-with-matches | head -10Repository: ctrlplanedev/ctrlplane Length of output: 456 🏁 Script executed: # Check if there's a custom useForm or form initialization pattern in ctrlplane
rg "useForm.*schema:" apps/web --context 3 | head -30
# Also check the signup form more carefully
grep -n "const form = " apps/web/app/routes/auth/signup.tsx -A 5Repository: ctrlplanedev/ctrlplane Length of output: 253 Add This file uses the Proposed fix+"use client";
+
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| import { authClient } from "~/api/auth-client"; | ||||||||||||||||||
| import { Button } from "~/components/ui/button"; | ||||||||||||||||||
| import { | ||||||||||||||||||
| Card, | ||||||||||||||||||
| CardContent, | ||||||||||||||||||
| CardDescription, | ||||||||||||||||||
| CardHeader, | ||||||||||||||||||
| CardTitle, | ||||||||||||||||||
| } from "~/components/ui/card"; | ||||||||||||||||||
| import { | ||||||||||||||||||
| Form, | ||||||||||||||||||
| FormControl, | ||||||||||||||||||
| FormField, | ||||||||||||||||||
| FormItem, | ||||||||||||||||||
| FormLabel, | ||||||||||||||||||
| FormMessage, | ||||||||||||||||||
| } from "~/components/ui/form"; | ||||||||||||||||||
| import { Input } from "~/components/ui/input"; | ||||||||||||||||||
|
|
||||||||||||||||||
| const signUpSchema = z.object({ | ||||||||||||||||||
| name: z.string().min(1, "Name is required"), | ||||||||||||||||||
| email: z.string().email("Invalid email address"), | ||||||||||||||||||
| password: z.string().min(8, "Password must be at least 8 characters"), | ||||||||||||||||||
| }); | ||||||||||||||||||
|
|
||||||||||||||||||
| function SignupForm() { | ||||||||||||||||||
| const form = useForm<z.infer<typeof signUpSchema>>({ | ||||||||||||||||||
| resolver: zodResolver(signUpSchema), | ||||||||||||||||||
| defaultValues: { | ||||||||||||||||||
| name: "", | ||||||||||||||||||
| email: "", | ||||||||||||||||||
| password: "", | ||||||||||||||||||
| }, | ||||||||||||||||||
| }); | ||||||||||||||||||
|
|
||||||||||||||||||
| const onSubmit = async (data: z.infer<typeof signUpSchema>) => { | ||||||||||||||||||
| const { error } = await authClient.signUp.email({ ...data }); | ||||||||||||||||||
| if (!error) window.location.href = "/workspaces"; | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
||||||||||||||||||
| return ( | ||||||||||||||||||
| <Form {...form}> | ||||||||||||||||||
| <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> | ||||||||||||||||||
| <FormField | ||||||||||||||||||
| control={form.control} | ||||||||||||||||||
| name="name" | ||||||||||||||||||
| render={({ field }) => ( | ||||||||||||||||||
| <FormItem> | ||||||||||||||||||
| <FormLabel>Name</FormLabel> | ||||||||||||||||||
| <FormControl> | ||||||||||||||||||
| <Input {...field} /> | ||||||||||||||||||
| </FormControl> | ||||||||||||||||||
| <FormMessage /> | ||||||||||||||||||
| </FormItem> | ||||||||||||||||||
| )} | ||||||||||||||||||
| /> | ||||||||||||||||||
| <FormField | ||||||||||||||||||
| control={form.control} | ||||||||||||||||||
| name="email" | ||||||||||||||||||
| render={({ field }) => ( | ||||||||||||||||||
| <FormItem> | ||||||||||||||||||
| <FormLabel>Email</FormLabel> | ||||||||||||||||||
| <FormControl> | ||||||||||||||||||
| <Input {...field} /> | ||||||||||||||||||
| </FormControl> | ||||||||||||||||||
| <FormMessage /> | ||||||||||||||||||
| </FormItem> | ||||||||||||||||||
| )} | ||||||||||||||||||
| /> | ||||||||||||||||||
| <FormField | ||||||||||||||||||
| control={form.control} | ||||||||||||||||||
| name="password" | ||||||||||||||||||
| render={({ field }) => ( | ||||||||||||||||||
| <FormItem> | ||||||||||||||||||
| <FormLabel>Password</FormLabel> | ||||||||||||||||||
| <FormControl> | ||||||||||||||||||
| <Input type="password" {...field} /> | ||||||||||||||||||
| </FormControl> | ||||||||||||||||||
| <FormMessage /> | ||||||||||||||||||
| </FormItem> | ||||||||||||||||||
| )} | ||||||||||||||||||
| /> | ||||||||||||||||||
| <div className="space-y-2"> | ||||||||||||||||||
| <Button type="submit" className="w-full"> | ||||||||||||||||||
| Sign up | ||||||||||||||||||
| </Button> | ||||||||||||||||||
| <span className="text-xs text-muted-foreground"> | ||||||||||||||||||
| Already have an account?{" "} | ||||||||||||||||||
| <a href="/login" className="cursor-pointer text-primary underline"> | ||||||||||||||||||
| Sign in | ||||||||||||||||||
| </a> | ||||||||||||||||||
| </span> | ||||||||||||||||||
| </div> | ||||||||||||||||||
| </form> | ||||||||||||||||||
| </Form> | ||||||||||||||||||
| ); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| export default function Signup() { | ||||||||||||||||||
| return <div>Signup</div>; | ||||||||||||||||||
| return ( | ||||||||||||||||||
| <div className="bg-linear-to-br flex min-h-screen items-center justify-center from-background via-background to-muted/20 p-4"> | ||||||||||||||||||
| <div className="mx-auto w-full" style={{ maxWidth: "400px" }}> | ||||||||||||||||||
| <div className="mb-6 flex items-center justify-center"> | ||||||||||||||||||
| <div className="relative flex h-16 w-16 items-center justify-center rounded-full bg-primary/10 p-3"> | ||||||||||||||||||
| <svg | ||||||||||||||||||
| viewBox="0 0 24 24" | ||||||||||||||||||
| fill="none" | ||||||||||||||||||
| stroke="currentColor" | ||||||||||||||||||
| strokeWidth="2" | ||||||||||||||||||
| strokeLinecap="round" | ||||||||||||||||||
| strokeLinejoin="round" | ||||||||||||||||||
| className="h-10 w-10 text-primary transition-all" | ||||||||||||||||||
| > | ||||||||||||||||||
| <path d="M12 2L2 7l10 5 10-5-10-5z" /> | ||||||||||||||||||
| <path d="M2 17l10 5 10-5" /> | ||||||||||||||||||
| <path d="M2 12l10 5 10-5" /> | ||||||||||||||||||
| </svg> | ||||||||||||||||||
| <div className="absolute inset-0 animate-pulse rounded-full border border-primary/20"></div> | ||||||||||||||||||
| </div> | ||||||||||||||||||
| </div> | ||||||||||||||||||
|
|
||||||||||||||||||
| <Card className="overflow-hidden border-border/30 bg-card/60 shadow-xl backdrop-blur-sm"> | ||||||||||||||||||
| <CardHeader className="space-y-1"> | ||||||||||||||||||
| <CardTitle className="text-center text-2xl"> | ||||||||||||||||||
| Welcome to Ctrlplane | ||||||||||||||||||
| </CardTitle> | ||||||||||||||||||
| <CardDescription className="text-center"> | ||||||||||||||||||
| Create an account to continue | ||||||||||||||||||
| </CardDescription> | ||||||||||||||||||
| </CardHeader> | ||||||||||||||||||
|
|
||||||||||||||||||
| <CardContent className="space-y-6 px-6"> | ||||||||||||||||||
| <SignupForm /> | ||||||||||||||||||
| </CardContent> | ||||||||||||||||||
| </Card> | ||||||||||||||||||
| </div> | ||||||||||||||||||
| </div> | ||||||||||||||||||
| ); | ||||||||||||||||||
| } | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 205
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 3334
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 3497
🏁 Script executed:
# Examine the auth-client implementation cat -n apps/web/app/api/auth-client.tsRepository: ctrlplanedev/ctrlplane
Length of output: 291
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 109
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 788
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 1000
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 244
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
Repository: ctrlplanedev/ctrlplane
Length of output: 48
Handle sign‑in errors instead of fire‑and‑forget.
Line 55–61 discards the promise without error handling, creating silent failures and unhandled rejections. The same library (
better-auth) is properly awaited insignup.tsx, and coding guidelines prefer async/await with explicit error handling.🐛 Suggested fix with async/await + user feedback
🤖 Prompt for AI Agents