history#createLocation TypeScript Examples

The following examples show how to use history#createLocation. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: router.ts    From che-dashboard-next with Eclipse Public License 2.0 6 votes vote down vote up
getMockRouterProps = <Params extends { [K in keyof Params]: string } = {}>(path: string, params: Params): {
  history: MemoryHistory<LocationState>;
  location: Location<LocationState>;
  match: routerMatch<Params>
} => {
  const isExact = false;
  const url = generateUrl(path, params);

  const match: routerMatch<Params> = { isExact, path, url, params };
  const history = createMemoryHistory();
  const location = createLocation(match.url);

  return { history, location, match };
}
Example #2
Source File: index.ts    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
protected _render(): void {
    // istanbul ignore else
    if (this.isConnected) {
      const history = getHistory();
      const currentLocation = { ...history.location };
      const toHref = this.useHref2 ? this.href2 : this.href;
      const toLocation = createLocation(toHref);

      delete currentLocation.key;

      if (!locationsAreEqual(currentLocation, toLocation)) {
        history.replace(toHref);
      }
    }
  }
Example #3
Source File: GeneralLogin.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
redirect = async (
    result: Record<string, any>,
    onLogin?: GeneralLoginProps["onLogin"]
  ): Promise<void> => {
    const runtime = getRuntime();
    runtime.reloadSharedData();
    await runtime.reloadMicroApps();
    resetLegacyIframe();

    authenticate({
      org: result.org,
      username: result.username,
      userInstanceId: result.userInstanceId,
      accessRule: result.accessRule,
      isAdmin: result.isAdmin,
    });
    const { state } = getHistory().location;
    const from =
      state && state.from
        ? state.from
        : {
            pathname: "/",
          };
    const redirect = createLocation(from);
    if (onLogin) {
      onLogin({ redirect });
    } else {
      getHistory().push(redirect);
    }
  };
