Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone page #893

Merged
merged 10 commits into from
Apr 5, 2024
11 changes: 0 additions & 11 deletions client/src/assets/img/logo.svg

This file was deleted.

2 changes: 1 addition & 1 deletion client/src/components/AuthClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const resetPasswordRequest = async (username?: string) => {
} else {
const params = new URLSearchParams(window.location.search);
await postAuthRequest(
`${BASE_URL}auth/reset_password_request_with_token?u=${params.get("token")}`
`${BASE_URL}auth/reset_password_request_with_token?token=${params.get("token")}`
);
}
return true;
Expand Down
1 change: 0 additions & 1 deletion client/src/components/EmailAlertSignup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ const BuildingSubscribeWithoutI18n = (props: BuildingSubscribeProps) => {
{!isEmailResent && <Trans render="div">Didn’t get the link?</Trans>}
<SendNewLink
setParentState={setIsEmailResent}
variant="secondary"
className="is-full-width"
onClick={() => AuthClient.resendVerifyEmail()}
/>
Expand Down
41 changes: 41 additions & 0 deletions client/src/components/JFLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { SVGProps } from "react";

export const JFLogo = (props: SVGProps<SVGSVGElement>) => (
<svg
width="96"
height="22"
viewBox="0 0 96 22"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M4.8626 15.8124C4.8626 17.6707 4.05216 18.8277 2.1366 18.8277C1.39984 18.8277 1.03146 18.7926 0.331541 18.6524L0 21.5624C0.84727 21.7027 1.58403 21.7728 2.61549 21.7728C6.5203 21.7728 8.25168 19.3536 8.25168 15.8826V0.455792H4.8626V15.8124Z"
fill="currentColor"
/>
<path
d="M23.1845 21.4923H26.3894V5.11889H23.1845V14.8307C23.1845 17.5655 21.4163 19.1082 18.4693 19.1082C15.3749 19.1082 14.3434 17.0746 14.3434 14.8307V5.11889H11.1386V15.6021C11.1386 19.1082 12.6857 21.913 17.1431 21.913C20.1638 21.913 22.4109 20.4054 23.1477 17.0746H23.1845V21.4923Z"
fill="currentColor"
/>
<path
d="M36.1592 21.913C40.8008 21.913 43.0111 19.9496 43.0111 16.9695C43.0111 14.4451 41.2797 12.8323 36.5644 12.0609C33.028 11.5 32.1439 10.6585 32.1439 9.29113C32.1439 7.92376 33.2859 7.08229 35.4593 7.08229C37.7433 7.08229 38.8852 8.064 39.5115 10.5183L42.569 9.81704C41.7954 6.6265 39.8798 4.69816 35.4593 4.69816C31.1493 4.69816 28.939 6.6265 28.939 9.46643C28.939 12.0259 30.5967 13.5686 35.1278 14.375C38.8115 14.971 39.843 15.6722 39.843 17.0396C39.8062 18.5472 38.6274 19.4938 36.1961 19.4938C32.9543 19.4938 31.7755 17.846 31.1861 15.6021L28.1654 16.1631C28.9022 19.564 30.8177 21.913 36.1592 21.913Z"
fill="currentColor"
/>
<path
d="M46.1377 16.6189C46.1377 19.6691 47.7217 21.913 51.3318 21.913C52.9158 21.913 53.8368 21.7027 55.0156 21.3521L54.6104 18.5472C53.6894 18.7926 52.9158 18.9679 51.9949 18.9679C50.0793 18.9679 49.3426 18.0213 49.3426 16.1981V7.74845H54.8314V5.11889H49.3426V0.596035H46.1377V5.11889H43.5959V7.74845H46.1377V16.6189Z"
fill="currentColor"
/>
<path
d="M70.2788 12.8323V9.78198H60.1484V3.50609H71.4945V0.455792H56.7593V21.4923H60.1484V12.8323H70.2788Z"
fill="currentColor"
/>
<path
d="M77.8197 2.5945V0H74.1727V2.5945H77.8197ZM77.5618 21.4923V5.11889H74.3937V21.4923H77.5618Z"
fill="currentColor"
/>
<path
d="M92.2794 21.4923H96V21.4222L90.1059 13.4283L95.8526 5.18901V5.11889H92.3531L87.7852 12.096L83.1068 5.11889H79.3861V5.18901L85.1697 13.0777L79.2756 21.4222V21.4923H82.8857L87.4536 14.41L92.2794 21.4923Z"
fill="currentColor"
/>
</svg>
);
53 changes: 35 additions & 18 deletions client/src/components/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useState, useContext } from "react";
import { Trans, t } from "@lingui/macro";
import { I18n } from "@lingui/core";
import { withI18n } from "@lingui/react";
import classNames from "classnames";
import { Button, Link as JFCLLink } from "@justfixnyc/component-library";

import "styles/Login.css";
Expand All @@ -28,14 +27,14 @@ enum Step {
RegisterAccount,
RegisterUserType,
VerifyEmail,
LoginSuccess,
}

