Skip to content

Commit

Permalink
SSO: Show modal on disconnection (#88552)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Grullon <[email protected]>
  • Loading branch information
2 people authored and billrobbins committed Mar 20, 2024
1 parent 1603b30 commit 2f43194
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 48 deletions.
49 changes: 49 additions & 0 deletions client/components/survey-modal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# SurveyModal

Simple modal component that links to a survey.

## Example Usage

```js
import { useState } from 'react';
import ReactDOM from 'react-dom';

import SurveyModal from 'calypso/components/survey-modal';
import surveyImage from 'calypso/assets/images/illustrations/illustration-seller.svg';

function MyComponent() {
const [ isModalVisible, setIsModalVisible ] = useState( false );

return <>
<div>Content</div>
{ isModalVisible &&
ReactDOM.createPortal(
<SurveyModal
name="sso-disable"
url="https://wordpressdotcom.survey.fm/sso-disable-survey?initiated-from=calypso"
heading={ translate( 'SSO Survey' ) }
title={ translate( 'Hi there!' ) }
description={ translate(
`Spare a moment? We'd love to hear why you want to disable SSO in a quick survey.`
) }
surveyImage={ surveyImage }
dismissText={ translate( 'Remind later' ) }
confirmText={ translate( 'Take survey' ) }
/>,
document.body
) };
</>
}
```

## Props

- `name` - (string) The name to use for cookie management. Recommended to use Kebap case.
- `className` - (string) Additional className for the modal.
- `url` - (string) The url to which the confirm button links to.
- `heading` - _optional_ (string) Heading of the modal
- `title` - _optional_ (string) Title text
- `surveyImage` - _optional_ (string) Image to display in the modal
- `description` - (string) Description text
- `dismissText` - (string) Text for the dismiss button
- `confirmText` - (string) Text for the confirm button
109 changes: 109 additions & 0 deletions client/components/survey-modal/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Gridicon } from '@automattic/components';
import { Button } from '@wordpress/components';
import { useState } from '@wordpress/element';
import classNames from 'classnames';
import cookie from 'cookie';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { getCurrentUserId } from 'calypso/state/current-user/selectors';
import './style.scss';

const SurveyModal = ( {
name,
className,
url,
heading,
title,
surveyImage,
description,
dismissText,
confirmText,
} ) => {
const userId = useSelector( getCurrentUserId );
const href = new URL( url );
href.searchParams.set( 'user-id', userId );

const [ hideNotice, setHideNotice ] = useState(
'dismissed' === cookie.parse( document.cookie )?.sso_survey
);

const setSurveyCookie = ( value, maxAge ) => {
document.cookie = cookie.serialize( name, value, {
path: '/',
maxAge,
} );
};

const onClose = () => {
setSurveyCookie( 'dismissed', 365 * 24 * 60 * 60 ); // 1 year
setHideNotice( true );
};

if ( hideNotice ) {
return null;
}

return (
<div className={ classNames( 'modal-survey-notice', className ) }>
<Button className="modal-survey-notice__backdrop" onClick={ onClose } />
<div className="modal-survey-notice__popup">
{ heading && (
<div className="modal-survey-notice__popup-head">
<div className="modal-survey-notice__popup-head-title">{ heading }</div>
<Button onClick={ onClose } className="modal-survey-notice__popup-head-close">
<Gridicon icon="cross" size={ 16 } />
</Button>
</div>
) }

{ ! heading && (
<Button onClick={ onClose } className="modal-survey-notice__popup-head-close">
<Gridicon icon="cross" size={ 16 } />
</Button>
) }

{ surveyImage && (
<div className="modal-survey-notice__popup-img">
<img src={ surveyImage } alt={ heading } />
</div>
) }

<div className="modal-survey-notice__popup-content">
{ title && <div className="modal-survey-notice__popup-content-title">{ title }</div> }
<div className="modal-survey-notice__popup-content-description">{ description }</div>
<div className="modal-survey-notice__popup-content-buttons">
<Button
className="modal-survey-notice__popup-content-buttons-cancel"
onClick={ onClose }
>
{ dismissText }
</Button>
<Button
className="modal-survey-notice__popup-content-buttons-ok"
href={ href.toString() }
target="_blank"
rel="noopener noreferrer"
onClick={ onClose }
>
{ confirmText }
</Button>
</div>
</div>
</div>
</div>
);
};

SurveyModal.propTypes = {
name: PropTypes.string.isRequired,
className: PropTypes.string,
url: PropTypes.string.isRequired,
heading: PropTypes.string,
title: PropTypes.string,
surveyImage: PropTypes.string,
description: PropTypes.string.isRequired,
dismissText: PropTypes.string.isRequired,
confirmText: PropTypes.string.isRequired,
};

export default SurveyModal;
114 changes: 114 additions & 0 deletions client/components/survey-modal/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.modal-survey-notice {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 1000;

.modal-survey-notice__backdrop {
background: var(--studio-black);
opacity: 0.2;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
cursor: default;
}


.modal-survey-notice__popup {
position: absolute;
right: 25px;
bottom: 25px;
width: 416px;
max-width: calc(100% - 50px);
z-index: 2;
border-radius: 2px;
box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.04), 0 3px 8px 0 rgba(0, 0, 0, 0.12);
overflow: hidden;

.modal-survey-notice__popup-head {
background: #0675c4;
border-bottom: 1px solid #f6f7f7;
height: 56px;
padding: 0 14px 0 16px;
display: flex;
align-items: center;
justify-content: space-between;

.modal-survey-notice__popup-head-title {
color: var(--studio-white);
font-size: rem(14px);
font-weight: 500;
line-height: 20px;
letter-spacing: -0.15px;
}

}

.modal-survey-notice__popup-head-close svg {
fill: var(--studio-white);
}

> .modal-survey-notice__popup-head-close {
position: absolute;
right: 0;
}

.modal-survey-notice__popup-img {
background: #0675c4;
padding-bottom: 57.9%;
height: 0;

img {
width: 100%;
display: block;
}
}

.modal-survey-notice__popup-content {
padding: 1rem;
background: var(--studio-white);

.modal-survey-notice__popup-content-title {
font-size: rem(16px);
font-weight: 500;
line-height: 24px;
letter-spacing: -0.32px;
padding-bottom: 8px;
}

.modal-survey-notice__popup-content-description {
font-size: rem(14px);
line-height: 20px;
letter-spacing: -0.15px;
padding-bottom: 18px;
}

.modal-survey-notice__popup-content-buttons {
display: flex;
justify-content: flex-end;

.modal-survey-notice__popup-content-buttons-ok {
padding: 8px 14px;
background: var(--studio-blue-50);
color: var(--studio-white);
font-size: rem(14px);
line-height: 20px;
letter-spacing: -0.15px;
}

.modal-survey-notice__popup-content-buttons-cancel {
padding: 8px 14px;
color: var(--studio-blue-50);
text-align: center;
font-size: rem(14px);
line-height: 20px;
letter-spacing: -0.15px;
}
}
}
}
}
Loading

0 comments on commit 2f43194

Please sign in to comment.