Fix signup jumping around

pull/11421/merge^2
Sean Brydon 2023-09-21 10:38:49 +01:00
parent 9d53103fe9
commit 04f7bdb918
2 changed files with 48 additions and 28 deletions

View File

@ -1,5 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { CalendarHeart, Clock, Info, Loader2, ShieldCheckIcon, StarIcon } from "lucide-react";
import { CalendarHeart, Clock, Info, ShieldCheckIcon, StarIcon } from "lucide-react";
import type { GetServerSidePropsContext } from "next";
import { signIn } from "next-auth/react";
import Link from "next/link";
@ -19,7 +19,7 @@ import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
import { useFlagMap } from "@calcom/features/flags/context/provider";
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
import { classNames } from "@calcom/lib";
import { IS_CALCOM, IS_SELF_HOSTED, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
import { APP_NAME, IS_CALCOM, IS_SELF_HOSTED, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
import { fetchUsername } from "@calcom/lib/fetchUsername";
import { useDebounce } from "@calcom/lib/hooks/useDebounce";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@ -59,35 +59,33 @@ const FEATURES = [
description: "schedule_for_your_team_description",
icon: Clock,
},
{
title: "scheduling_for_your_team",
description: "schedule_for_your_team_description",
icon: Clock,
},
];
function UsernameField({
username,
setPremium,
premium,
setUsernameTaken,
usernameTaken,
...props
}: React.ComponentProps<typeof TextField> & {
username: string;
setPremium: (value: boolean) => void;
premium: boolean;
usernameTaken: boolean;
setUsernameTaken: (value: boolean) => void;
}) {
const { t } = useLocale();
const { watch, register, formState } = useFormContext<FormValues>();
const [taken, setTaken] = useState(false);
const { register, formState } = useFormContext<FormValues>();
const [loading, setLoading] = useState(false);
const debouncedUsername = useDebounce(username, 500);
const debouncedUsername = useDebounce(username, 700);
useEffect(() => {
async function checkUsername() {
if (!debouncedUsername) {
setLoading(false);
setPremium(false);
setTaken(false);
setUsernameTaken(false);
return;
}
setLoading(true);
@ -95,7 +93,7 @@ function UsernameField({
.then(({ data }) => {
setPremium(data.premium);
if (!data.available) {
setTaken(true);
setUsernameTaken(true);
}
})
.finally(() => {
@ -103,23 +101,23 @@ function UsernameField({
});
}
checkUsername();
}, [debouncedUsername, setPremium, setTaken]);
}, [debouncedUsername, setPremium, setUsernameTaken]);
return (
<div>
<TextField {...props} {...register("username")} data-testid="signup-usernamefield" />
<TextField
{...props}
{...register("username")}
data-testid="signup-usernamefield"
addOnFilled={false}
/>
{!formState.isSubmitting && (
<div className="text-gray text-default flex items-center text-sm">
<p className="flex items-center text-sm ">
{loading ? (
<>
<Loader2 className="mr-1 inline-block h-4 w-4 animate-spin" />
{t("loading")}
</>
) : taken ? (
{usernameTaken ? (
<div className="text-error">
<Info className="mr-1 inline-block h-4 w-4" />
{t("already_taken")}
{t("already_in_use_error")}
</div>
) : premium ? (
<div data-testid="premium-username-warning">
@ -138,6 +136,7 @@ function UsernameField({
export default function Signup({ prepopulateFormValues, token, orgSlug }: SignupProps) {
const [premiumUsername, setPremiumUsername] = useState(false);
const [usernameTaken, setUsernameTaken] = useState(false);
const searchParams = useSearchParams();
const telemetry = useTelemetry();
@ -228,7 +227,9 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
<p className="text-subtle text-base font-medium leading-none">{t("cal_signup_description")}</p>
) : (
<p className="text-subtle text-base font-medium leading-none">
Meet all your scheduling needs{" "}
{t("calcom_explained", {
appName: APP_NAME,
})}
</p>
)}
</div>
@ -245,6 +246,8 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
label={t("username")}
username={watch("username")}
premium={premiumUsername}
usernameTaken={usernameTaken}
setUsernameTaken={(value) => setUsernameTaken(value)}
data-testid="signup-usernamefield"
setPremium={(value) => setPremiumUsername(value)}
addOnLeading={
@ -268,8 +271,18 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
{...register("password")}
hintErrors={["caplow", "min", "num"]}
/>
<Button type="submit" className="my-2 w-full justify-center" loading={isSubmitting}>
{premiumUsername ? `Create Account for ${getPremiumPlanPriceValue()}` : t("create_account")}
<Button
type="submit"
className="my-2 w-full justify-center"
loading={isSubmitting}
disabled={
!!formMethods.formState.errors.username ||
!!formMethods.formState.errors.email ||
usernameTaken
}>
{premiumUsername && !usernameTaken
? `Create Account for ${getPremiumPlanPriceValue()}`
: t("create_account")}
</Button>
</Form>
{/* Continue with Social Logins */}
@ -283,7 +296,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
</div>
</div>
{/* Social Logins */}
<div className="mt-6 grid gap-2 lg:grid-cols-2">
<div className="mt-6 grid gap-2 md:grid-cols-2">
<Button
color="secondary"
disabled={!!formMethods.formState.errors.username}
@ -363,15 +376,21 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
</div>
<div className="bg-subtle border-subtle my-6 hidden w-full flex-col justify-center rounded-l-2xl py-12 pl-12 lg:flex">
<img src="/mock-event-type-list.svg" alt="#" />
<div className="mr-12 mt-4 grid h-full w-full grid-cols-2 gap-4 overflow-hidden">
<div className="mr-12 mt-4 grid h-full w-full grid-cols-3 gap-4 overflow-hidden">
{FEATURES.map((feature) => (
<>
<div className="flex flex-col leading-none">
<div className="text-emphasis flex items-center gap-1">
<div className="text-emphasis items-center gap-1">
<feature.icon className="h-4 w-4 " />
<span className="text-sm font-medium">{t(feature.title)}</span>
</div>
<p className="text-subtle text-sm">{t(feature.description)}</p>
<div className="text-subtle text-sm">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse auctor justo nec
est ultricies, sed auctor mauris iaculis. Pellentesque consectetur metus sed nunc
bibendum,
</p>
</div>
</div>
</>
))}

View File

@ -1519,6 +1519,7 @@
"or_continue_with": "Or continue with",
"resend_email": "Resend email",
"member_already_invited": "Member has already been invited",
"already_in_use_error": "Username already in use",
"enter_email_or_username": "Enter an email or username",
"team_name_taken": "This name is already taken",
"must_enter_team_name": "Must enter a team name",