Skip to content

Commit

Permalink
Merge pull request #1537 from clpetersonucf/issue/improved-invalid-lo…
Browse files Browse the repository at this point in the history
…gin-states-updated

Improved invalid login states
  • Loading branch information
clpetersonucf authored Jan 9, 2024
2 parents 9978e88 + 9b080cb commit d7aabf0
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 56 deletions.
21 changes: 21 additions & 0 deletions src/components/invalid-login-modal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import Modal from './modal'

const InvalidLoginModal = ({onClose}) => (
<Modal onClose={onClose} ignoreClose={true} smaller={true} alert={true}>
<div>
<span className='alert-title'>
Your Session is No Longer Valid
</span>
<p className='alert-description'>Your session with Materia is considered invalid and you have been logged out. You'll have to log back in to see this content.</p>
<span className='buttons'>
<a className='action_button'
onClick={onClose}>
Okay
</a>
</span>
</div>
</Modal>
)

export default InvalidLoginModal
79 changes: 32 additions & 47 deletions src/components/modal.jsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,45 @@
import React from 'react'
import { createPortal } from 'react-dom';
import React, { useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'

import './modal.scss'

class Modal extends React.Component {
constructor( props ) {
super( props )
// create an element div for this modal
this.modalRef = React.createRef()
this.element = document.createElement( 'div' )
this.clickOutsideListener = this.clickOutsideListener.bind(this)
const Modal = (props) => {

// We get hold of the div with the id modal that we have created in index.html
this.modalRoot = document.getElementById( 'modal' )
}
const innerModalRef = useRef(null)

clickOutsideListener(event){
const clickOutsideListener = (event) => {
// Do nothing if clicking ref's element or descendent elements
if (!this.modalRef.current || this.modalRef.current.contains(event.target)) {
return
}
if (!innerModalRef.current || innerModalRef.current.contains(event.target)) return
if (props.ignoreClose != true) props.onClose()
}

if (this.props.ignoreClose !== true) {
this.props.onClose()
}
};
useEffect(() => {

componentDidMount() {
this.modalRoot.appendChild( this.element )
document.addEventListener('mousedown', this.clickOutsideListener)
document.addEventListener('touchstart', this.clickOutsideListener)
}
document.addEventListener('mouseup', clickOutsideListener)
document.addEventListener('touchend', clickOutsideListener)

componentWillUnmount() {
this.modalRoot.removeChild( this.element )
document.removeEventListener('mousedown', this.clickOutsideListener)
document.removeEventListener('touchstart', this.clickOutsideListener)
}
return () => {
document.removeEventListener('mouseup', clickOutsideListener)
document.removeEventListener('touchend', clickOutsideListener)
}

render() {
const stuff = (
<>
<div className={`modal-overlay ${this.props.alert ? 'alert' : ''}`} id='modal-overlay'></div>

<div ref={this.modalRef} className={`modal ${this.props.smaller ? 'small' : ''} ${this.props.noGutter ? 'no-gutter' : ''}`} id='inner-modal'>
<span className='close-button'
id='close-button'
aria-label={`close${this.props.testId ? `-${this.props.testId}-` : '-'}modal`}
onClick={this.props.onClose}>X</span>
<div className={`modal-guts ${this.props.noGutter ? 'no-gutter' : ''}`}>
{this.props.children}
</div>
},[])

const modal =
(<>
<div className={`modal-overlay ${props.alert ? 'alert' : ''}`} id='modal-overlay'></div>
<div ref={innerModalRef} className={`modal ${props.smaller ? 'small' : ''} ${props.noGutter ? 'no-gutter' : ''}`} id='inner-modal'>
<span className='close-button'
id='close-button'
aria-label={`close${props.testId ? `-${props.testId}-` : '-'}modal`}
onClick={props.onClose}>X</span>
<div className={`modal-guts ${props.noGutter ? 'no-gutter' : ''}`}>
{props.children}
</div>
</>
)
return createPortal( stuff, this.element );
}
</div>
</>)

return createPortal(modal, document.getElementById('modal'))
}

export default Modal
4 changes: 3 additions & 1 deletion src/components/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
z-index: 1003;
width: 540px;
min-height: 200px;

text-align: center;
}
}
.closed {
Expand Down Expand Up @@ -102,7 +104,7 @@

.alert-title {
border-bottom: solid 1px #bebebe;
text-align: left;
text-align: center;
position: static;
display: block;
font-weight: bold;
Expand Down
8 changes: 5 additions & 3 deletions src/components/my-widgets-collaborate-dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,11 @@ const MyWidgetsCollaborateDialog = ({onClose, inst, myPerms, otherUserPerms, set
if (state.shareNotAllowed === true) {
noShareWarningRender = (
<Modal onClose={disableShareNotAllowed} smaller={true} alert={true}>
<span className='alert-title'>Share Not Allowed</span>
<p className='alert-description'>Access must be set to "Guest Mode" to collaborate with students.</p>
<button className='alert-btn' onClick={disableShareNotAllowed}>Okay</button>
<div>
<span className='alert-title'>Share Not Allowed</span>
<p className='alert-description'>Access must be set to "Guest Mode" to collaborate with students.</p>
<button className='action_button' onClick={disableShareNotAllowed}>Okay</button>
</div>
</Modal>
)
}
Expand Down
14 changes: 9 additions & 5 deletions src/components/my-widgets-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import rawPermsToObj from '../util/raw-perms-to-object'
import Header from './header'
import MyWidgetsSideBar from './my-widgets-side-bar'
import MyWidgetSelectedInstance from './my-widgets-selected-instance'
import InvalidLoginModal from './invalid-login-modal'
import LoadingIcon from './loading-icon'
import useInstanceList from './hooks/useInstanceList'
import useCopyWidget from './hooks/useCopyWidget'
Expand Down Expand Up @@ -68,11 +69,6 @@ const MyWidgetsPage = () => {
}
}, [validCode])

// hook associated with the invalidLogin error
useEffect(() => {
if (invalidLogin) window.location.reload();
}, [invalidLogin])

// hook to attach the hashchange event listener to the window
useEffect(() => {
window.addEventListener('hashchange', listenToHashChange)
Expand Down Expand Up @@ -300,6 +296,13 @@ const MyWidgetsPage = () => {
)
}

let invalidLoginRender = null
if (invalidLogin) {
invalidLoginRender = (
<InvalidLoginModal onClose={() => { window.location.href = 'users/logout' }}></InvalidLoginModal>
)
}

/**
* If the user is loading, show a loading screen. If the user is fetching, show a loading screen. If
* the user has no widgets, show a message. If the user has no selected widget, show a message. If the
Expand Down Expand Up @@ -383,6 +386,7 @@ const MyWidgetsPage = () => {
<div className='my_widgets'>

{widgetCatalogCalloutRender}
{invalidLoginRender}

<div className='container'>
<div className="container_main-content">
Expand Down

0 comments on commit d7aabf0

Please sign in to comment.