chore: Updating the login and signup page for cloud hosting as per new design (#32641)
## Description Updating the login and signup page for cloud hosting as per new design Fixes [#32267](https://github.com/appsmithorg/appsmith/issues/32267) ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/8723701550> > Commit: 65a0179c5d22e1f950888c24a119af608aed2a28 > Cypress dashboard url: <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8723701550&attempt=4" target="_blank">Click here!</a> <!-- end of auto-generated comment: Cypress test results --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced titles and messages across login, signup, and forgot password pages for clarity and engagement. - Added new analytics event for tracking visits to self-hosting documentation. - Introduced new content and layout adjustments in user authentication pages to improve user experience. - Implemented conditional rendering to optimize content display for mobile devices and cloud hosting scenarios. - **Bug Fixes** - Updated footer links to use consistent capitalization. - **Refactor** - Major structural and styling overhaul of forms and user authentication components to utilize modern CSS practices and improve maintainability. - **Documentation** - Added direct links to self-hosting documentation to facilitate user access. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
313338899e
commit
e07e3ecd04
|
|
@ -64,7 +64,7 @@ describe(
|
||||||
homePage.Signout();
|
homePage.Signout();
|
||||||
// validating sso with github is enabled
|
// validating sso with github is enabled
|
||||||
assertHelper.AssertContains(
|
assertHelper.AssertContains(
|
||||||
"Continue with Github",
|
"Github",
|
||||||
"be.visible",
|
"be.visible",
|
||||||
adminSettingsLocators.loginWithGithub,
|
adminSettingsLocators.loginWithGithub,
|
||||||
);
|
);
|
||||||
|
|
@ -110,7 +110,7 @@ describe(
|
||||||
homePage.Signout();
|
homePage.Signout();
|
||||||
// validating sso with github is disabled
|
// validating sso with github is disabled
|
||||||
assertHelper.AssertContains(
|
assertHelper.AssertContains(
|
||||||
"Continue with Github",
|
"Github",
|
||||||
"not.exist",
|
"not.exist",
|
||||||
adminSettingsLocators.loginWithGithub,
|
adminSettingsLocators.loginWithGithub,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,7 @@ describe(
|
||||||
cy.get(homePage.signOutIcon).click();
|
cy.get(homePage.signOutIcon).click();
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
// validating sso with google is enabled
|
// validating sso with google is enabled
|
||||||
cy.get(adminSettings.loginWithGoogle).should(
|
cy.get(adminSettings.loginWithGoogle).should("have.text", "Google");
|
||||||
"have.text",
|
|
||||||
"Continue with Google",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("3. Go to admin settings and disable Google", function () {
|
it("3. Go to admin settings and disable Google", function () {
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
"d3-geo": "^3.1.0",
|
"d3-geo": "^3.1.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.6",
|
||||||
"deep-diff": "^1.0.2",
|
"deep-diff": "^1.0.2",
|
||||||
"design-system": "npm:@appsmithorg/design-system@2.1.36",
|
"design-system": "npm:@appsmithorg/design-system@2.1.37",
|
||||||
"design-system-old": "npm:@appsmithorg/design-system-old@1.1.16",
|
"design-system-old": "npm:@appsmithorg/design-system-old@1.1.16",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
"echarts": "^5.4.2",
|
"echarts": "^5.4.2",
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,7 @@ export const FORM_VALIDATION_INVALID_PASSWORD = FORM_VALIDATION_PASSWORD_RULE;
|
||||||
|
|
||||||
export const LOGIN_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
export const LOGIN_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
||||||
export const LOGIN_PAGE_PASSWORD_INPUT_LABEL = () => `Password`;
|
export const LOGIN_PAGE_PASSWORD_INPUT_LABEL = () => `Password`;
|
||||||
export const LOGIN_PAGE_EMAIL_INPUT_PLACEHOLDER = () =>
|
export const LOGIN_PAGE_EMAIL_INPUT_PLACEHOLDER = () => `Enter your email`;
|
||||||
`Enter your email address`;
|
|
||||||
export const LOGIN_PAGE_PASSWORD_INPUT_PLACEHOLDER = () =>
|
export const LOGIN_PAGE_PASSWORD_INPUT_PLACEHOLDER = () =>
|
||||||
`Enter your password`;
|
`Enter your password`;
|
||||||
export const LOGIN_PAGE_INVALID_CREDS_ERROR = () =>
|
export const LOGIN_PAGE_INVALID_CREDS_ERROR = () =>
|
||||||
|
|
@ -66,25 +65,28 @@ export const LOGIN_PAGE_INVALID_CREDS_ERROR = () =>
|
||||||
export const LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK = () =>
|
export const LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK = () =>
|
||||||
`Reset password`;
|
`Reset password`;
|
||||||
export const NEW_TO_APPSMITH = () => `Don't have an account?`;
|
export const NEW_TO_APPSMITH = () => `Don't have an account?`;
|
||||||
export const LOGIN_PAGE_TITLE = () => `Sign in`;
|
export const LOGIN_PAGE_TITLE = () => `Sign in to your account`;
|
||||||
export const LOGIN_PAGE_SUBTITLE = () => `Sign in to your account`;
|
export const LOGIN_PAGE_SUBTITLE = () => `Sign in to your account`;
|
||||||
|
|
||||||
export const LOGIN_PAGE_LOGIN_BUTTON_TEXT = () => `Sign in`;
|
export const LOGIN_PAGE_LOGIN_BUTTON_TEXT = () => `Sign in`;
|
||||||
export const LOGIN_PAGE_FORGOT_PASSWORD_TEXT = () => `Forgot password`;
|
export const LOGIN_PAGE_FORGOT_PASSWORD_TEXT = () => `Forgot password`;
|
||||||
export const LOGIN_PAGE_REMEMBER_ME_LABEL = () => `Remember`;
|
export const LOGIN_PAGE_REMEMBER_ME_LABEL = () => `Remember`;
|
||||||
export const LOGIN_PAGE_SIGN_UP_LINK_TEXT = () => `Sign up`;
|
export const LOGIN_PAGE_SIGN_UP_LINK_TEXT = () => `Sign up`;
|
||||||
export const SIGNUP_PAGE_TITLE = () => `Create your free account`;
|
export const SIGNUP_PAGE_TITLE = () => `Create your account`;
|
||||||
export const SIGNUP_PAGE_SUBTITLE = () => `Use your workspace email`;
|
export const SIGNUP_PAGE_SUBTITLE = () => `Use your workspace email`;
|
||||||
export const SIGNUP_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
export const SIGNUP_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
||||||
export const SIGNUP_PAGE_EMAIL_INPUT_PLACEHOLDER = () => `Email`;
|
export const SIGNUP_PAGE_EMAIL_INPUT_PLACEHOLDER = () => `Enter your email`;
|
||||||
export const SIGNUP_PAGE_NAME_INPUT_PLACEHOLDER = () => `Name`;
|
export const SIGNUP_PAGE_NAME_INPUT_PLACEHOLDER = () => `Name`;
|
||||||
export const SIGNUP_PAGE_NAME_INPUT_LABEL = () => `Name`;
|
export const SIGNUP_PAGE_NAME_INPUT_LABEL = () => `Name`;
|
||||||
export const SIGNUP_PAGE_PASSWORD_INPUT_LABEL = () => `Password`;
|
export const SIGNUP_PAGE_PASSWORD_INPUT_LABEL = () => `Password`;
|
||||||
export const SIGNUP_PAGE_PASSWORD_INPUT_PLACEHOLDER = () => `Password`;
|
export const SIGNUP_PAGE_PASSWORD_INPUT_PLACEHOLDER = () =>
|
||||||
|
`Enter your password`;
|
||||||
export const SIGNUP_PAGE_LOGIN_LINK_TEXT = () => `Sign in`;
|
export const SIGNUP_PAGE_LOGIN_LINK_TEXT = () => `Sign in`;
|
||||||
export const SIGNUP_PAGE_NAME_INPUT_SUBTEXT = () => `How should we call you?`;
|
export const SIGNUP_PAGE_NAME_INPUT_SUBTEXT = () => `How should we call you?`;
|
||||||
export const SIGNUP_PAGE_SUBMIT_BUTTON_TEXT = () => `Sign up`;
|
export const SIGNUP_PAGE_SUBMIT_BUTTON_TEXT = () => `Sign up`;
|
||||||
export const ALREADY_HAVE_AN_ACCOUNT = () => `Already have an account?`;
|
export const ALREADY_HAVE_AN_ACCOUNT = () => `Already have an account?`;
|
||||||
|
export const LOOKING_TO_SELF_HOST = () => "Looking to self-host Appsmith?";
|
||||||
|
export const VISIT_OUR_DOCS = () => "Visit our docs";
|
||||||
|
|
||||||
export const SIGNUP_PAGE_SUCCESS = () =>
|
export const SIGNUP_PAGE_SUCCESS = () =>
|
||||||
`Awesome! You have successfully registered.`;
|
`Awesome! You have successfully registered.`;
|
||||||
|
|
@ -110,11 +112,14 @@ export const RESET_PASSWORD_INVALID_TOKEN = () =>
|
||||||
export const RESET_PASSWORD_FORGOT_PASSWORD_LINK = () => `Forgot password`;
|
export const RESET_PASSWORD_FORGOT_PASSWORD_LINK = () => `Forgot password`;
|
||||||
|
|
||||||
export const FORGOT_PASSWORD_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
export const FORGOT_PASSWORD_PAGE_EMAIL_INPUT_LABEL = () => `Email`;
|
||||||
export const FORGOT_PASSWORD_PAGE_EMAIL_INPUT_PLACEHOLDER = () => `Email`;
|
export const FORGOT_PASSWORD_PAGE_EMAIL_INPUT_PLACEHOLDER = () =>
|
||||||
|
`Enter your email`;
|
||||||
export const FORGOT_PASSWORD_PAGE_TITLE = () => `Reset password`;
|
export const FORGOT_PASSWORD_PAGE_TITLE = () => `Reset password`;
|
||||||
|
export const FORGOT_PASSWORD_PAGE_SUB_TITLE = () =>
|
||||||
|
`Enter the email address associated with your account`;
|
||||||
export const FORGOT_PASSWORD_PAGE_SUBTITLE = () =>
|
export const FORGOT_PASSWORD_PAGE_SUBTITLE = () =>
|
||||||
`We will send a reset link to the email below`;
|
`We will send a reset link to the email below`;
|
||||||
export const FORGOT_PASSWORD_PAGE_SUBMIT_BUTTON_TEXT = () => `Reset`;
|
export const FORGOT_PASSWORD_PAGE_SUBMIT_BUTTON_TEXT = () => `Send reset link`;
|
||||||
export const FORGOT_PASSWORD_SUCCESS_TEXT = (email: string) =>
|
export const FORGOT_PASSWORD_SUCCESS_TEXT = (email: string) =>
|
||||||
`A password reset link has been sent to your email address ${email} registered with Appsmith.`;
|
`A password reset link has been sent to your email address ${email} registered with Appsmith.`;
|
||||||
|
|
||||||
|
|
@ -122,12 +127,12 @@ export const VERIFICATION_PENDING_TITLE = () => `Check your inbox`;
|
||||||
export const VERIFICATION_PENDING_BODY = () =>
|
export const VERIFICATION_PENDING_BODY = () =>
|
||||||
`To finish your account setup click on the verification link we have sent in an email to `;
|
`To finish your account setup click on the verification link we have sent in an email to `;
|
||||||
|
|
||||||
export const VERIFICATION_PENDING_NOT_YOU = () => `(not you?)`;
|
export const VERIFICATION_PENDING_NOT_YOU = () => `Not you?`;
|
||||||
|
|
||||||
export const VERIFICATION_PENDING_NO_EMAIL = () =>
|
export const VERIFICATION_PENDING_NO_EMAIL = () =>
|
||||||
`No email in your inbox or spam folder?`;
|
`No email in your inbox or spam folder?`;
|
||||||
|
|
||||||
export const VERIFICATION_PENDING_RESEND_LINK = () => `Resend the link`;
|
export const VERIFICATION_PENDING_RESEND_LINK = () => `Resend link`;
|
||||||
|
|
||||||
export const VERIFY_ERROR_ALREADY_VERIFIED_TITLE = () =>
|
export const VERIFY_ERROR_ALREADY_VERIFIED_TITLE = () =>
|
||||||
`Email already verified`;
|
`Email already verified`;
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,8 @@ import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||||
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
|
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
|
||||||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||||
import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/CreateNewAppFromTemplatesWrapper";
|
import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/CreateNewAppFromTemplatesWrapper";
|
||||||
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
|
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
|
||||||
|
|
||||||
export const { cloudHosting } = getAppsmithConfigs();
|
export const { cloudHosting } = getAppsmithConfigs();
|
||||||
|
|
||||||
|
|
@ -644,7 +646,7 @@ export function ApplicationsSection(props: any) {
|
||||||
<div className="flex flex-col items-center justify-center mt-[180px]">
|
<div className="flex flex-col items-center justify-center mt-[180px]">
|
||||||
<img
|
<img
|
||||||
className="mb-6"
|
className="mb-6"
|
||||||
src="https://assets.appsmith.com/no-workspace-found.svg"
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/no-workspace-found.svg`)}`}
|
||||||
/>
|
/>
|
||||||
<NewText className="!mb-3 !font-semibold" kind="heading-s">
|
<NewText className="!mb-3 !font-semibold" kind="heading-s">
|
||||||
{createMessage(NO_WORKSPACE_HEADING)}
|
{createMessage(NO_WORKSPACE_HEADING)}
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,8 @@ export type EventName =
|
||||||
| "MULTI_FILE_PICKER_EXCEEDS_LIMIT"
|
| "MULTI_FILE_PICKER_EXCEEDS_LIMIT"
|
||||||
| "TEMPLATE_ADD_PAGE_FROM_TEMPLATE_FLOW"
|
| "TEMPLATE_ADD_PAGE_FROM_TEMPLATE_FLOW"
|
||||||
| HOMEPAGE_CREATE_APP_FROM_TEMPLATE_EVENTS
|
| HOMEPAGE_CREATE_APP_FROM_TEMPLATE_EVENTS
|
||||||
| "EDITOR_MODE_CHANGE";
|
| "EDITOR_MODE_CHANGE"
|
||||||
|
| "VISIT_SELF_HOST_DOCS";
|
||||||
|
|
||||||
type HOMEPAGE_CREATE_APP_FROM_TEMPLATE_EVENTS =
|
type HOMEPAGE_CREATE_APP_FROM_TEMPLATE_EVENTS =
|
||||||
| "TEMPLATE_DROPDOWN_CLICK"
|
| "TEMPLATE_DROPDOWN_CLICK"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,12 @@ import { Form } from "redux-form";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
const StyledForm = styled(Form)`
|
const StyledForm = styled(Form)`
|
||||||
width: 100%;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
.bp3-form-group {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default StyledForm;
|
export default StyledForm;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ export const GITHUB_RELEASE_URL =
|
||||||
"https://github.com/appsmithorg/appsmith/releases/tag";
|
"https://github.com/appsmithorg/appsmith/releases/tag";
|
||||||
export const GET_RELEASE_NOTES_URL = (tagName: string) =>
|
export const GET_RELEASE_NOTES_URL = (tagName: string) =>
|
||||||
`${GITHUB_RELEASE_URL}/${tagName}`;
|
`${GITHUB_RELEASE_URL}/${tagName}`;
|
||||||
|
export const SELF_HOSTING_DOC =
|
||||||
|
"https://docs.appsmith.com/getting-started/setup";
|
||||||
export const GOOGLE_MAPS_SETUP_DOC =
|
export const GOOGLE_MAPS_SETUP_DOC =
|
||||||
"https://docs.appsmith.com/getting-started/setup/instance-configuration/google-maps";
|
"https://docs.appsmith.com/getting-started/setup/instance-configuration/google-maps";
|
||||||
export const GOOGLE_SIGNUP_SETUP_DOC =
|
export const GOOGLE_SIGNUP_SETUP_DOC =
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
import FooterLinks from "./FooterLinks";
|
|
||||||
import { getTenantConfig } from "@appsmith/selectors/tenantSelectors";
|
import { getTenantConfig } from "@appsmith/selectors/tenantSelectors";
|
||||||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
|
import LeftSideContent from "./LeftSideContent";
|
||||||
|
import { getAppsmithConfigs } from "@appsmith/configs";
|
||||||
|
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
interface ContainerProps {
|
interface ContainerProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
@ -14,38 +17,67 @@ interface ContainerProps {
|
||||||
testId?: string;
|
testId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ContainerWrapper = styled.div`
|
||||||
|
a {
|
||||||
|
span {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const BoxWrapper = styled.div<{ isMobileView: boolean }>`
|
||||||
|
box-shadow: 0px 1px 20px 0px rgba(76, 86, 100, 0.11);
|
||||||
|
border-radius: var(--ads-v2-border-radius);
|
||||||
|
background: var(--ads-v2-color-bg);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--ads-v2-spaces-5);
|
||||||
|
padding: 32px 24px;
|
||||||
|
|
||||||
|
${({ isMobileView }) =>
|
||||||
|
isMobileView ? "border: 1px solid var(--ads-v2-color-border);" : ""}
|
||||||
|
`;
|
||||||
|
|
||||||
function Container(props: ContainerProps) {
|
function Container(props: ContainerProps) {
|
||||||
const { children, footer, subtitle, testId, title } = props;
|
const { children, footer, subtitle, testId, title } = props;
|
||||||
const tenantConfig = useSelector(getTenantConfig);
|
const tenantConfig = useSelector(getTenantConfig);
|
||||||
|
const { cloudHosting } = getAppsmithConfigs();
|
||||||
|
const isMobileDevice = useIsMobileDevice();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<ContainerWrapper
|
||||||
className="flex flex-col items-center gap-4 my-auto min-w-min"
|
className={`gap-14 my-auto flex items-center justify-center min-w-min`}
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
>
|
>
|
||||||
<div className="bg-white border border-t-4 border-[color:var(--ads-v2\-color-border)] border-t-[color:var(--ads-v2\-color-border-brand)] py-8 px-6 w-[min(400px,80%)] flex flex-col gap-6 t--login-container rounded-[var(--ads-v2\-border-radius)]">
|
{cloudHosting && !isMobileDevice && <LeftSideContent />}
|
||||||
<img
|
<BoxWrapper
|
||||||
className="h-8 mx-auto"
|
className={`t--login-container ${
|
||||||
src={getAssetUrl(tenantConfig.brandLogoUrl)}
|
isMobileDevice ? "w-full" : "w-[min(400px,80%)]"
|
||||||
/>
|
}`}
|
||||||
<div className="flex flex-col gap-2 text-center">
|
isMobileView={isMobileDevice}
|
||||||
<h1 className="text-xl font-semibold text-center text-[color:var(--ads-v2\-color-fg-emphasis)]">
|
>
|
||||||
{title}
|
{!isMobileDevice && (
|
||||||
</h1>
|
<img
|
||||||
{subtitle && (
|
className="h-8 mx-auto"
|
||||||
<p className="text-base text-center text-[color:var(--ads-v2\-color-fg)]">
|
src={getAssetUrl(tenantConfig.brandLogoUrl)}
|
||||||
{subtitle}
|
/>
|
||||||
</p>
|
)}
|
||||||
)}
|
<div className={`flex flex-col gap-4`}>
|
||||||
|
<div className="flex flex-col gap-2 text-center">
|
||||||
|
<h1 className="text-lg font-semibold text-center text-[color:var(--ads-v2\-color-fg-emphasis)]">
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
{subtitle && (
|
||||||
|
<p className="text-[14px] text-center text-[color:var(--ads-v2\-color-fg)]">
|
||||||
|
{subtitle}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{children}
|
||||||
|
{footer}
|
||||||
</div>
|
</div>
|
||||||
{children}
|
</BoxWrapper>
|
||||||
</div>
|
</ContainerWrapper>
|
||||||
|
|
||||||
<div className="bg-white border w-[min(400px,80%)] rounded-[var(--ads-v2\-border-radius)] border-[color:var(--ads-v2\-color-border)]">
|
|
||||||
{footer}
|
|
||||||
<FooterLinks />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,35 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "design-system";
|
import { Link } from "design-system";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
const FooterWrapper = styled.div`
|
||||||
|
width: 85%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
a {
|
||||||
|
display: inline;
|
||||||
|
span {
|
||||||
|
display: inline;
|
||||||
|
svg {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
function FooterLinks() {
|
function FooterLinks() {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center gap-4 px-2 py-2">
|
<FooterWrapper>
|
||||||
|
By using Appsmith, you are agreeing to our
|
||||||
<Link target="_blank" to="/privacy-policy.html">
|
<Link target="_blank" to="/privacy-policy.html">
|
||||||
Privacy policy
|
privacy policy
|
||||||
</Link>
|
</Link>
|
||||||
|
and
|
||||||
<Link target="_blank" to="/terms-and-conditions.html">
|
<Link target="_blank" to="/terms-and-conditions.html">
|
||||||
Terms and conditions
|
terms of service
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
.
|
||||||
|
</FooterWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ import {
|
||||||
FORM_VALIDATION_EMPTY_EMAIL,
|
FORM_VALIDATION_EMPTY_EMAIL,
|
||||||
FORM_VALIDATION_INVALID_EMAIL,
|
FORM_VALIDATION_INVALID_EMAIL,
|
||||||
FORGOT_PASSWORD_SUCCESS_TEXT,
|
FORGOT_PASSWORD_SUCCESS_TEXT,
|
||||||
FORGOT_PASSWORD_PAGE_LOGIN_LINK,
|
|
||||||
createMessage,
|
createMessage,
|
||||||
|
FORGOT_PASSWORD_PAGE_SUB_TITLE,
|
||||||
} from "@appsmith/constants/messages";
|
} from "@appsmith/constants/messages";
|
||||||
import { AUTH_LOGIN_URL } from "constants/routes";
|
import { AUTH_LOGIN_URL } from "constants/routes";
|
||||||
import { FORGOT_PASSWORD_FORM_NAME } from "@appsmith/constants/forms";
|
import { FORGOT_PASSWORD_FORM_NAME } from "@appsmith/constants/forms";
|
||||||
import FormTextField from "components/utils/ReduxFormTextField";
|
import FormTextField from "components/utils/ReduxFormTextField";
|
||||||
import { FormGroup } from "design-system-old";
|
import { FormGroup } from "design-system-old";
|
||||||
import { Button, Link, Callout } from "design-system";
|
import { Button, Link, Callout, Icon } from "design-system";
|
||||||
import { isEmail, isEmptyString } from "utils/formhelpers";
|
import { isEmail, isEmptyString } from "utils/formhelpers";
|
||||||
import type { ForgotPasswordFormValues } from "./helpers";
|
import type { ForgotPasswordFormValues } from "./helpers";
|
||||||
import { forgotPasswordSubmitHandler } from "./helpers";
|
import { forgotPasswordSubmitHandler } from "./helpers";
|
||||||
|
|
@ -58,18 +58,25 @@ export const ForgotPassword = (props: ForgotPasswordProps) => {
|
||||||
}
|
}
|
||||||
}, [props.emailValue]);
|
}, [props.emailValue]);
|
||||||
|
|
||||||
|
const footerSection = (
|
||||||
|
<div className="px-2 flex items-center justify-center text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
|
<Icon name="arrow-left-line" size="md" />
|
||||||
|
Back to
|
||||||
|
<Link
|
||||||
|
className="text-sm justify-center"
|
||||||
|
kind="primary"
|
||||||
|
target="_self"
|
||||||
|
to={AUTH_LOGIN_URL}
|
||||||
|
>
|
||||||
|
Sign in
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
subtitle={
|
footer={footerSection}
|
||||||
<Link
|
subtitle={createMessage(FORGOT_PASSWORD_PAGE_SUB_TITLE)}
|
||||||
className="text-sm justify-center"
|
|
||||||
startIcon="arrow-left-line"
|
|
||||||
target="_self"
|
|
||||||
to={AUTH_LOGIN_URL}
|
|
||||||
>
|
|
||||||
{createMessage(FORGOT_PASSWORD_PAGE_LOGIN_LINK)}
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
title={createMessage(FORGOT_PASSWORD_PAGE_TITLE)}
|
title={createMessage(FORGOT_PASSWORD_PAGE_TITLE)}
|
||||||
>
|
>
|
||||||
<FormMessagesContainer>
|
<FormMessagesContainer>
|
||||||
|
|
|
||||||
119
app/client/src/pages/UserAuth/LeftSideContent.tsx
Normal file
119
app/client/src/pages/UserAuth/LeftSideContent.tsx
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
|
import React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
|
||||||
|
import { Avatar } from "design-system";
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
width: 432px;
|
||||||
|
|
||||||
|
.left-description {
|
||||||
|
padding-bottom: 24px;
|
||||||
|
border-bottom: 1px solid var(--ads-v2-color-border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--ads-spaces-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-description-container {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--ads-v2-color-gray-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-description-author {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--ads-spaces-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-description-author > div {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client-logo-container {
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client-heading {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1.33;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client-logo-container img {
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client-logo-container .client-logo-section {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
gap: var(--ads-spaces-3);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
function LeftSideContent() {
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<div className="left-description">
|
||||||
|
<div className="left-description-container">
|
||||||
|
"We’d been looking for a tool like Appsmith for years. With
|
||||||
|
Appsmith we were able to build a UI on top of 12 different Snowflake
|
||||||
|
control tables. Appsmith was easy for our developers to learn, and
|
||||||
|
it’s easy to implement."
|
||||||
|
</div>
|
||||||
|
<div className="left-description-author">
|
||||||
|
<Avatar
|
||||||
|
image={`${getAssetUrl(`${ASSETS_CDN_URL}/thomas-zwick.png`)}`}
|
||||||
|
label="Thomas Zwick"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<div>Thomas Zwick</div>
|
||||||
|
<div className="dot">·</div>
|
||||||
|
<div>Director, Omron</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="client-logo-container">
|
||||||
|
<div className="client-heading">
|
||||||
|
Used by more than 10,000 organisations across the globe
|
||||||
|
</div>
|
||||||
|
<div className="client-logo-section">
|
||||||
|
<img
|
||||||
|
alt="GSK logo"
|
||||||
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/gsk-logo-grey.svg`)}`}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="Omron logo"
|
||||||
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/omron-logo.svg`)}`}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="Dropbox logo"
|
||||||
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/dropbox-text-logo.svg`)}`}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="AWS logo"
|
||||||
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/aws-logo-grey.svg`)}`}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="Twilio logo"
|
||||||
|
src={`${getAssetUrl(`${ASSETS_CDN_URL}/twilio-logo.svg`)}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LeftSideContent;
|
||||||
|
|
@ -24,7 +24,6 @@ import {
|
||||||
LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK,
|
LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK,
|
||||||
NEW_TO_APPSMITH,
|
NEW_TO_APPSMITH,
|
||||||
createMessage,
|
createMessage,
|
||||||
LOGIN_PAGE_SUBTITLE,
|
|
||||||
} from "@appsmith/constants/messages";
|
} from "@appsmith/constants/messages";
|
||||||
import { FormGroup } from "design-system-old";
|
import { FormGroup } from "design-system-old";
|
||||||
import { Button, Link, Callout } from "design-system";
|
import { Button, Link, Callout } from "design-system";
|
||||||
|
|
@ -33,7 +32,11 @@ import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
|
||||||
import { isEmail, isEmptyString } from "utils/formhelpers";
|
import { isEmail, isEmptyString } from "utils/formhelpers";
|
||||||
import type { LoginFormValues } from "pages/UserAuth/helpers";
|
import type { LoginFormValues } from "pages/UserAuth/helpers";
|
||||||
|
|
||||||
import { SpacedSubmitForm, FormActions } from "pages/UserAuth/StyledComponents";
|
import {
|
||||||
|
SpacedSubmitForm,
|
||||||
|
FormActions,
|
||||||
|
EmailFormWrapper,
|
||||||
|
} from "pages/UserAuth/StyledComponents";
|
||||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||||
import { LOGIN_SUBMIT_PATH } from "@appsmith/constants/ApiConstants";
|
import { LOGIN_SUBMIT_PATH } from "@appsmith/constants/ApiConstants";
|
||||||
import PerformanceTracker, {
|
import PerformanceTracker, {
|
||||||
|
|
@ -125,10 +128,10 @@ export function Login(props: LoginFormProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const footerSection = isFormLoginEnabled && (
|
const footerSection = isFormLoginEnabled && (
|
||||||
<div className="px-2 py-4 flex align-center justify-center text-base text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
<div className="px-2 flex align-center justify-center text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
{createMessage(NEW_TO_APPSMITH)}
|
{createMessage(NEW_TO_APPSMITH)}
|
||||||
<Link
|
<Link
|
||||||
className="t--sign-up t--signup-link pl-[var(--ads-v2\-spaces-3)]"
|
className="t--sign-up t--signup-link"
|
||||||
kind="primary"
|
kind="primary"
|
||||||
target="_self"
|
target="_self"
|
||||||
to={signupURL}
|
to={signupURL}
|
||||||
|
|
@ -139,11 +142,7 @@ export function Login(props: LoginFormProps) {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container footer={footerSection} title={createMessage(LOGIN_PAGE_TITLE)}>
|
||||||
footer={footerSection}
|
|
||||||
subtitle={createMessage(LOGIN_PAGE_SUBTITLE)}
|
|
||||||
title={createMessage(LOGIN_PAGE_TITLE)}
|
|
||||||
>
|
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{htmlPageTitle}</title>
|
<title>{htmlPageTitle}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
@ -171,7 +170,7 @@ export function Login(props: LoginFormProps) {
|
||||||
<ThirdPartyAuth logins={socialLoginList} type={"SIGNIN"} />
|
<ThirdPartyAuth logins={socialLoginList} type={"SIGNIN"} />
|
||||||
)}
|
)}
|
||||||
{isFormLoginEnabled && (
|
{isFormLoginEnabled && (
|
||||||
<>
|
<EmailFormWrapper>
|
||||||
<SpacedSubmitForm action={loginURL} method="POST">
|
<SpacedSubmitForm action={loginURL} method="POST">
|
||||||
<FormGroup
|
<FormGroup
|
||||||
intent={error ? "danger" : "none"}
|
intent={error ? "danger" : "none"}
|
||||||
|
|
@ -218,12 +217,13 @@ export function Login(props: LoginFormProps) {
|
||||||
</SpacedSubmitForm>
|
</SpacedSubmitForm>
|
||||||
<Link
|
<Link
|
||||||
className="justify-center"
|
className="justify-center"
|
||||||
|
kind="secondary"
|
||||||
target="_self"
|
target="_self"
|
||||||
to={forgotPasswordURL}
|
to={forgotPasswordURL}
|
||||||
>
|
>
|
||||||
{createMessage(LOGIN_PAGE_FORGOT_PASSWORD_TEXT)}
|
{createMessage(LOGIN_PAGE_FORGOT_PASSWORD_TEXT)}
|
||||||
</Link>
|
</Link>
|
||||||
</>
|
</EmailFormWrapper>
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { RESET_PASSWORD_FORM_NAME } from "@appsmith/constants/forms";
|
||||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||||
import { getIsTokenValid, getIsValidatingToken } from "selectors/authSelectors";
|
import { getIsTokenValid, getIsValidatingToken } from "selectors/authSelectors";
|
||||||
import FormTextField from "components/utils/ReduxFormTextField";
|
import FormTextField from "components/utils/ReduxFormTextField";
|
||||||
import { Button, Callout, Link } from "design-system";
|
import { Button, Callout, Icon, Link } from "design-system";
|
||||||
import Spinner from "components/editorComponents/Spinner";
|
import Spinner from "components/editorComponents/Spinner";
|
||||||
import StyledForm from "components/editorComponents/Form";
|
import StyledForm from "components/editorComponents/Form";
|
||||||
import { isEmptyString, isStrongPassword } from "utils/formhelpers";
|
import { isEmptyString, isStrongPassword } from "utils/formhelpers";
|
||||||
|
|
@ -20,7 +20,6 @@ import { AUTH_LOGIN_URL, FORGOT_PASSWORD_URL } from "constants/routes";
|
||||||
import {
|
import {
|
||||||
RESET_PASSWORD_PAGE_PASSWORD_INPUT_LABEL,
|
RESET_PASSWORD_PAGE_PASSWORD_INPUT_LABEL,
|
||||||
RESET_PASSWORD_PAGE_PASSWORD_INPUT_PLACEHOLDER,
|
RESET_PASSWORD_PAGE_PASSWORD_INPUT_PLACEHOLDER,
|
||||||
RESET_PASSWORD_LOGIN_LINK_TEXT,
|
|
||||||
RESET_PASSWORD_SUBMIT_BUTTON_TEXT,
|
RESET_PASSWORD_SUBMIT_BUTTON_TEXT,
|
||||||
RESET_PASSWORD_PAGE_TITLE,
|
RESET_PASSWORD_PAGE_TITLE,
|
||||||
FORM_VALIDATION_INVALID_PASSWORD,
|
FORM_VALIDATION_INVALID_PASSWORD,
|
||||||
|
|
@ -153,18 +152,25 @@ export function ResetPassword(props: ResetPasswordProps) {
|
||||||
if (!isTokenValid && validatingToken) {
|
if (!isTokenValid && validatingToken) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const footerSection = (
|
||||||
|
<div className="px-2 flex items-center justify-center text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
|
<Icon name="arrow-left-line" size="md" />
|
||||||
|
Back to
|
||||||
|
<Link
|
||||||
|
className="text-sm justify-center"
|
||||||
|
kind="primary"
|
||||||
|
target="_self"
|
||||||
|
to={AUTH_LOGIN_URL}
|
||||||
|
>
|
||||||
|
Sign in
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
subtitle={
|
footer={footerSection}
|
||||||
<Link
|
|
||||||
className="text-sm justify-center"
|
|
||||||
startIcon="arrow-left-line"
|
|
||||||
target="_self"
|
|
||||||
to={AUTH_LOGIN_URL}
|
|
||||||
>
|
|
||||||
{createMessage(RESET_PASSWORD_LOGIN_LINK_TEXT)}
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
title={createMessage(RESET_PASSWORD_PAGE_TITLE)}
|
title={createMessage(RESET_PASSWORD_PAGE_TITLE)}
|
||||||
>
|
>
|
||||||
{(showSuccessMessage || showFailureMessage) && (
|
{(showSuccessMessage || showFailureMessage) && (
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ import { AUTH_LOGIN_URL } from "constants/routes";
|
||||||
import { SIGNUP_FORM_NAME } from "@appsmith/constants/forms";
|
import { SIGNUP_FORM_NAME } from "@appsmith/constants/forms";
|
||||||
import type { RouteComponentProps } from "react-router-dom";
|
import type { RouteComponentProps } from "react-router-dom";
|
||||||
import { useHistory, useLocation, withRouter } from "react-router-dom";
|
import { useHistory, useLocation, withRouter } from "react-router-dom";
|
||||||
import { SpacedSubmitForm, FormActions } from "pages/UserAuth/StyledComponents";
|
import {
|
||||||
|
SpacedSubmitForm,
|
||||||
|
FormActions,
|
||||||
|
OrWithLines,
|
||||||
|
} from "pages/UserAuth/StyledComponents";
|
||||||
import {
|
import {
|
||||||
SIGNUP_PAGE_TITLE,
|
SIGNUP_PAGE_TITLE,
|
||||||
SIGNUP_PAGE_EMAIL_INPUT_LABEL,
|
SIGNUP_PAGE_EMAIL_INPUT_LABEL,
|
||||||
|
|
@ -19,8 +23,9 @@ import {
|
||||||
SIGNUP_PAGE_SUBMIT_BUTTON_TEXT,
|
SIGNUP_PAGE_SUBMIT_BUTTON_TEXT,
|
||||||
ALREADY_HAVE_AN_ACCOUNT,
|
ALREADY_HAVE_AN_ACCOUNT,
|
||||||
createMessage,
|
createMessage,
|
||||||
SIGNUP_PAGE_SUBTITLE,
|
|
||||||
GOOGLE_RECAPTCHA_KEY_ERROR,
|
GOOGLE_RECAPTCHA_KEY_ERROR,
|
||||||
|
LOOKING_TO_SELF_HOST,
|
||||||
|
VISIT_OUR_DOCS,
|
||||||
} from "@appsmith/constants/messages";
|
} from "@appsmith/constants/messages";
|
||||||
import FormTextField from "components/utils/ReduxFormTextField";
|
import FormTextField from "components/utils/ReduxFormTextField";
|
||||||
import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
|
import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
|
||||||
|
|
@ -54,13 +59,14 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||||
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
||||||
import { getHTMLPageTitle } from "@appsmith/utils/BusinessFeatures/brandingPageHelpers";
|
import { getHTMLPageTitle } from "@appsmith/utils/BusinessFeatures/brandingPageHelpers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import { SELF_HOSTING_DOC } from "constants/ThirdPartyConstants";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
grecaptcha: any;
|
grecaptcha: any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { googleRecaptchaSiteKey } = getAppsmithConfigs();
|
const { cloudHosting, googleRecaptchaSiteKey } = getAppsmithConfigs();
|
||||||
|
|
||||||
const validate = (values: SignupFormValues) => {
|
const validate = (values: SignupFormValues) => {
|
||||||
const errors: SignupFormValues = {};
|
const errors: SignupFormValues = {};
|
||||||
|
|
@ -171,25 +177,40 @@ export function SignUp(props: SignUpFormProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const footerSection = (
|
const footerSection = (
|
||||||
<div className="px-2 py-4 flex align-center justify-center text-base text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
<>
|
||||||
{createMessage(ALREADY_HAVE_AN_ACCOUNT)}
|
<div className="px-2 flex align-center justify-center text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
<Link
|
{createMessage(ALREADY_HAVE_AN_ACCOUNT)}
|
||||||
className="t--sign-up t--signup-link pl-[var(--ads-v2\-spaces-3)]"
|
<Link
|
||||||
kind="primary"
|
className="t--sign-up t--signup-link"
|
||||||
target="_self"
|
kind="primary"
|
||||||
to={AUTH_LOGIN_URL}
|
target="_self"
|
||||||
>
|
to={AUTH_LOGIN_URL}
|
||||||
{createMessage(SIGNUP_PAGE_LOGIN_LINK_TEXT)}
|
>
|
||||||
</Link>
|
{createMessage(SIGNUP_PAGE_LOGIN_LINK_TEXT)}
|
||||||
</div>
|
</Link>
|
||||||
|
</div>
|
||||||
|
{cloudHosting && (
|
||||||
|
<>
|
||||||
|
<OrWithLines>or</OrWithLines>
|
||||||
|
<div className="px-2 text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
|
{createMessage(LOOKING_TO_SELF_HOST)}
|
||||||
|
<Link
|
||||||
|
className="t--visit-docs t--visit-docs-link pl-[var(--ads-v2\-spaces-3)] justify-center"
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => AnalyticsUtil.logEvent("VISIT_SELF_HOST_DOCS")}
|
||||||
|
target="_self"
|
||||||
|
to={`${SELF_HOSTING_DOC}?utm_source=cloudSignup`}
|
||||||
|
>
|
||||||
|
{createMessage(VISIT_OUR_DOCS)}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container footer={footerSection} title={createMessage(SIGNUP_PAGE_TITLE)}>
|
||||||
footer={footerSection}
|
|
||||||
subtitle={createMessage(SIGNUP_PAGE_SUBTITLE)}
|
|
||||||
title={createMessage(SIGNUP_PAGE_TITLE)}
|
|
||||||
>
|
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{htmlPageTitle}</title>
|
<title>{htmlPageTitle}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ export const AuthCardBody = styled.div`
|
||||||
export const SpacedForm = styled(Form)``;
|
export const SpacedForm = styled(Form)``;
|
||||||
|
|
||||||
export const SpacedSubmitForm = styled.form`
|
export const SpacedSubmitForm = styled.form`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
&& .bp3-label {
|
&& .bp3-label {
|
||||||
color: var(--ads-v2-color-fg);
|
color: var(--ads-v2-color-fg);
|
||||||
margin-bottom: var(--ads-v2-spaces-2);
|
margin-bottom: var(--ads-v2-spaces-2);
|
||||||
|
|
@ -108,6 +111,15 @@ export const SpacedSubmitForm = styled.form`
|
||||||
&:only-child {
|
&:only-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
.bp3-form-group {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const EmailFormWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FormActions = styled.div`
|
export const FormActions = styled.div`
|
||||||
|
|
@ -117,7 +129,6 @@ export const FormActions = styled.div`
|
||||||
}
|
}
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
margin-top: ${(props) => props.theme.spaces[5]}px;
|
|
||||||
& > label {
|
& > label {
|
||||||
margin-right: ${(props) => props.theme.spaces[11]}px;
|
margin-right: ${(props) => props.theme.spaces[11]}px;
|
||||||
}
|
}
|
||||||
|
|
@ -158,3 +169,29 @@ export const StyledFormGroup = styled(FormGroup)`
|
||||||
margin-bottom: var(--ads-v2-spaces-2);
|
margin-bottom: var(--ads-v2-spaces-2);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const OrWithLines = styled.div`
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
background-color: var(--ads-v2-color-border);
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
height: 1px;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
right: 0.5em;
|
||||||
|
margin-left: -50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
left: 0.5em;
|
||||||
|
margin-right: -50%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,24 @@ import { Button } from "design-system";
|
||||||
|
|
||||||
const ThirdPartyAuthWrapper = styled.div`
|
const ThirdPartyAuthWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--ads-v2-spaces-3);
|
gap: var(--ads-v2-spaces-3);
|
||||||
|
width: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledButton = styled(Button)`
|
||||||
|
flex: 1 0 171px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type SignInType = "SIGNIN" | "SIGNUP";
|
type SignInType = "SIGNIN" | "SIGNUP";
|
||||||
|
|
||||||
|
const startIcon: {
|
||||||
|
[key: string]: string;
|
||||||
|
} = {
|
||||||
|
Google: "google-colored",
|
||||||
|
Github: "github-fill",
|
||||||
|
};
|
||||||
|
|
||||||
function SocialLoginButton(props: {
|
function SocialLoginButton(props: {
|
||||||
logo: string;
|
logo: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -33,7 +45,7 @@ function SocialLoginButton(props: {
|
||||||
url += `?redirectUrl=${encodeURIComponent(redirectUrl)}`;
|
url += `?redirectUrl=${encodeURIComponent(redirectUrl)}`;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Button
|
<StyledButton
|
||||||
href={url}
|
href={url}
|
||||||
kind="secondary"
|
kind="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
@ -55,14 +67,14 @@ function SocialLoginButton(props: {
|
||||||
size="md"
|
size="md"
|
||||||
startIcon={
|
startIcon={
|
||||||
["Google", "Github"].includes(props.name)
|
["Google", "Github"].includes(props.name)
|
||||||
? props.name.toLowerCase() + `-fill`
|
? startIcon[props.name]
|
||||||
: "key-2-line"
|
: "key-2-line"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="login-method" data-testid={`login-with-${props.name}`}>
|
<div className="login-method" data-testid={`login-with-${props.name}`}>
|
||||||
{props.label ?? `Continue with ${props.name}`}
|
{props.label ?? `${props.name}`}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import Container from "./Container";
|
import Container from "./Container";
|
||||||
import { Button, Callout, Link, Text } from "design-system";
|
import { Button, Callout, Icon, Link, Text } from "design-system";
|
||||||
import { AUTH_LOGIN_URL } from "constants/routes";
|
import { AUTH_LOGIN_URL } from "constants/routes";
|
||||||
import {
|
import {
|
||||||
createMessage,
|
createMessage,
|
||||||
DEFAULT_ERROR_MESSAGE,
|
DEFAULT_ERROR_MESSAGE,
|
||||||
FORGOT_PASSWORD_PAGE_LOGIN_LINK,
|
|
||||||
PAGE_CLIENT_ERROR_DESCRIPTION,
|
PAGE_CLIENT_ERROR_DESCRIPTION,
|
||||||
VERIFY_ERROR_ALREADY_VERIFIED_TITLE,
|
VERIFY_ERROR_ALREADY_VERIFIED_TITLE,
|
||||||
VERIFY_ERROR_EXPIRED_TITLE,
|
VERIFY_ERROR_EXPIRED_TITLE,
|
||||||
|
|
@ -97,14 +96,16 @@ const VerificationError = (
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
footer={
|
footer={
|
||||||
<div className="px-2 py-4 flex align-center justify-center text-base text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
<div className="px-2 py-4 flex items-center justify-center text-base text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
|
<Icon name="arrow-left-line" size="md" />
|
||||||
|
Back to
|
||||||
<Link
|
<Link
|
||||||
className="pl-[var(--ads-v2\-spaces-3)]"
|
className="text-sm justify-center pl-[var(--ads-v2\-spaces-3)]"
|
||||||
kind="primary"
|
kind="primary"
|
||||||
target="_self"
|
target="_self"
|
||||||
to={AUTH_LOGIN_URL}
|
to={AUTH_LOGIN_URL}
|
||||||
>
|
>
|
||||||
{createMessage(FORGOT_PASSWORD_PAGE_LOGIN_LINK)}
|
Sign in
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import React from "react";
|
||||||
import Container from "./Container";
|
import Container from "./Container";
|
||||||
import {
|
import {
|
||||||
createMessage,
|
createMessage,
|
||||||
VERIFICATION_PENDING_BODY,
|
|
||||||
VERIFICATION_PENDING_NO_EMAIL,
|
VERIFICATION_PENDING_NO_EMAIL,
|
||||||
VERIFICATION_PENDING_NOT_YOU,
|
VERIFICATION_PENDING_NOT_YOU,
|
||||||
VERIFICATION_PENDING_RESEND_LINK,
|
VERIFICATION_PENDING_RESEND_LINK,
|
||||||
|
|
@ -33,16 +32,21 @@ const VerificationPending = (props: RouteComponentProps<{ email: string }>) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
|
footer={
|
||||||
|
<div className="px-2 flex align-center justify-center text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
|
||||||
|
<Link kind="primary" target="_self" to={AUTH_LOGIN_URL}>
|
||||||
|
{createMessage(VERIFICATION_PENDING_NOT_YOU)}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
testId="verification-pending"
|
testId="verification-pending"
|
||||||
title={createMessage(VERIFICATION_PENDING_TITLE)}
|
title={createMessage(VERIFICATION_PENDING_TITLE)}
|
||||||
>
|
>
|
||||||
<Body>
|
<Body>
|
||||||
<Text kind={"body-m"}>
|
<Text kind={"body-m"}>
|
||||||
{createMessage(VERIFICATION_PENDING_BODY)} <Email>{email}</Email>
|
Click the verification link sent to <Email>{email}</Email> to finish
|
||||||
|
setting up your account.
|
||||||
</Text>
|
</Text>
|
||||||
<Link kind="primary" target="_self" to={AUTH_LOGIN_URL}>
|
|
||||||
{createMessage(VERIFICATION_PENDING_NOT_YOU)}
|
|
||||||
</Link>
|
|
||||||
</Body>
|
</Body>
|
||||||
<Body>
|
<Body>
|
||||||
<Text kind="body-m">
|
<Text kind="body-m">
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,11 @@ import { ThemeProvider } from "styled-components";
|
||||||
import VerificationPending from "./VerificationPending";
|
import VerificationPending from "./VerificationPending";
|
||||||
import VerifyUser from "./VerifyUser";
|
import VerifyUser from "./VerifyUser";
|
||||||
import VerificationError from "./VerificationError";
|
import VerificationError from "./VerificationError";
|
||||||
|
import FooterLinks from "./FooterLinks";
|
||||||
|
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
|
||||||
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
|
import { getTenantConfig } from "@appsmith/selectors/tenantSelectors";
|
||||||
|
import { getAppsmithConfigs } from "@appsmith/configs";
|
||||||
|
|
||||||
const SentryRoute = Sentry.withSentryRouting(Route);
|
const SentryRoute = Sentry.withSentryRouting(Route);
|
||||||
|
|
||||||
|
|
@ -23,11 +28,24 @@ export function UserAuth() {
|
||||||
const lightTheme = useSelector((state: AppState) =>
|
const lightTheme = useSelector((state: AppState) =>
|
||||||
getThemeDetails(state, ThemeMode.LIGHT),
|
getThemeDetails(state, ThemeMode.LIGHT),
|
||||||
);
|
);
|
||||||
|
const isMobileDevice = useIsMobileDevice();
|
||||||
|
const tenantConfig = useSelector(getTenantConfig);
|
||||||
|
const { cloudHosting } = getAppsmithConfigs();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={lightTheme}>
|
<ThemeProvider theme={lightTheme}>
|
||||||
{/* TODO: (Albin) - chnages this to ads-v2 variable once branding is sorted out. */}
|
{/* TODO: (Albin) - chnages this to ads-v2 variable once branding is sorted out. */}
|
||||||
<div className="absolute inset-0 flex flex-col overflow-y-auto auth-container bg-[color:var(--ads-color-background-secondary)] p-4 t--auth-container">
|
<div
|
||||||
|
className={`absolute inset-0 flex flex-col overflow-y-auto auth-container bg-[color:var(--ads-color-background-secondary)] ${
|
||||||
|
!isMobileDevice ? "p-4" : "px-6 py-12"
|
||||||
|
} t--auth-container justify-between`}
|
||||||
|
>
|
||||||
|
{isMobileDevice && (
|
||||||
|
<img
|
||||||
|
className="h-8 mx-auto"
|
||||||
|
src={getAssetUrl(tenantConfig.brandLogoUrl)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Switch location={location}>
|
<Switch location={location}>
|
||||||
<SentryRoute component={Login} exact path={`${path}/login`} />
|
<SentryRoute component={Login} exact path={`${path}/login`} />
|
||||||
<SentryRoute component={SignUp} exact path={`${path}/signup`} />
|
<SentryRoute component={SignUp} exact path={`${path}/signup`} />
|
||||||
|
|
@ -54,6 +72,7 @@ export function UserAuth() {
|
||||||
/>
|
/>
|
||||||
<SentryRoute component={PageNotFound} />
|
<SentryRoute component={PageNotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
{cloudHosting && <FooterLinks />}
|
||||||
</div>
|
</div>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13257,7 +13257,7 @@ __metadata:
|
||||||
d3-geo: ^3.1.0
|
d3-geo: ^3.1.0
|
||||||
dayjs: ^1.10.6
|
dayjs: ^1.10.6
|
||||||
deep-diff: ^1.0.2
|
deep-diff: ^1.0.2
|
||||||
design-system: "npm:@appsmithorg/design-system@2.1.36"
|
design-system: "npm:@appsmithorg/design-system@2.1.37"
|
||||||
design-system-old: "npm:@appsmithorg/design-system-old@1.1.16"
|
design-system-old: "npm:@appsmithorg/design-system-old@1.1.16"
|
||||||
diff: ^5.0.0
|
diff: ^5.0.0
|
||||||
dotenv: ^8.1.0
|
dotenv: ^8.1.0
|
||||||
|
|
@ -17288,9 +17288,9 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"design-system@npm:@appsmithorg/design-system@2.1.36":
|
"design-system@npm:@appsmithorg/design-system@2.1.37":
|
||||||
version: 2.1.36
|
version: 2.1.37
|
||||||
resolution: "@appsmithorg/design-system@npm:2.1.36"
|
resolution: "@appsmithorg/design-system@npm:2.1.37"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@radix-ui/react-dialog": ^1.0.2
|
"@radix-ui/react-dialog": ^1.0.2
|
||||||
"@radix-ui/react-dropdown-menu": ^2.0.4
|
"@radix-ui/react-dropdown-menu": ^2.0.4
|
||||||
|
|
@ -17320,7 +17320,7 @@ __metadata:
|
||||||
react-dom: ^17.0.2
|
react-dom: ^17.0.2
|
||||||
react-router-dom: ^5.0.0
|
react-router-dom: ^5.0.0
|
||||||
styled-components: ^5.3.6
|
styled-components: ^5.3.6
|
||||||
checksum: 410db12c576560c6195d5b9ed776f1172c00985966b39d75fbfff119694f2227c94521e5e6d1c3068dd2d49fbac37975c2bc05b1284a09ef434ac7bd551bf84c
|
checksum: 012936cc603bf5c21bcd6486c35935bc22171f2243dd988cb93f92ed559fcd3245561ceda2f791845dce559de942c2acce8cde1fc8c3d30d45c24d4768aedf72
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user