Example #4
Source File: GeneralSignup.spec.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
jest.spyOn(kit, "getHistory").mockReturnValue({
  location: {
    state: {
      from: createLocation("/mock-from"),
    },
  },
  push: spyOnHistoryPush,
  createHref: jest.fn(),
} as any);
Example #5
Source File: GeneralLogin.spec.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
jest.spyOn(kit, "getHistory").mockReturnValue({
  location: {
    state: {
      from: createLocation("/mock-from"),
    },
  },
  push: spyOnHistoryPush,
} as any);
Example #6
Source File: URLParser.test.ts    From kfp-tekton-backend with Apache License 2.0 5 votes vote down vote up
location = createLocation('/')
Example #7
Source File: amount.spec.tsx    From bitpay-browser-extension with MIT License 4 votes vote down vote up
describe('Amount Page', () => {
  let path: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  let history: any;
  let matchObj: match<{ id: string }>;
  let location;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  let wrapper: any;
  beforeEach(() => {
    path = '/amount/:brand';
    history = createMemoryHistory();

    matchObj = {
      isExact: false,
      path,
      url: path.replace(':brand', 'amazon'),
      params: { id: 'amazon' }
    };
    location = createLocation(path, { cardConfig: CardConfigData, merchant: MerchantData });

    wrapper = shallow(
      <Amount
        clientId={AmountProps.clientId}
        email={AmountProps.email}
        purchasedGiftCards={AmountProps.purchasedGiftCards}
        setPurchasedGiftCards={AmountProps.setPurchasedGiftCards}
        history={history}
        location={location}
        match={matchObj}
      />
    );
  });

  it('should create the component', () => {
    expect(wrapper.exists()).toBeTruthy();
  });

  it('should validate input value', () => {
    const inputText = [
      { value: 'alphabetic', expectedInputVal: '', expectedInputDivVal: '0' },
      { value: '12', expectedInputVal: '12', expectedInputDivVal: '12' },
      { value: '40.013', expectedInputVal: '40.01', expectedInputDivVal: '40.01' },
      { value: '200.11', expectedInputVal: '200.11', expectedInputDivVal: '200.11' },
      { value: '0.11', expectedInputVal: '0.11', expectedInputDivVal: '0.11' },
      { value: '4000', expectedInputVal: '', expectedInputDivVal: '0' },
      { value: '#$%12', expectedInputVal: '12', expectedInputDivVal: '12' },
      { value: 'alpha%12', expectedInputVal: '12', expectedInputDivVal: '12' }
    ];
    inputText.forEach(val => {
      const input = wrapper.find('input');
      input.simulate('change', { currentTarget: { value: val.value } });
      expect(wrapper.find('input').prop('value')).toBe(val.expectedInputVal);
      expect(wrapper.find('.amount-page__amount-box__amount__value').text()).toBe(val.expectedInputDivVal);
      input.simulate('change', { currentTarget: { value: '' } });
    });
  });

  it('should change page CTA based on paymentPageAvailable value', () => {
    expect(wrapper.find(ActionButton).exists()).toBeTruthy();
    expect(wrapper.find(PayWithBitpay).exists()).toBeFalsy();
    wrapper.setProps({ email: '[email protected]' });
    expect(wrapper.find(ActionButton).exists()).toBeFalsy();
    expect(wrapper.find(PayWithBitpay).exists()).toBeTruthy();
  });

  it('should have displayName value as title', () => {
    expect(wrapper.find('.amount-page__merchant-name').text()).toBe(CardConfigData.displayName);
  });

  it('should hide/show DiscountText based on discount value', () => {
    expect(wrapper.find(DiscountText).exists()).toBeFalsy();

    const cardConfigData: CardConfig = CardConfigData;
    const discounts: GiftCardDiscount = {
      code: 'discountCode',
      type: 'percentage',
      amount: 10
    };
    cardConfigData.discounts = [discounts];
    location = createLocation(path, { cardConfig: cardConfigData, merchant: MerchantData });
    wrapper = shallow(
      <Amount
        clientId={AmountProps.clientId}
        email={AmountProps.email}
        purchasedGiftCards={AmountProps.purchasedGiftCards}
        setPurchasedGiftCards={AmountProps.setPurchasedGiftCards}
        history={history}
        location={location}
        match={matchObj}
      />
    );
    expect(wrapper.find(DiscountText).exists()).toBeTruthy();
  });
});
Example #8
Source File: GeneralLogin.spec.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
describe("GeneralLogin", () => {
  afterEach(() => {
    spyOnLogin.mockReset();
    spyOnHistoryPush.mockClear();
    spyOnAuthenticate.mockClear();
    spyOnReloadMicroApps.mockClear();
    spyOnReloadSharedData.mockClear();
    spyOnError.mockClear();
    spyOnHandleHttpError.mockClear();
    spyOnKit.mockClear();
    spyOnEsbLogin.mockClear();
  });

  it("should login successfully", (done) => {
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "mock-pswd",
        });
        expect(spyOnAuthenticate).toBeCalledWith({
          org: 1,
          username: "mock-user",
          userInstanceId: "abc",
          accessRule: "cmdb",
        });
        expect(spyOnReloadMicroApps).toBeCalled();
        expect(spyOnReloadSharedData).toBeCalled();
        expect(spyOnHistoryPush).toBeCalledWith(createLocation("/mock-from"));
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    expect(wrapper).toBeTruthy();
    expect(wrapper.find(Card).find(Tabs).prop("activeKey")).toEqual("ldap");
    wrapper.find(Tabs).prop("onChange")("easyops");
    spyOnLogin.mockResolvedValueOnce({
      loggedIn: true,
      username: "mock-user",
      userInstanceId: "abc",
      org: 1,
      accessRule: "cmdb",
    });
    wrapper.find(Form).at(1).simulate("submit", new Event("submit"));
    expect(spyOnLogin).toHaveBeenCalled();
    expect(storage["LAST_LOGIN_METHOD"]).toEqual("easyops");
    expect(storage["LAST_LOGIN_TIME"]).toEqual(timeStamp);
  });
  it("should work when last login method doesn't exist in misc", (done) => {
    const invalidStorage = {
      LAST_LOGIN_METHOD: "wx",
      LAST_LOGIN_TIME: timeStamp,
    } as any;
    (JsonStorage as jest.Mock).mockImplementation(() => {
      return {
        getItem: (key: string): string => {
          return invalidStorage[key];
        },
        setItem: (key: string, value: string): void => {
          invalidStorage[key] = value;
        },
      };
    });
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "mock-pswd",
        });
        expect(spyOnAuthenticate).toBeCalledWith({
          org: 1,
          username: "mock-user",
          userInstanceId: "abc",
          accessRule: "cmdb",
        });
        expect(spyOnReloadMicroApps).toBeCalled();
        expect(spyOnReloadSharedData).toBeCalled();
        expect(spyOnHistoryPush).toBeCalledWith(createLocation("/mock-from"));
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    expect(wrapper).toBeTruthy();
    expect(wrapper.find(Card).find(Tabs).prop("activeKey")).toEqual("easyops");
    spyOnLogin.mockResolvedValueOnce({
      loggedIn: true,
      username: "mock-user",
      userInstanceId: "abc",
      org: 1,
      accessRule: "cmdb",
    });
    wrapper.find(Form).at(1).simulate("submit", new Event("submit"));
  });
  it("should esb login successfully", (done) => {
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "mock-pswd",
        });
        expect(spyOnAuthenticate).toBeCalledWith({
          org: 1,
          username: "mock-user",
          userInstanceId: "abc",
        });
        expect(spyOnReloadMicroApps).toBeCalled();
        expect(spyOnReloadSharedData).toBeCalled();
        expect(spyOnHistoryPush).toBeCalledWith(createLocation("/mock-from"));
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    expect(wrapper).toBeTruthy();
    spyOnEsbLogin.mockResolvedValueOnce({
      loggedIn: true,
      username: "mock-user",
      userInstanceId: "abc",
      org: 1,
    });
    spyOnKit.mockReturnValueOnce({
      getFeatureFlags: () => ({
        "esb-login": true,
      }),
    } as any);
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
  });
  it("should work when open mfa ", (done) => {
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "mock-pswd",
        });
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    expect(wrapper).toBeTruthy();
    spyOnLogin.mockResolvedValueOnce({
      loggedIn: false,
      username: "mock-user",
      userInstanceId: "abc",
      org: 1,
    });
    spyOnMFALogin.mockResolvedValueOnce({
      totpSecret: "xxx",
      secret: "xxx",
    });
    spyOnMFASetRule.mockResolvedValueOnce({
      isSet: true,
    });
    spyOnKit.mockReturnValueOnce({
      getFeatureFlags: () => ({
        factors: true,
      }),
    } as any);
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
  });

  it("should login failed if give wrong password", async () => {
    expect.assertions(4);
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "wrong-pswd",
        });
        expect(spyOnAuthenticate).not.toBeCalled();
        expect(spyOnReloadMicroApps).not.toBeCalled();
        expect(spyOnReloadSharedData).not.toBeCalled();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    spyOnLogin.mockRejectedValue("用户名(邮箱)或密码错误");
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
    await jest.runAllTimers();
    await (global as any).flushPromises();
    wrapper.update();
    expect(wrapper.find(".loginFormError").at(0).text()).toBe(
      "用户名(邮箱)或密码错误"
    );
  });

  it("should login failed if server error", (done) => {
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(null, {
          username: "mock-user",
          password: "mock-pswd",
        });
        expect(spyOnAuthenticate).not.toBeCalled();
        expect(spyOnReloadMicroApps).not.toBeCalled();
        expect(spyOnReloadSharedData).not.toBeCalled();
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    spyOnLogin.mockRejectedValueOnce(new TypeError("oops"));
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
  });

  it("should not login if form is invalid", (done) => {
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(new Error("mock error"));
        expect(spyOnLogin).not.toBeCalled();
        expect(spyOnAuthenticate).not.toBeCalled();
        expect(spyOnReloadMicroApps).not.toBeCalled();
        expect(spyOnReloadSharedData).not.toBeCalled();
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
  });

  it("brand setting should work", (done) => {
    brandFn.mockReturnValue({ auth_logo_url: "/x/y/z" });
    const form = {
      getFieldDecorator: () => (comp: React.Component) => comp,
      validateFields: jest.fn().mockImplementation(async (fn) => {
        await fn(new Error("mock error"));
        expect(spyOnLogin).not.toBeCalled();
        expect(spyOnAuthenticate).not.toBeCalled();
        expect(spyOnReloadMicroApps).not.toBeCalled();
        expect(spyOnReloadSharedData).not.toBeCalled();
        done();
      }),
    };
    const wrapper = shallow(
      <LegacyGeneralLogin form={form as any} {...i18nProps} />
    );
    expect(wrapper.find("img").first().prop("src")).toBe("/x/y/z");
    wrapper.find(Form).at(0).simulate("submit", new Event("submit"));
  });
});
Example #9
Source File: GeneralSignup.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function GeneralSignup(props: GeneralSignupProps): React.ReactElement {
  const [form] = Form.useForm();
  const runtime = getRuntime();
  const brand = runtime.getBrandSettings();
  const enabledFeatures = runtime.getFeatureFlags();
  const { t } = useTranslation(NS_GENERAL_AUTH);
  const [, setForceUpdate] = useState<any>();

  const passwordConfigMap = {
    default: {
      regex: /^.{6,20}$/,
      description: "请输入6至20位密码",
    },
    strong: {
      regex: /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9]).{8,20}$/,
      description: "请输入8至20位密码,且同时包含大小写字母、数字、特殊字符",
    },
    backend: {},
  };
  let passwordLevel: keyof typeof passwordConfigMap = "default"; //特性开关
  useEffect(() => {
    if (enabledFeatures["enable-backend-password-config"]) {
      (async () => {
        passwordLevel = "backend";
        passwordConfigMap[passwordLevel] =
          await UserAdminApi_getPasswordConfig();
      })();
    }
  }, []);

  const MIN_USERNAME_LENGTH = 3; //特性开关
  const MAX_USERNAME_LENGTH = 32; //特性开关
  const usernamePattern = new RegExp(
    `^[A-Za-z0-9][A-Za-z0-9|_\\-\\.]{${MIN_USERNAME_LENGTH - 1},${
      MAX_USERNAME_LENGTH - 1
    }}$`
  );

  const iniviteCodePattern = /^[0-9a-zA-Z]{9}$/;
  const hideInvite = iniviteCodePattern.test(getInviteCode());
  const [isCommonSignup, setIsCommonSignup] = useState(true);

  const [isTermsVisible, setIsTermsVisible] = useState(false);

  function showTerms(): void {
    setIsTermsVisible(true);
  }
  function hideTerms(): void {
    setIsTermsVisible(false);
  }
  function agreeTerms(): void {
    form.setFieldsValue({
      terms: true,
    });
    hideTerms();
  }
  function disagreeTerms(): void {
    form.setFieldsValue({
      terms: false,
    });
    hideTerms();
  }

  const [imageHeight, setImageHeight] = useState(window.innerHeight);
  const onWindowResized = () => {
    if (imageHeight < window.innerHeight) {
      setImageHeight(window.innerHeight);
    }
  };
  useEffect(() => {
    const handleWindowResized = debounce(onWindowResized, 500, {
      leading: false,
    });
    window.addEventListener("resize", handleWindowResized);
    return () => {
      window.removeEventListener("resize", handleWindowResized);
    };
  }, []);

  const timer = useRef<any>();
  const count = useRef<number>(duration);
  const [verifyBtnDisabled, setVerifyBtnDisabled] = useState(true);
  const [content, setContent] = useState(t(K.GET_VERIFY_CODE));
  const [messageId, setMessageId] = useState("");
  const handleVerifyBtnClick = async (
    e: React.MouseEvent<HTMLElement, MouseEvent>
  ) => {
    if (timer.current) return;
    count.current -= 1;
    setContent(t(K.GET_VERIFY_CODE_TIPS, { count: count.current }));
    setVerifyBtnDisabled(true);
    timer.current = setInterval(() => {
      count.current -= 1;
      setContent(t(K.GET_VERIFY_CODE_TIPS, { count: count.current }));
      if (count.current === 0) {
        clearInterval(timer.current);
        timer.current = null;
        count.current = duration;
        setVerifyBtnDisabled(false);
        setContent(t(K.GET_VERIFY_CODE));
      }
    }, 1000);
    const result = await CustomerApi_sendApplicationVerificationCode({
      phone_number: form.getFieldValue("phone"),
    });
    result.message_id && setMessageId(result.message_id);
  };

  const redirect = async (result: Record<string, any>): Promise<void> => {
    runtime.reloadSharedData();
    await runtime.reloadMicroApps();
    resetLegacyIframe();
    authenticate({
      org: result.org,
      username: result.username,
      userInstanceId: result.userInstanceId,
      accessRule: result.accessRule,
    });
    const { state } = getHistory().location;
    const from =
      state && state.from
        ? state.from
        : {
            pathname: "/",
          };
    const redirect = createLocation(from);
    getHistory().push(redirect);
  };

  const onFinish = async (values: Record<string, any>): Promise<void> => {
    values.password = encryptValue(values.password);
    try {
      let result: Record<string, any>;
      if (isCommonSignup && !hideInvite) {
        result = await OrgApi_saaSOrgRegister(
          assign(omit(values, ["terms", "password2"]), {
            message_id: messageId,
          }) as OrgApi_SaaSOrgRegisterRequestBody
        );
      } else {
        result = await AuthApi_register(
          assign(
            omit(values, ["terms", "password2", "username"]),
            hideInvite
              ? { invite: getInviteCode(), name: values["username"] }
              : { name: values["username"] }
          ) as AuthApi_RegisterRequestBody
        );
      }
      if (result.loggedIn) {
        redirect(result);
      }
      message.success(t(K.REGISTER_SUCCESS));
    } catch (error) {
      Modal.error({
        title: t(K.REGISTER_FAILED),
        content:
          isCommonSignup && !hideInvite
            ? t(K.WRONG_VERIFICATION_CODE)
            : t(K.WRONG_INVITE_CODE),
      });
    }
  };

  return (
    <>
      <div className={styles.signupWrapper}>
        <div className={styles.signupHeader}>
          <div className={styles.logoBar}>
            <Link to="/">
              {brand.auth_logo_url ? (
                <img
                  src={brand.auth_logo_url}
                  style={{ height: 32, verticalAlign: "middle" }}
                />
              ) : (
                <Logo height={32} style={{ verticalAlign: "middle" }} />
              )}
            </Link>
          </div>
        </div>
        <div className={styles.signupImg}>
          <img src={loginPng} style={{ height: imageHeight }} />
        </div>
        <div className={styles.signupForm}>
          <Card bordered={false}>
            {!hideInvite &&
              (isCommonSignup ? (
                <a
                  onClick={() => {
                    setIsCommonSignup(false);
                  }}
                  style={{ alignSelf: "flex-end" }}
                  id="JumpToJoinFormLink"
                >
                  {t(K.JOIN_THE_ORGANIZATION)} <RightOutlined />
                </a>
              ) : (
                <a
                  onClick={() => {
                    setIsCommonSignup(true);
                  }}
                  id="JumpToCommonFormLink"
                >
                  <LeftOutlined /> {t(K.REGISTER_COMMONLY)}
                </a>
              ))}
            {!hideInvite && isCommonSignup ? (
              <div className={styles.title}>{t(K.REGISTER_ACCOUNT)}</div>
            ) : (
              <div className={styles.title}>{t(K.REGISTER_AND_JOIN)}</div>
            )}
            <Form name="signupForm" form={form} onFinish={onFinish}>
              <Form.Item
                validateFirst={true}
                name="username"
                rules={[
                  {
                    required: true,
                    message: t(K.USERNAME_TIPS, {
                      minLength: 3,
                      maxLength: 32,
                    }),
                  },
                  {
                    pattern: usernamePattern,
                    message: t(K.USERNAME_TIPS, {
                      minLength: 3,
                      maxLength: 32,
                    }),
                  },
                  {
                    validator: (
                      _: any,
                      value: any,
                      callback: (value?: string) => void
                    ) =>
                      validateMap["airNameValidator"](
                        value,
                        callback,
                        setForceUpdate
                      ),
                  },
                ]}
              >
                <Input
                  prefix={<UserOutlined className={styles.inputPrefixIcon} />}
                  placeholder={t(K.USERNAME)}
                />
              </Form.Item>
              {enabledFeatures["enable-nickname-config"] && hideInvite && (
                <Form.Item validateFirst={false} name="nickname">
                  <Input
                    prefix={
                      <SolutionOutlined className={styles.inputPrefixIcon} />
                    }
                    placeholder={t(K.NICKNAME)}
                  />
                </Form.Item>
              )}
              <Form.Item
                name="email"
                validateFirst={true}
                rules={[
                  { required: true, message: t(K.PLEASE_ENTER_VALID_EMAIL) },
                  { type: "email", message: t(K.PLEASE_ENTER_VALID_EMAIL) },
                  {
                    validator: (
                      _: any,
                      value: any,
                      callback: (value?: string) => void
                    ) =>
                      validateMap["airEmailValidator"](
                        value,
                        callback,
                        setForceUpdate
                      ),
                  },
                ]}
              >
                <Input
                  prefix={<MailOutlined className={styles.inputPrefixIcon} />}
                  type="email"
                  placeholder={t(K.EMAIL)}
                />
              </Form.Item>
              <Form.Item
                validateFirst={true}
                name="password"
                rules={[
                  { required: true, message: t(K.PLEASE_INPUT_PASSWORD) },
                  {
                    pattern: passwordConfigMap[passwordLevel].regex,
                    message: passwordConfigMap[passwordLevel].description,
                  },
                ]}
              >
                <Input
                  prefix={<LockOutlined className={styles.inputPrefixIcon} />}
                  type="password"
                  placeholder={t(K.PASSWORD)}
                />
              </Form.Item>
              <Form.Item
                dependencies={["password"]}
                name="password2"
                rules={[
                  { required: true, message: t(K.PLEASE_INPUT_PASSWORD) },
                  ({ getFieldValue }) => ({
                    validator(_, value) {
                      if (!value || getFieldValue("password") === value) {
                        return Promise.resolve();
                      }
                      return Promise.reject(
                        new Error(t(K.TWO_PASSWORDS_ARE_INCONSISTENT))
                      );
                    },
                  }),
                ]}
              >
                <Input
                  prefix={<LockOutlined className={styles.inputPrefixIcon} />}
                  type="password"
                  placeholder={t(K.PASSWORD_CONFIRM)}
                />
              </Form.Item>
              {!hideInvite &&
                (isCommonSignup ? (
                  <>
                    <Form.Item
                      validateFirst={true}
                      rules={[
                        {
                          required: true,
                          message: t(K.PLEASE_FILL_IN_VALID_PHONE_NUMBER),
                        },
                        {
                          validator: (_, value) => {
                            if (
                              /^(?=\d{11}$)^1(?:3\d|4[57]|5[^4\D]|7[^249\D]|8\d)\d{8}$/.test(
                                value
                              )
                            ) {
                              setVerifyBtnDisabled(false);
                              return Promise.resolve();
                            }
                            setVerifyBtnDisabled(true);
                            return Promise.reject(
                              new Error(t(K.PLEASE_FILL_IN_VALID_PHONE_NUMBER))
                            );
                          },
                        },
                      ]}
                      name="phone"
                    >
                      <Input
                        prefix={
                          <PhoneOutlined
                            className={styles.inputPrefixIcon}
                            rotate={90}
                          />
                        }
                        suffix={
                          <Button
                            disabled={verifyBtnDisabled}
                            type="text"
                            onClick={handleVerifyBtnClick}
                            id="verifyBtn"
                          >
                            {content}
                          </Button>
                        }
                        placeholder={t(K.PHONE)}
                      />
                    </Form.Item>
                    <Form.Item
                      rules={[
                        {
                          required: true,
                          message: t(K.PLEASE_INPUT_PHRASE),
                        },
                        {
                          pattern: /^\d{6}$/,
                          message: t(K.PLEASE_INPUT_VALID_PHRASE),
                        },
                      ]}
                      name="verification_code"
                    >
                      <Input
                        prefix={
                          <SafetyOutlined className={styles.inputPrefixIcon} />
                        }
                        placeholder={t(K.VERIFY_CODE)}
                      ></Input>
                    </Form.Item>
                  </>
                ) : (
                  <Form.Item
                    validateFirst={true}
                    name="invite"
                    rules={[
                      {
                        required: true,
                        message: t([K.PLEASE_FILL_IN_INVITE_CODE]),
                      },
                      {
                        pattern: iniviteCodePattern,
                        message: t([K.PLEASE_FILL_IN_INVITE_CODE]),
                      },
                    ]}
                  >
                    <Input
                      prefix={
                        <GeneralIcon
                          icon={{
                            lib: "easyops",
                            icon: "release-management",
                            category: "menu",
                            color: "rgba(0,0,0,.25)",
                          }}
                        />
                      }
                      type="text"
                      placeholder={t(K.INVITE_CODE)}
                    />
                  </Form.Item>
                ))}
              <Form.Item
                name="terms"
                valuePropName="checked"
                rules={[
                  {
                    validator: (_, value) =>
                      value
                        ? Promise.resolve()
                        : Promise.reject(new Error(t(K.AGREE_TERMS_TIPS))),
                  },
                ]}
              >
                <Checkbox>
                  {t(K.AGREE_TERMS)}
                  <a
                    onClick={() => {
                      showTerms();
                    }}
                    id="TermsLink"
                  >
                    {t(K.UWINTECH_TERMS)}
                  </a>
                </Checkbox>
              </Form.Item>
              <Form.Item>
                <Button
                  type="primary"
                  htmlType="submit"
                  style={{
                    width: "100%",
                    height: 34,
                  }}
                  id="submitBtn"
                >
                  {t(K.REGISTER)}
                </Button>
              </Form.Item>
              <Form.Item>
                <div style={{ textAlign: "center" }}>
                  {t(K.ALREADY_HAVE_AN_ACCOUNT)}
                  <a
                    id="LogInLink"
                    onClick={() => {
                      getHistory().push(
                        createLocation({
                          pathname: props.loginUrl ?? "/auth/login",
                        })
                      );
                    }}
                  >
                    {t(K.LOGIN_IMMEDIATELY)}
                  </a>
                </div>
              </Form.Item>
            </Form>
          </Card>
          <Modal
            visible={isTermsVisible}
            title={t(K.UWINTECH_TERMS)}
            width={598}
            okType="default"
            cancelText={t(K.DISAGREE)}
            okText={t(K.AGREE)}
            closable={false}
            onCancel={() => {
              disagreeTerms();
            }}
            onOk={() => {
              agreeTerms();
            }}
          >
            <Terms />
          </Modal>
        </div>
      </div>
    </>
  );
}