type LoginProps = {
i18n: I18n;
addr?: AddressRecord;
onBuildingPage?: boolean;
onSuccess?: (user: JustfixUser) => void;
handleRedirect?: () => void;
registerInModal?: boolean;
setLoginRegisterInProgress?: React.Dispatch<React.SetStateAction<boolean>>;
showForgotPassword?: boolean;
Expand All @@ -47,13 +46,12 @@ const LoginWithoutI18n = (props: LoginProps) => {
addr,
onBuildingPage,
onSuccess,
handleRedirect,
registerInModal,
setLoginRegisterInProgress,
} = props;

const userContext = useContext(UserContext);
const { account } = createWhoOwnsWhatRoutePaths();
const { home, account } = createWhoOwnsWhatRoutePaths();

const [showRegisterModal, setShowRegisterModal] = useState(false);

Expand All @@ -63,6 +61,7 @@ const LoginWithoutI18n = (props: LoginProps) => {
const isRegisterAccountStep = step === Step.RegisterAccount;
const isRegisterUserTypeStep = step === Step.RegisterUserType;
const isVerifyEmailStep = step === Step.VerifyEmail;
const isLoginSuccessStep = step === Step.LoginSuccess;

const {
value: email,
Expand Down Expand Up @@ -157,7 +156,7 @@ const LoginWithoutI18n = (props: LoginProps) => {

const renderFooter = () => {
return (
<div className="building-page-footer">
<div className="login-footer">
{isRegisterAccountStep && (
<span className="privacy-links">
<Trans>
Expand Down Expand Up @@ -219,18 +218,27 @@ const LoginWithoutI18n = (props: LoginProps) => {
};

const renderResendVerifyEmail = () => (
<>
<div className="resend-email-container">
{!isEmailResent && (
<Trans render="span" className="resend-verify-label">
<Trans render="p" className="didnt-get-link">
Didn’t get the link?
</Trans>
)}
<SendNewLink
setParentState={setIsEmailResent}
variant="secondary"
size={onBuildingPage ? "small" : "large"}
className="is-full-width"
onClick={() => AuthClient.resendVerifyEmail()}
/>
</div>
);

const renderLoginSuccess = () => (
<>
<Trans render="h1">You are logged in</Trans>
<Trans render="h2">
<JFCLLocaleLink to={home}>Search for an address</JFCLLocaleLink> to add to Building Updates
</Trans>
</>
);

Expand Down Expand Up @@ -291,12 +299,17 @@ const LoginWithoutI18n = (props: LoginProps) => {
return;
}

!!setLoginRegisterInProgress && setLoginRegisterInProgress(false);

if (!onBuildingPage) {
handleRedirect && handleRedirect();
if (resp?.user?.verified) {
setStep(Step.LoginSuccess);
} else {
await AuthClient.resendVerifyEmail();
setStep(Step.VerifyEmail);
}
return;
}

!!setLoginRegisterInProgress && setLoginRegisterInProgress(false);
};

const onAccountSubmit = async () => {
Expand Down Expand Up @@ -433,12 +446,15 @@ const LoginWithoutI18n = (props: LoginProps) => {
const renderLoginFlow = () => {
return (
<div className="Login">
{!!headerText && (
<h4 className={classNames(!onBuildingPage && "page-title")}>{headerText}</h4>
)}
{!!subHeaderText && <div className="card-description">{subHeaderText}</div>}
{!!headerText && (onBuildingPage ? <h4>{headerText}</h4> : <h1>{headerText}</h1>)}
{!!subHeaderText &&
(onBuildingPage ? (
<div className="card-description">{subHeaderText}</div>
) : (
<h2>{subHeaderText}</h2>
))}
{renderAlert()}
{!isVerifyEmailStep && (
{!isVerifyEmailStep && !isLoginSuccessStep && (
<form
className="input-group"
onSubmit={(e) => {
Expand Down Expand Up @@ -468,7 +484,7 @@ const LoginWithoutI18n = (props: LoginProps) => {
setError={setPasswordError}
onChange={onChangePassword}
showPasswordRules={isRegisterAccountStep}
autoFocus={showRegisterModal && !!email && !password}
autoFocus={!!email && !password}
/>
)}
{isRegisterUserTypeStep && (
Expand All @@ -483,14 +499,15 @@ const LoginWithoutI18n = (props: LoginProps) => {
<Button
type="submit"
variant="primary"
size="small"
size={onBuildingPage ? "small" : "large"}
className="is-full-width"
labelText={submitButtonText}
/>
</div>
</form>
)}
{isVerifyEmailStep && renderResendVerifyEmail()}
{isLoginSuccessStep && renderLoginSuccess()}
{(isLoginStep || isRegisterAccountStep) && renderFooter()}
</div>
);
Expand Down
7 changes: 4 additions & 3 deletions client/src/components/SendNewLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import { CheckIcon } from "./Icons";
type SendNewLinkProps = withI18nProps & {
setParentState: React.Dispatch<React.SetStateAction<boolean>>;
onClick: () => void;
variant: "primary" | "secondary" | "tertiary";
variant?: "primary" | "secondary" | "tertiary";
size?: "small" | "large";
className?: string;
};

const SendNewLinkWithoutI18n = (props: SendNewLinkProps) => {
const { setParentState, onClick, variant, className, i18n } = props;
const { setParentState, onClick, variant = "secondary", size = "small", className, i18n } = props;

const [linkSent, setLinkSent] = useState(false);

Expand All @@ -30,7 +31,7 @@ const SendNewLinkWithoutI18n = (props: SendNewLinkProps) => {
<div className="send-new-link">
<Button
variant={variant}
size="small"
size={size}
className={className}
labelText={i18n._(t`Send new link`)}
onClick={handleClick}
Expand Down
63 changes: 63 additions & 0 deletions client/src/components/StandalonePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import classNames from "classnames";
import { withI18n, withI18nProps } from "@lingui/react";
import { Link as JFCLLink } from "@justfixnyc/component-library";

import "styles/StandalonePage.css";
import Page from "./Page";
import { createWhoOwnsWhatRoutePaths } from "routes";
import { JFCLLocaleLink, LocaleLink } from "i18n";
import { Trans } from "@lingui/macro";
import { JFLogo } from "./JFLogo";

export const StandalonePageFooter = () => {
const { home } = createWhoOwnsWhatRoutePaths();
return (
<Trans render="div" className="wow-footer">
<JFCLLocaleLink to={home}>Who Owns What</JFCLLocaleLink> by JustFix.
<br />
Read our{" "}
<JFCLLink
href="https://www.justfix.org/en/privacy-policy/"
target="_blank"
rel="noopener noreferrer"
>
Privacy Policy
</JFCLLink>{" "}
and{" "}
<JFCLLink
href="https://www.justfix.org/en/terms-of-use/"
target="_blank"
rel="noopener noreferrer"
>
Terms of Service
</JFCLLink>
</Trans>
);
};

type StandalonePageProps = withI18nProps & {
title: string;
className: string;
children: React.ReactNode;
};

const StandalonePage = withI18n()((props: StandalonePageProps) => {
const { title, className, children } = props;
const { home } = createWhoOwnsWhatRoutePaths();
return (
<Page title={title}>
<div className={classNames("StandalonePage Page", className)}>
<div className="page-container">
<LocaleLink className="jf-logo" to={home}>
<JFLogo />
</LocaleLink>
<div className="standalone-container">{children}</div>
<StandalonePageFooter />
</div>
</div>
</Page>
);
});

export default StandalonePage;
1 change: 0 additions & 1 deletion client/src/components/UserSettingField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ const EmailSettingFieldWithoutI18n = (props: EmailSettingFieldProps) => {
{!isEmailResent && <Trans render="p">Didn’t get the link?</Trans>}
<SendNewLink
setParentState={setIsEmailResent}
variant="secondary"
onClick={() => AuthClient.resendVerifyEmail()}
/>
</div>
Expand Down
18 changes: 14 additions & 4 deletions client/src/containers/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { useEffect, useState, useContext } from "react";
import { BrowserRouter as Router, Switch, Route, useLocation } from "react-router-dom";
import { Trans, t } from "@lingui/macro";
import logo from "../assets/img/logo.svg";
import logoDivider from "../assets/img/logo-divider.svg";

import "styles/App.css";

Expand Down Expand Up @@ -49,6 +47,8 @@ import ResetPasswordPage from "./ResetPasswordPage";
import ForgotPasswordPage from "./ForgotPasswordPage";
import UnsubscribePage from "./UnsubscribePage";
import LoginPage from "./LoginPage";
import { JFLogo } from "components/JFLogo";
import logoDivider from "../assets/img/logo-divider.svg";

const HomeLink = withI18n()((props: withI18nProps) => {
const { i18n } = props;
Expand All @@ -65,7 +65,7 @@ const HomeLink = withI18n()((props: withI18nProps) => {
}}
to={isLegacyPath(pathname) ? legacy.home : home}
>
<img className="jf-logo" src={logo} width="96" height="22" alt="JustFix" />
<JFLogo className="jf-logo" />
<img
className="jf-logo-divider"
src={logoDivider}
Expand Down Expand Up @@ -264,7 +264,17 @@ const Navbar = () => {

const userContext = useContext(UserContext);

return (
const standalonePages = [
"forgot-password",
"login",
"verify-email",
"forgot-password",
"reset-password",
"unsubscribe",
];
const hideNavbar = standalonePages.some((v) => pathname.includes(`account/${v}`));

return hideNavbar ? null : (
Comment on lines +267 to +277
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't feel like a great way to do this, would be curious what you think. I don't like this sometimes returning null for the component, but I couldn't put this logic in the parent component because it doesn't have the ability to get pathname from the useLocation hook.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i hear ya. i can't think of a better way to do this logically but there is a way to avoid returning a null, like so. tried it locally and it works!

return (
  <>
    {!hideNavbar && (insert JSX element here)}
  </>
);

<div
className={classnames(
"App__header",
Expand Down
Loading