mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-22 21:48:12 -05:00
chore: more wip
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/atoms/Button/Button";
|
||||
import { Input } from "@/components/atoms/Input/Input";
|
||||
import { Link } from "@/components/atoms/Link/Link";
|
||||
import { AuthCard } from "@/components/auth/AuthCard";
|
||||
import AuthFeedback from "@/components/auth/AuthFeedback";
|
||||
import { EmailNotAllowedModal } from "@/components/auth/EmailNotAllowedModal";
|
||||
@@ -61,7 +62,7 @@ export default function LoginPage() {
|
||||
</>
|
||||
) : null}
|
||||
<Form {...form}>
|
||||
<form onSubmit={handleSubmit} className="flex w-full flex-col gap-6">
|
||||
<form onSubmit={handleSubmit} className="flex w-full flex-col gap-1">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
@@ -87,6 +88,11 @@ export default function LoginPage() {
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
error={form.formState.errors.password?.message}
|
||||
hint={
|
||||
<Link variant="secondary" href="/reset-password">
|
||||
Forgot password?
|
||||
</Link>
|
||||
}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -160,7 +160,10 @@ export default function ResetPasswordPage() {
|
||||
<div className="flex h-full min-h-[85vh] flex-col items-center justify-center">
|
||||
<AuthCard title="Reset Password">
|
||||
{user ? (
|
||||
<form onSubmit={changePasswordForm.handleSubmit(onChangePassword)}>
|
||||
<form
|
||||
onSubmit={changePasswordForm.handleSubmit(onChangePassword)}
|
||||
className="flex w-full flex-col gap-1"
|
||||
>
|
||||
<Form {...changePasswordForm}>
|
||||
<FormField
|
||||
control={changePasswordForm.control}
|
||||
@@ -222,7 +225,10 @@ export default function ResetPasswordPage() {
|
||||
</Form>
|
||||
</form>
|
||||
) : (
|
||||
<form onSubmit={sendEmailForm.handleSubmit(onSendEmail)}>
|
||||
<form
|
||||
onSubmit={sendEmailForm.handleSubmit(onSendEmail)}
|
||||
className="flex w-full flex-col gap-1"
|
||||
>
|
||||
<Form {...sendEmailForm}>
|
||||
<FormField
|
||||
control={sendEmailForm.control}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { AuthCard } from "@/components/auth/AuthCard";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
export function LoadingSignup() {
|
||||
return (
|
||||
<div className="flex h-full min-h-[85vh] flex-col items-center justify-center">
|
||||
<AuthCard title="">
|
||||
<Skeleton className="mx-auto h-8 w-48" />
|
||||
<Skeleton className="h-12 w-full rounded-md" />
|
||||
<div className="w-full space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-12" />
|
||||
<Skeleton className="h-12 w-full rounded-md" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-16" />
|
||||
<Skeleton className="h-12 w-full rounded-md" />
|
||||
</div>
|
||||
<Skeleton className="h-16 w-full rounded-md" />
|
||||
<Skeleton className="h-12 w-full rounded-md" />
|
||||
<div className="flex justify-center space-x-1">
|
||||
<Skeleton className="h-4 w-32" />
|
||||
<Skeleton className="h-4 w-12" />
|
||||
</div>
|
||||
</div>
|
||||
</AuthCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import { Button } from "@/components/atoms/Button/Button";
|
||||
import { Input } from "@/components/atoms/Input/Input";
|
||||
import { Link } from "@/components/atoms/Link/Link";
|
||||
import { Text } from "@/components/atoms/Text/Text";
|
||||
import { AuthCard } from "@/components/auth/AuthCard";
|
||||
import AuthFeedback from "@/components/auth/AuthFeedback";
|
||||
import { EmailNotAllowedModal } from "@/components/auth/EmailNotAllowedModal";
|
||||
@@ -15,11 +17,10 @@ import {
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import LoadingBox from "@/components/ui/loading";
|
||||
import { getBehaveAs } from "@/lib/utils";
|
||||
import Link from "next/link";
|
||||
import { WarningOctagonIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import { LoadingSignup } from "./components/LoadingSignup";
|
||||
import { useSignupPage } from "./useSignupPage";
|
||||
|
||||
export default function SignupPage() {
|
||||
@@ -41,7 +42,7 @@ export default function SignupPage() {
|
||||
} = useSignupPage();
|
||||
|
||||
if (isUserLoading || isLoggedIn) {
|
||||
return <LoadingBox className="h-[80vh]" />;
|
||||
return <LoadingSignup />;
|
||||
}
|
||||
|
||||
if (!isSupabaseAvailable) {
|
||||
@@ -52,6 +53,10 @@ export default function SignupPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const confirmPasswordError = form.formState.errors.confirmPassword?.message;
|
||||
const withConfirmPassword = form.getValues("confirmPassword").length > 0;
|
||||
const termsError = form.formState.errors.agreeToTerms?.message;
|
||||
|
||||
return (
|
||||
<div className="flex h-full min-h-[85vh] flex-col items-center justify-center">
|
||||
<AuthCard title="Create a new account">
|
||||
@@ -73,7 +78,7 @@ export default function SignupPage() {
|
||||
) : null}
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={handleSubmit} className="flex w-full flex-col gap-6">
|
||||
<form onSubmit={handleSubmit} className="flex w-full flex-col gap-1">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
@@ -112,16 +117,75 @@ export default function SignupPage() {
|
||||
placeholder="********"
|
||||
type="password"
|
||||
autoComplete="new-password"
|
||||
error={form.formState.errors.confirmPassword?.message}
|
||||
error={confirmPasswordError}
|
||||
{...field}
|
||||
/>
|
||||
<p className="text-sm font-normal leading-tight text-slate-500">
|
||||
Password needs to be at least 12 characters long
|
||||
</p>
|
||||
{!confirmPasswordError && !withConfirmPassword ? (
|
||||
<Text
|
||||
variant="small"
|
||||
className="relative -top-7 !text-slate-500"
|
||||
>
|
||||
Password needs to be at least 12 characters long
|
||||
</Text>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="agreeToTerms"
|
||||
render={({ field }) => (
|
||||
<>
|
||||
<FormItem className="mt-6 flex w-full flex-row items-center -space-y-1 space-x-2">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
className="relative bottom-px"
|
||||
/>
|
||||
</FormControl>
|
||||
<div>
|
||||
<FormLabel className="flex items-center gap-1">
|
||||
<Text
|
||||
variant="body-medium"
|
||||
className="inline-block text-slate-950"
|
||||
>
|
||||
I agree to the
|
||||
</Text>
|
||||
<Link
|
||||
href="https://auto-gpt.notion.site/Terms-of-Use-11400ef5bece80d0b087d7831c5fd6bf"
|
||||
variant="secondary"
|
||||
>
|
||||
Terms of Use
|
||||
</Link>
|
||||
<Text
|
||||
variant="body-medium"
|
||||
className="inline-block text-slate-950"
|
||||
>
|
||||
and
|
||||
</Text>
|
||||
<Link
|
||||
href="https://www.notion.so/auto-gpt/Privacy-Policy-ab11c9c20dbd4de1a15dcffe84d77984"
|
||||
variant="secondary"
|
||||
>
|
||||
Privacy Policy
|
||||
</Link>
|
||||
</FormLabel>
|
||||
</div>
|
||||
</FormItem>
|
||||
{termsError ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<WarningOctagonIcon className="h-4 w-4 text-red-500" />
|
||||
<Text variant="small-medium" className="!text-red-500">
|
||||
{termsError}
|
||||
</Text>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Turnstile CAPTCHA Component */}
|
||||
<Turnstile
|
||||
key={captchaKey}
|
||||
@@ -142,43 +206,6 @@ export default function SignupPage() {
|
||||
>
|
||||
Sign up
|
||||
</Button>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="agreeToTerms"
|
||||
render={({ field }) => (
|
||||
<FormItem className="mt-6 flex flex-row items-start -space-y-1 space-x-2">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<div className="">
|
||||
<FormLabel>
|
||||
<span className="mr-1 text-sm font-normal leading-normal text-slate-950">
|
||||
I agree to the
|
||||
</span>
|
||||
<Link
|
||||
href="https://auto-gpt.notion.site/Terms-of-Use-11400ef5bece80d0b087d7831c5fd6bf"
|
||||
className="text-sm font-normal leading-normal text-slate-950 underline"
|
||||
>
|
||||
Terms of Use
|
||||
</Link>
|
||||
<span className="mx-1 text-sm font-normal leading-normal text-slate-950">
|
||||
and
|
||||
</span>
|
||||
<Link
|
||||
href="https://www.notion.so/auto-gpt/Privacy-Policy-ab11c9c20dbd4de1a15dcffe84d77984"
|
||||
className="text-sm font-normal leading-normal text-slate-950 underline"
|
||||
>
|
||||
Privacy Policy
|
||||
</Link>
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
<AuthFeedback
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Input as BaseInput, type InputProps } from "@/components/ui/input";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ReactNode } from "react";
|
||||
import { Text } from "../Text/Text";
|
||||
import { useInput } from "./useInput";
|
||||
|
||||
@@ -8,6 +9,7 @@ export interface TextFieldProps extends InputProps {
|
||||
hideLabel?: boolean;
|
||||
decimalCount?: number; // Only used for type="amount"
|
||||
error?: string;
|
||||
hint?: ReactNode;
|
||||
}
|
||||
|
||||
export function Input({
|
||||
@@ -16,6 +18,7 @@ export function Input({
|
||||
placeholder,
|
||||
hideLabel = false,
|
||||
decimalCount,
|
||||
hint,
|
||||
error,
|
||||
...props
|
||||
}: TextFieldProps) {
|
||||
@@ -48,13 +51,19 @@ export function Input({
|
||||
);
|
||||
|
||||
const inputWithError = (
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="relative mb-6">
|
||||
{input}
|
||||
{error && (
|
||||
<Text variant="small-medium" as="span" className="!text-red-500">
|
||||
{error}
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
variant="small-medium"
|
||||
as="span"
|
||||
className={cn(
|
||||
"absolute left-0 top-full mt-1 !text-red-500 transition-opacity duration-200",
|
||||
error ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
>
|
||||
{error || " "}{" "}
|
||||
{/* Always render with space to maintain consistent height calculation */}
|
||||
</Text>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -62,9 +71,12 @@ export function Input({
|
||||
inputWithError
|
||||
) : (
|
||||
<label className="flex flex-col gap-2">
|
||||
<Text variant="body-medium" as="span" className="text-black">
|
||||
{label}
|
||||
</Text>
|
||||
<div className="flex items-center justify-between">
|
||||
<Text variant="body-medium" as="span" className="text-black">
|
||||
{label}
|
||||
</Text>
|
||||
{hint}
|
||||
</div>
|
||||
{inputWithError}
|
||||
</label>
|
||||
);
|
||||
|
||||
@@ -19,17 +19,14 @@ AuthCard.BottomText = function BottomText({
|
||||
<div
|
||||
className={cn(
|
||||
className,
|
||||
"mt-8 inline-flex w-full items-center justify-center",
|
||||
"mt-8 inline-flex w-full items-center justify-center gap-1",
|
||||
)}
|
||||
>
|
||||
<span className="text-sm font-medium leading-normal text-slate-950">
|
||||
<Text variant="body-medium" className="text-slate-950">
|
||||
{text}
|
||||
</span>
|
||||
</Text>
|
||||
{link ? (
|
||||
<Link
|
||||
href={link.href}
|
||||
className="ml-1 text-sm font-medium leading-normal text-slate-950 underline"
|
||||
>
|
||||
<Link href={link.href} variant="secondary">
|
||||
{link.text}
|
||||
</Link>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user