Search code examples
cssreactjstypescriptreact-routerstyled-components

Conditionally render JSX on specific routes


I built a React Component Layout for SplitScreen pages (the bottom layout design on the screen shot).

enter image description here

The problem is that the LoginPage layout (the top layout design on the screen shot) I won't need the backArrowIcon at to top, as you can better see on the second screen shot.

enter image description here

I also would have to change the Left<->Right split display on the screen on the LoginPage container.

Anyone has a clue of what can I do to solve my two problems?

Here's also my SplitScreen Component code:

import React from 'react';
import { Link, useHistory, withRouter } from 'react-router-dom';

import logoImg from '../../assets/images/logo.svg';
import backIcon from '../../assets/images/icons/back.svg';

import './styles.css';

function SplitScreen(props: { children: React.ReactNode; }) {
  return (
    <section className="split-page-container">
      <div className="right-side">
        <Link
          className="back-arrow"                 // Here's the backArrowIcon
          to="/">
          <img src={backIcon} alt="Voltar" />
        </Link>
        <div className="proffy">
          <div className="proffy-fundo">
            <img src={logoImg} alt="Proffy Logo" />
            <h2>Sua plataforma de <br /> estudos online.</h2>
          </div>
        </div>
      </div>

      <div className="left-side">
        <div className="content-box">
          {props.children}
        </div>
      </div>
    </section>
  );
}

export default SplitScreen;

and here's my CSS:

.split-page-container {
  width: 100vw;
  height: 100vh;

  display: flex;
  flex-flow: column nowrap;
}

.left-side, .right-side {
  display: flex;
  flex-direction: column;
  flex: 1;
  align-items: center;
  justify-content: center;
}

.left-side {
  background: var(--color-background);
}

.right-side {
  background: var(--color-primary);
}

.content-box {
  padding: 5.6rem 3.2rem;
}

.back-arrow {
  align-self: flex-start;
  padding: 1.2rem 1.8rem;
  height: 0;
  color: var(--color-text-in-primary);
}

.right-side a {
  transition: opacity 0.2s;
}

.right-side a:hover {
  opacity: 0.6;
}

.proffy {
  height: 37.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.proffy-fundo {
  display: flex;
  flex-flow: column;
  align-items: center;
  justify-content: center;
  width: 23.8rem;
  height: 26.6rem;
  background-image: url('../../assets/images/success-background.svg');
  background-position: center;
  background-size: contain;
}

.proffy-fundo img {
  width: 16rem;
}

.proffy-fundo h2 {
  width: 16rem;
  
  text-align: left;
  font-weight: 500;
  font-size: 1.6rem;
  margin-top: 0.8rem;

  color: var(--color-text-in-primary);
}

@media (min-width: 1100px) {
  .split-page-container {
    flex-flow: row-reverse nowrap;       // How can I delete this .split-page-container styling on
  }                                      // my LoginPage container?

  .back-arrow {
    color: var(--color-primary-darker);
    transform: translate(-39vw, -23vh);
  }

  .right-side a {
    transition: opacity 0.2s;
  }
  
  .right-side a:hover {
    opacity: 0.8;
  }

  .proffy-fundo {
    width: 40rem;
    height: 58.4rem;
  }

  .proffy-fundo img {
    width: 33.4rem;
  }

  .proffy-fundo h2 {
    width: 33.4rem;

    text-align: left;
    font-weight: 500;
    font-size: 2.4rem;
    line-height: 3.4rem;
    margin-top: 0.8rem;
  }
}

Solution

  • You can use the location pathname and check if on your login route.

    useLocation

    If not on your login route then conditionally render the back button.

    import React from 'react';
    import { Link, useLocation, useHistory, withRouter } from 'react-router-dom';
    
    import logoImg from '../../assets/images/logo.svg';
    import backIcon from '../../assets/images/icons/back.svg';
    
    import './styles.css';
    
    function SplitScreen(props: { children: React.ReactNode; }) {
      const { pathname } = useLoction();
    
      const showBack = !pathname.startsWith("/login");
    
      return (
        <section className="split-page-container">
          <div className="right-side">
            {showBack && (
              <Link
                className="back-arrow"
                to="/">
                <img src={backIcon} alt="Voltar" />
              </Link>
            )}
            <div className="proffy">
              <div className="proffy-fundo">
                <img src={logoImg} alt="Proffy Logo" />
                <h2>Sua plataforma de <br /> estudos online.</h2>
              </div>
            </div>
          </div>
    
          <div className="left-side">
            <div className="content-box">
              {props.children}
            </div>
          </div>
        </section>
      );
    }
    

    If you simply want to swap the left and right sides you can swap the classnames.

    function SplitScreen(props: { children: React.ReactNode; }) {
      const { pathname } = useLoction();
    
      const showBack = !pathname.startsWith("/login");
    
      return (
        <section className="split-page-container">
          <div className="left-side"> // <-- now the left side
            {showBack && (
              <Link
                className="back-arrow"
                to="/">
                <img src={backIcon} alt="Voltar" />
              </Link>
            )}
            <div className="proffy">
              <div className="proffy-fundo">
                <img src={logoImg} alt="Proffy Logo" />
                <h2>Sua plataforma de <br /> estudos online.</h2>
              </div>
            </div>
          </div>
    
          <div className="right-side"> // <-- now the right side
            <div className="content-box">
              {props.children}
            </div>
          </div>
        </section>
      );
    }