Add premium username tag
parent
260f0aaa20
commit
bc6af6ea3d
|
@ -1,5 +1,5 @@
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { ShieldCheckIcon } from "lucide-react";
|
import { Info, Loader2, ShieldCheckIcon, StarIcon } from "lucide-react";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import { signIn } from "next-auth/react";
|
import { signIn } from "next-auth/react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
@ -12,6 +12,7 @@ import { Trans } from "react-i18next";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import getStripe from "@calcom/app-store/stripepayment/lib/client";
|
import getStripe from "@calcom/app-store/stripepayment/lib/client";
|
||||||
|
import { getPremiumPlanPriceValue } from "@calcom/app-store/stripepayment/lib/utils";
|
||||||
import { getOrgFullDomain } from "@calcom/ee/organizations/lib/orgDomains";
|
import { getOrgFullDomain } from "@calcom/ee/organizations/lib/orgDomains";
|
||||||
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
|
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
|
||||||
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
||||||
|
@ -42,12 +43,15 @@ type FormValues = z.infer<typeof signupSchema>;
|
||||||
|
|
||||||
type SignupProps = inferSSRProps<typeof getServerSideProps>;
|
type SignupProps = inferSSRProps<typeof getServerSideProps>;
|
||||||
|
|
||||||
function UsernameField({ ...props }: React.ComponentProps<typeof TextField>) {
|
function UsernameField({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TextField> & { setPremiumExternal?: () => void }) {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const { formState, watch, setError, register } = useFormContext<FormValues>();
|
const { formState, watch, setError, register } = useFormContext<FormValues>();
|
||||||
const { errors } = formState;
|
const { errors } = formState;
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [premium, setPremium] = useState(false);
|
const [premium, setPremium] = useState(false);
|
||||||
|
const [taken, setTaken] = useState(false);
|
||||||
const watchedUsername = watch("username");
|
const watchedUsername = watch("username");
|
||||||
const debouncedUsername = useDebounce(watchedUsername, 500);
|
const debouncedUsername = useDebounce(watchedUsername, 500);
|
||||||
|
|
||||||
|
@ -55,23 +59,20 @@ function UsernameField({ ...props }: React.ComponentProps<typeof TextField>) {
|
||||||
async function checkUsername() {
|
async function checkUsername() {
|
||||||
if (!debouncedUsername) {
|
if (!debouncedUsername) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
setPremium(false);
|
||||||
|
setTaken(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
fetchUsername(debouncedUsername)
|
fetchUsername(debouncedUsername)
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
if (data.premium) {
|
if (data.premium) {
|
||||||
// setError("username", {
|
|
||||||
// type: "manual",
|
|
||||||
// message: t("premium_username_error"),
|
|
||||||
// });
|
|
||||||
setPremium(true);
|
setPremium(true);
|
||||||
|
} else {
|
||||||
|
setPremium(false);
|
||||||
}
|
}
|
||||||
if (!data.available) {
|
if (!data.available) {
|
||||||
setError("username", {
|
setTaken(true);
|
||||||
type: "manual",
|
|
||||||
message: t("already_in_use_error"),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -82,13 +83,31 @@ function UsernameField({ ...props }: React.ComponentProps<typeof TextField>) {
|
||||||
}, [debouncedUsername, t, setError]);
|
}, [debouncedUsername, t, setError]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div>
|
||||||
<TextField {...props} {...register("username")} hintErrors={["premium"]} />
|
<TextField {...props} {...register("username")} />
|
||||||
<div className="text-gray text-default flex items-center text-sm">
|
<div className="text-gray text-default flex items-center text-sm">
|
||||||
{loading && <span className="text-default mr-2 h-4 w-4 animate-spin">⏳</span>}
|
<p className="flex items-center text-sm ">
|
||||||
{errors.username?.message}
|
{loading ? (
|
||||||
|
<>
|
||||||
|
<Loader2 className="mr-1 inline-block h-4 w-4 animate-spin" />
|
||||||
|
{t("loading")}
|
||||||
|
</>
|
||||||
|
) : taken ? (
|
||||||
|
<div className="text-error">
|
||||||
|
<Info className="mr-1 inline-block h-4 w-4" />
|
||||||
|
{t("already_taken")}
|
||||||
|
</div>
|
||||||
|
) : premium ? (
|
||||||
|
<>
|
||||||
|
<StarIcon className="mr-1 inline-block h-4 w-4" />
|
||||||
|
{t("premium_username", {
|
||||||
|
price: getPremiumPlanPriceValue(),
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1138,6 +1138,7 @@
|
||||||
"active_on": "Active on",
|
"active_on": "Active on",
|
||||||
"workflow_updated_successfully": "{{workflowName}} workflow updated successfully",
|
"workflow_updated_successfully": "{{workflowName}} workflow updated successfully",
|
||||||
"premium_to_standard_username_description": "This is a standard username and updating will take you to billing to downgrade.",
|
"premium_to_standard_username_description": "This is a standard username and updating will take you to billing to downgrade.",
|
||||||
|
"premium_username": "This is a premium username, get yours for {{price}}",
|
||||||
"current": "Current",
|
"current": "Current",
|
||||||
"premium": "premium",
|
"premium": "premium",
|
||||||
"standard": "standard",
|
"standard": "standard",
|
||||||
|
|
Loading…
Reference in New Issue