fix: signup nit (#12585)
* Disable submit on empty form * Fix submit --------- Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
co-authored by
Peer Richelsen
parent
b840b3b1bb
commit
a75ef8870b
+46
-27
@@ -122,21 +122,23 @@ function UsernameField({
|
||||
/>
|
||||
{(!formState.isSubmitting || !formState.isSubmitted) && (
|
||||
<div className="text-gray text-default flex items-center text-sm">
|
||||
<p className="flex items-center text-sm ">
|
||||
<div className="text-sm ">
|
||||
{usernameTaken ? (
|
||||
<div className="text-error">
|
||||
<div className="text-error flex items-center">
|
||||
<Info className="mr-1 inline-block h-4 w-4" />
|
||||
{t("already_in_use_error")}
|
||||
<p>{t("already_in_use_error")}</p>
|
||||
</div>
|
||||
) : premium ? (
|
||||
<div data-testid="premium-username-warning">
|
||||
<div data-testid="premium-username-warning" className="flex items-center">
|
||||
<StarIcon className="mr-1 inline-block h-4 w-4" />
|
||||
{t("premium_username", {
|
||||
price: getPremiumPlanPriceValue(),
|
||||
})}
|
||||
<p>
|
||||
{t("premium_username", {
|
||||
price: getPremiumPlanPriceValue(),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -161,6 +163,7 @@ export default function Signup({
|
||||
}: SignupProps) {
|
||||
const [premiumUsername, setPremiumUsername] = useState(false);
|
||||
const [usernameTaken, setUsernameTaken] = useState(false);
|
||||
const [isGoogleLoading, setIsGoogleLoading] = useState(false);
|
||||
|
||||
const searchParams = useCompatSearchParams();
|
||||
const telemetry = useTelemetry();
|
||||
@@ -245,21 +248,21 @@ export default function Signup({
|
||||
"--cal-brand-subtle": "#9CA3AF",
|
||||
} as CSSProperties
|
||||
}>
|
||||
<div className="bg-muted 2xl:border-subtle grid max-h-[800px] w-full max-w-[1440px] grid-cols-1 grid-rows-1 lg:grid-cols-2 2xl:rounded-lg 2xl:border ">
|
||||
<div className="bg-muted 2xl:border-subtle grid w-full max-w-[1440px] grid-cols-1 grid-rows-1 lg:grid-cols-2 2xl:rounded-[20px] 2xl:border 2xl:py-6">
|
||||
<HeadSeo title={t("sign_up")} description={t("sign_up")} />
|
||||
<div className="flex w-full flex-col px-4 py-6 sm:px-16 md:px-24 2xl:px-28">
|
||||
<div className="flex w-full flex-col px-4 pt-6 sm:px-16 md:px-20 2xl:px-28">
|
||||
{/* Header */}
|
||||
{errors.apiError && (
|
||||
<Alert severity="error" message={errors.apiError?.message} data-testid="signup-error-message" />
|
||||
)}
|
||||
<div className="flex flex-col gap-1">
|
||||
<h1 className="font-cal text-[28px] ">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="font-cal text-[28px] leading-none ">
|
||||
{IS_CALCOM ? t("create_your_calcom_account") : t("create_your_account")}
|
||||
</h1>
|
||||
{IS_CALCOM ? (
|
||||
<p className="text-subtle text-base font-medium leading-6">{t("cal_signup_description")}</p>
|
||||
<p className="text-subtle text-base font-medium leading-5">{t("cal_signup_description")}</p>
|
||||
) : (
|
||||
<p className="text-subtle text-base font-medium leading-6">
|
||||
<p className="text-subtle text-base font-medium leading-5">
|
||||
{t("calcom_explained", {
|
||||
appName: APP_NAME,
|
||||
})}
|
||||
@@ -318,6 +321,8 @@ export default function Signup({
|
||||
disabled={
|
||||
!!formMethods.formState.errors.username ||
|
||||
!!formMethods.formState.errors.email ||
|
||||
!formMethods.getValues("email") ||
|
||||
!formMethods.getValues("password") ||
|
||||
usernameTaken
|
||||
}>
|
||||
{premiumUsername && !usernameTaken
|
||||
@@ -344,11 +349,22 @@ export default function Signup({
|
||||
<Button
|
||||
color="secondary"
|
||||
disabled={!!formMethods.formState.errors.username || premiumUsername}
|
||||
loading={isGoogleLoading}
|
||||
StartIcon={() => (
|
||||
<>
|
||||
<img
|
||||
className={classNames("text-subtle mr-2 h-4 w-4", premiumUsername && "opacity-50")}
|
||||
src="/google-icon.svg"
|
||||
alt=""
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
className={classNames(
|
||||
"w-full justify-center rounded-md text-center",
|
||||
formMethods.formState.errors.username ? "opacity-50" : ""
|
||||
)}
|
||||
onClick={async () => {
|
||||
setIsGoogleLoading(true);
|
||||
const username = formMethods.getValues("username");
|
||||
const baseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL;
|
||||
const GOOGLE_AUTH_URL = `${baseUrl}/auth/sso/google`;
|
||||
@@ -362,11 +378,6 @@ export default function Signup({
|
||||
}
|
||||
router.push(GOOGLE_AUTH_URL);
|
||||
}}>
|
||||
<img
|
||||
className={classNames("text-emphasis mr-2 h-5 w-5", premiumUsername && "opacity-50")}
|
||||
src="/google-icon.svg"
|
||||
alt=""
|
||||
/>
|
||||
Google
|
||||
</Button>
|
||||
) : null}
|
||||
@@ -410,17 +421,20 @@ export default function Signup({
|
||||
)}
|
||||
</div>
|
||||
{/* Already have an account & T&C */}
|
||||
<div className="mt-6">
|
||||
<div className="mt-10 flex h-full flex-col justify-end text-xs">
|
||||
<div className="flex flex-col text-sm">
|
||||
<Link href="/auth/login" className="text-emphasis hover:underline">
|
||||
{t("already_have_account")}
|
||||
</Link>
|
||||
<div className="flex gap-1">
|
||||
<p className="text-subtle">{t("already_have_account")}</p>
|
||||
<Link href="/auth/login" className="text-emphasis hover:underline">
|
||||
{t("sign_in")}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="text-subtle">
|
||||
By signing up, you agree to our{" "}
|
||||
<Link className="text-emphasis hover:underline" href={`${WEBSITE_URL}/terms`}>
|
||||
Terms of Service{" "}
|
||||
Terms{" "}
|
||||
</Link>
|
||||
<span>and</span>{" "}
|
||||
<span>&</span>{" "}
|
||||
<Link className="text-emphasis hover:underline" href={`${WEBSITE_URL}/privacy`}>
|
||||
Privacy Policy.
|
||||
</Link>
|
||||
@@ -428,7 +442,12 @@ export default function Signup({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-subtle border-subtle hidden w-full flex-col justify-between rounded-l-2xl py-12 pl-12 lg:flex">
|
||||
<div
|
||||
className="border-subtle hidden w-full flex-col justify-between rounded-l-2xl border py-12 pl-12 lg:flex"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(162.05% 170% at 109.58% 35%, rgba(102, 117, 147, 0.7) 0%, rgba(212, 212, 213, 0.4) 100%) ",
|
||||
}}>
|
||||
{IS_CALCOM && (
|
||||
<div className="mb-12 mr-12 grid h-full w-full grid-cols-4 gap-4 ">
|
||||
<div className="">
|
||||
@@ -443,7 +462,7 @@ export default function Signup({
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="rounded-2xl border-y border-l border-dashed border-[#D1D5DB5A] py-[6px] pl-[6px]"
|
||||
className="border-default rounded-bl-2xl rounded-br-none rounded-tl-2xl border-dashed py-[6px] pl-[6px]"
|
||||
style={{
|
||||
backgroundColor: "rgba(236,237,239,0.9)",
|
||||
}}>
|
||||
|
||||
@@ -48,8 +48,6 @@ test.describe("Organization", () => {
|
||||
await newPage.waitForLoadState("networkidle");
|
||||
|
||||
// Check required fields
|
||||
await newPage.locator("button[type=submit]").click();
|
||||
await expect(newPage.locator(".text-red-700")).toHaveCount(3); // 3 password hints
|
||||
await newPage.locator("input[name=password]").fill(`P4ssw0rd!`);
|
||||
await newPage.locator("button[type=submit]").click();
|
||||
await newPage.waitForURL("/getting-started?from=signup");
|
||||
@@ -78,8 +76,8 @@ test.describe("Organization", () => {
|
||||
await inviteLinkPage.waitForLoadState("networkidle");
|
||||
|
||||
// Check required fields
|
||||
await inviteLinkPage.locator("button[type=submit]").click();
|
||||
await expect(inviteLinkPage.locator(".text-red-700")).toHaveCount(4); // email + 3 password hints
|
||||
const button = inviteLinkPage.locator("button[type=submit][disabled]");
|
||||
await expect(button).toBeVisible(); // email + 3 password hints
|
||||
|
||||
// Happy path
|
||||
await inviteLinkPage.locator("input[name=email]").fill(`rick@domain-${Date.now()}.com`);
|
||||
|
||||
@@ -51,8 +51,10 @@ test.describe("Team", () => {
|
||||
await newPage.waitForLoadState("networkidle");
|
||||
|
||||
// Check required fields
|
||||
await newPage.locator("button[type=submit]").click();
|
||||
await expect(newPage.locator('[data-testid="hint-error"]')).toHaveCount(3);
|
||||
const button = newPage.locator("button[type=submit][disabled]");
|
||||
await expect(button).toBeVisible(); // email + 3 password hints
|
||||
|
||||
// Check required fields
|
||||
await newPage.locator("input[name=password]").fill(`P4ssw0rd!`);
|
||||
await newPage.locator("button[type=submit]").click();
|
||||
await newPage.waitForURL("/getting-started?from=signup");
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"cannot_repackage_codebase": "You can not repackage or sell the codebase",
|
||||
"acquire_license": "Acquire a commercial license to remove these terms by emailing",
|
||||
"terms_summary": "Summary of terms",
|
||||
"signing_up_terms":"By signing up, you agree to our <2>Terms of Service</2> and <3>Privacy Policy</3>.",
|
||||
"signing_up_terms":"By signing up you agree to our <2>Terms</2> & <3>Privacy Policy</3>.",
|
||||
"open_env": "Open .env and agree to our License",
|
||||
"env_changed": "I've changed my .env",
|
||||
"accept_license": "Accept License",
|
||||
@@ -1607,7 +1607,7 @@
|
||||
"enable_apps": "Enable Apps",
|
||||
"enable_apps_description": "Enable apps that users can integrate with {{appName}}",
|
||||
"purchase_license": "Purchase a License",
|
||||
"already_have_account":"I already have an account",
|
||||
"already_have_account":"Already have an account?",
|
||||
"already_have_key": "I already have a key:",
|
||||
"already_have_key_suggestion": "Please copy your existing CALCOM_LICENSE_KEY environment variable here.",
|
||||
"app_is_enabled": "{{appName}} is enabled",
|
||||
|
||||
Reference in New Issue
Block a user