<div id="app"></div>
.modal_overlay{
  position: absolute;
  top:0;
  left:0;
  width:100vw;
  height:100vh;
  background: black;
  opacity:0.5;
}

.modal{
   display:flex;
   flex-direction: column;
   width: 50%;
   height: 50%;
  gap:20px;
   padding: 16px;
   border:1px solid black;
   position:relative;
   background:white;
   justify-content:space-between;
  
}
.modal_content {
   align-self: center; 
   text-align:center;
}

.modal_btn{
  align-self:flex-start;
}


.modal_buttons {
   align-self: center;
}

.modal_wrapper{
  display:flex;
  justify-content:center;
  align-items:center;
}
/*
* https://frontendeval.com/questions/modal-overlay
*
* Build a modal control and overlay
*/




const Modal = ({
  onClose, confirmButtonText, onConfirm, modalContent,
}) => {
 
  
  React.useEffect(() => {
    const onKeyDown = (e) => {
      e.code === "Escape" && onClose();
    }
    document.addEventListener("keydown", onKeyDown);
    return () => document.removeEventListener("keydown", onKeyDown)
  }
  , []);
  
  return (
    <div className="modal_wrapper">
      <div className="modal_overlay" onClick={onClose}> </div>
      <div className="modal">
        <button className = "modal_btn" onClick ={onClose}> X </button>
        <div className = "modal_content">
          { modalContent}
        </div>
        <div className = "modal_buttons">
          <button className= "modal_confirm" onClick={onConfirm}> {confirmButtonText}</button>
        </div>
      </div>
    </div>
  )
}

const App = () => {
  const offers = [ 
    {
      id: 0,
      btnText: "Show Offer 1",
      text: "Offer 1 accepted",
    },
    {
      id: 1,
      btnText: "Show Offer 2",
      text: "Offer 2 accepted", 
    },
  
  ]
  
  const [open, setOpen] = React.useState(false);
  const [accepted, setAccepted] = React.useState([false, false]);
  const [currentOffer, setOffer] = React.useState(-1);
  
  const onClose = () => {
    setOpen(false);
  }
  
  const onAccept = () => {
    console.log({
      accepted,
      currentOffer,
    });
    setOpen(false);
    accepted[currentOffer] = true;
    setAccepted([...accepted]);  
  }
 
  const showModal = (id) => {
    setOpen(true);
    setOffer(id);
  }
 
  
  return (
    <>
      {
        offers.map(({
          id, btnText, text,
        }) =>  <> {!accepted[id] ? <button onClick= {() => showModal(id)}>{btnText}</button> :  text }</>)
      }
      { open && <Modal 
        onClose = {onClose}
        confirmButtonText ={"Accept"}
        onConfirm ={onAccept}
        modalContent ={"Click the button to get amazing offers"}
      /> }
    </>
  )
  
}

ReactDOM.render(<App />, document.getElementById('app'));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js