mirror of
https://github.com/BradNut/weddingsite
synced 2025-09-08 17:40:36 +00:00
Change modal component to reach-ui modal.
This commit is contained in:
parent
e84e20e0f1
commit
27b650e5ff
6 changed files with 15022 additions and 138 deletions
|
|
@ -1,95 +1,113 @@
|
|||
import { createPortal } from 'react-dom';
|
||||
import { DialogContent, DialogOverlay } from '@reach/dialog';
|
||||
import VisuallyHidden from '@reach/visually-hidden';
|
||||
import '@reach/dialog/styles.css';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const ModalOverlayStyles = styled.div`
|
||||
background-color: #999999;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
opacity: 0.5;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
z-index: 500;
|
||||
const DialogStyles = styled.div`
|
||||
@media (max-width: 1000px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 55vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 60vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 650px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 70vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 80vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 550px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 90vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 500px) {
|
||||
div[data-reach-dialog-content] {
|
||||
width: 95vw;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const ModalWrapperStyles = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
outline: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
position: fixed;
|
||||
top: 25%;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
const ModalCloseStyles = styled.button`
|
||||
color: var(--black);
|
||||
font-size: 2.5rem;
|
||||
text-shadow: none;
|
||||
|
||||
&:hover {
|
||||
transition: 0.3s ease transform;
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
`;
|
||||
|
||||
const ModalStyles = styled.div`
|
||||
align-items: center;
|
||||
background: var(--background);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 1.8rem;
|
||||
max-width: 500px;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
`;
|
||||
const StandardModalHeader = (props) => {
|
||||
const { onHide, caption } = props;
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="modal-header"
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<div className="modal-title">{caption}</div>
|
||||
<ModalCloseStyles
|
||||
type="button"
|
||||
className="close-button"
|
||||
onClick={onHide}
|
||||
>
|
||||
<VisuallyHidden>Close</VisuallyHidden>
|
||||
<span>×</span>
|
||||
</ModalCloseStyles>
|
||||
</div>
|
||||
<hr />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ModalHeaderStyles = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.8rem 0.95rem;
|
||||
`;
|
||||
|
||||
const ModalTitleStyles = styled.h2`
|
||||
margin-bottom: 0.4rem;
|
||||
`;
|
||||
|
||||
const ModalButtonStyles = styled.button`
|
||||
// border-top: 1px solid var(--primary);
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
padding: 2rem;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const ModalDescriptionStyles = styled.span`
|
||||
padding: 2rem;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const Modal = ({ isVisible, hideModal, title, message, children }) =>
|
||||
isVisible
|
||||
? createPortal(
|
||||
<>
|
||||
<ModalOverlayStyles />
|
||||
<ModalWrapperStyles
|
||||
aria-modal
|
||||
aria-hidden={!isVisible}
|
||||
tabIndex={-1}
|
||||
role="dialog"
|
||||
aria-label={title}
|
||||
>
|
||||
<ModalStyles>
|
||||
<ModalHeaderStyles>
|
||||
<ModalTitleStyles>{title}</ModalTitleStyles>
|
||||
<ModalDescriptionStyles>
|
||||
{message}
|
||||
{children}
|
||||
</ModalDescriptionStyles>
|
||||
</ModalHeaderStyles>
|
||||
<ModalButtonStyles type="button" onClick={hideModal}>
|
||||
Close
|
||||
</ModalButtonStyles>
|
||||
</ModalStyles>
|
||||
</ModalWrapperStyles>
|
||||
</>,
|
||||
document.body
|
||||
)
|
||||
: null;
|
||||
|
||||
export default Modal;
|
||||
export default function Modal({
|
||||
isOpen,
|
||||
onHide,
|
||||
contentLabel,
|
||||
headerCaption,
|
||||
focusRef = null,
|
||||
children,
|
||||
}) {
|
||||
return (
|
||||
<DialogOverlay
|
||||
allowPinchZoom
|
||||
initialFocusRef={focusRef}
|
||||
onDismiss={onHide}
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogStyles>
|
||||
<DialogContent
|
||||
aria-label={contentLabel}
|
||||
style={{
|
||||
background: 'var(--modalBackground)',
|
||||
boxShadow: 'var(--level-4)',
|
||||
borderRadius: 'var(--borderRadius)',
|
||||
maxWidth: '55rem',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<StandardModalHeader caption={headerCaption} onHide={onHide} />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</DialogStyles>
|
||||
</DialogOverlay>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ const GlobalStyles = createGlobalStyle`
|
|||
--linkHover: var(--lightViolet);
|
||||
--lightHairLine: var(--lightGrey);
|
||||
|
||||
/* Modal */
|
||||
--modalBackground: var(--background);
|
||||
|
||||
/* Styles */
|
||||
--line: solid 1px var(--lineColor);
|
||||
|
||||
|
|
|
|||
14843
package-lock.json
generated
Normal file
14843
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
48
package.json
48
package.json
|
|
@ -9,45 +9,49 @@
|
|||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reach/dialog": "^0.16.2",
|
||||
"@reach/portal": "^0.16.2",
|
||||
"@reach/visually-hidden": "^0.16.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-plugin-styled-components": "^1.12.0",
|
||||
"babel-plugin-styled-components": "^1.13.3",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cloudinary-build-url": "^0.2.1",
|
||||
"dotenv": "^10.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mongodb": "^3.6.9",
|
||||
"mongoose": "^5.12.13",
|
||||
"next": "^10.2.3",
|
||||
"mongodb": "^4.1.4",
|
||||
"mongoose": "^6.0.12",
|
||||
"next": "^11.1.2",
|
||||
"next-iron-session": "^4.2.0",
|
||||
"next-with-apollo": "^5.1.1",
|
||||
"next-with-apollo": "^5.2.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-icons": "^4.2.0",
|
||||
"styled-components": "^5.3.0",
|
||||
"react-icons": "^4.3.1",
|
||||
"styled-components": "^5.3.1",
|
||||
"swr": "^0.5.6",
|
||||
"waait": "^1.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.4",
|
||||
"@typescript-eslint/eslint-plugin": "^4.26.1",
|
||||
"@typescript-eslint/parser": "^4.26.1",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/preset-env": "^7.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.32.0",
|
||||
"@typescript-eslint/parser": "^4.32.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.28.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb": "^18.2.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-wesbos": "^2.0.0-beta.7",
|
||||
"eslint-plugin-html": "^6.1.2",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"prettier": "^2.3.1",
|
||||
"typescript": "^4.3.2"
|
||||
"eslint-config-wesbos": "^2.1.0",
|
||||
"eslint-plugin-html": "^6.2.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.27.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"prettier": "^2.4.1",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
|
@ -108,4 +112,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ import Group from '../../models/Group';
|
|||
import Guest from '../../models/Guest';
|
||||
import connectDb from '../../utils/db';
|
||||
import { CalendarIcon, MapIcon } from '../../lib/svgs';
|
||||
import useModal from '../../lib/useModal';
|
||||
import Modal from '../../components/Modal';
|
||||
|
||||
const RSVPGroupStyles = styled.div`
|
||||
|
|
@ -131,6 +130,14 @@ const ErrorContactStyles = styled.p`
|
|||
}
|
||||
`;
|
||||
|
||||
const ModalContentStyles = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
export default function SingleGroupPage({ group }) {
|
||||
const { guests, note } = group;
|
||||
const { user } = useUser({ redirectTo: '/login' });
|
||||
|
|
@ -139,9 +146,12 @@ export default function SingleGroupPage({ group }) {
|
|||
const [message, setMessage] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [groupHasPlusOne, setGroupHasPlusOne] = useState(false);
|
||||
const { isVisible, toggleModal } = useModal();
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const address = 'Central Park, New York, New York, USA';
|
||||
|
||||
const openModal = () => setShowModal(true);
|
||||
const closeModal = () => setShowModal(false);
|
||||
|
||||
function getInitialFormData() {
|
||||
const initial = {};
|
||||
for (const guest of guests) {
|
||||
|
|
@ -163,9 +173,8 @@ export default function SingleGroupPage({ group }) {
|
|||
return initial;
|
||||
}
|
||||
|
||||
const { inputs, handleChange, clearForm, resetForm } = useForm(
|
||||
getInitialFormData
|
||||
);
|
||||
const { inputs, handleChange, clearForm, resetForm } =
|
||||
useForm(getInitialFormData);
|
||||
|
||||
if (!user || user.isLoggedIn === false) {
|
||||
return <Layout>Loading...</Layout>;
|
||||
|
|
@ -205,7 +214,7 @@ export default function SingleGroupPage({ group }) {
|
|||
body.guests.length > 1 ? 's' : ''
|
||||
}. Don't forget to save the date!!`
|
||||
);
|
||||
toggleModal();
|
||||
openModal();
|
||||
} else {
|
||||
setErrorCount(errorCount + 1);
|
||||
setErrorMsg('Unable to RSVP Your Group');
|
||||
|
|
@ -370,14 +379,21 @@ export default function SingleGroupPage({ group }) {
|
|||
)}
|
||||
<button type="submit">Submit RSVP</button>
|
||||
</FormStyles>
|
||||
<Modal isVisible={isVisible} hideModal={toggleModal} title="RSVP Success">
|
||||
<p>{message}</p>
|
||||
<div>
|
||||
<p>Monday, June 3, 2030 at 5:00 PM</p>
|
||||
<a href="/myevents.ics" aria-label="Click to add to calendar">
|
||||
<CalendarIcon /> Add to Calendar
|
||||
</a>
|
||||
</div>
|
||||
<Modal
|
||||
isOpen={showModal}
|
||||
onHide={closeModal}
|
||||
contentLabel="RSVP Success"
|
||||
headerCaption={<h2>RSVP Success</h2>}
|
||||
>
|
||||
<ModalContentStyles>
|
||||
<p>{message}</p>
|
||||
<div>
|
||||
<p>Saturday, June 25, 2022 at 5:00 PM</p>
|
||||
<a href="/ibwedding.ics" aria-label="Click to add to calendar">
|
||||
<CalendarIcon /> Add to Calendar
|
||||
</a>
|
||||
</div>
|
||||
</ModalContentStyles>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -389,20 +405,21 @@ export async function getServerSideProps({ params }) {
|
|||
|
||||
// TODO: REMOVE THIS WHEN TAKING YOUR SITE TO PRODUCTION
|
||||
if (process.env.SITE_ENV === 'TEST_SITE') {
|
||||
const group = {};
|
||||
group.id = params.id;
|
||||
group.guests = [{
|
||||
id: 'TEST_GUEST_ID_12345',
|
||||
firstName: 'Test',
|
||||
lastName: 'Lastname',
|
||||
rsvpStatus: false,
|
||||
dietaryNotes: '',
|
||||
songRequests: '',
|
||||
hasPlusOne: true,
|
||||
plusOne: false,
|
||||
plusOneFirstName: '',
|
||||
plusOneLastName: '',
|
||||
}];
|
||||
group.guests = [
|
||||
{
|
||||
id: 'TEST_GUEST_ID_12345',
|
||||
firstName: 'Test',
|
||||
lastName: 'Lastname',
|
||||
rsvpStatus: false,
|
||||
dietaryNotes: '',
|
||||
songRequests: '',
|
||||
hasPlusOne: true,
|
||||
plusOne: false,
|
||||
plusOneFirstName: '',
|
||||
plusOneLastName: '',
|
||||
},
|
||||
];
|
||||
group.note = '';
|
||||
return { props: { group } };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// import mongo from 'mongodb';
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
const url = process.env.MONGO_URL;
|
||||
|
|
|
|||
Loading…
Reference in a new issue