feat: 🎨 Wedding start refactor, fixes to header and APIs

This commit is contained in:
Bradley Shellnut 2022-07-05 14:38:52 -07:00
parent 7905bdee5b
commit a6ebcbf371
7 changed files with 74 additions and 32 deletions

View file

@ -4,6 +4,7 @@ import Link from 'next/link';
import useUser from '../lib/useUser';
import WeddingStart from './WeddingStart';
import Nav from './Nav';
import useWeddingStart from '../lib/useWeddingStart';
const HeaderStyles = styled.header`
display: grid;
@ -22,6 +23,10 @@ const HeaderStyles = styled.header`
const Header = () => {
const { user } = useUser();
const { timeAsDays, pastWeddingDate } = useWeddingStart({
update: 60000,
});
return (
<HeaderStyles>
<div>
@ -30,11 +35,9 @@ const Header = () => {
<h1 className="center">Name & Name</h1>
</a>
</Link>
{user && user.isLoggedIn === true ? (
{user && user.isLoggedIn === true && !pastWeddingDate ? (
<>
<h2 className="center">
June 3rd, 2030 &#8226; New York, New York
</h2>
<h2 className="center">June 3rd, 2030 @ New York, New York</h2>
<h3 className="center">
Countdown: <WeddingStart /> days!
</h3>

View file

@ -1,17 +1,4 @@
import { useState } from 'react';
import useInterval from '../utils/useInterval';
function useWeddingStart({ update = 60000 }) {
const weddingDate = 1906736400000;
const [timeToWedding, setTime] = useState(weddingDate - Date.now());
useInterval(() => {
setTime(weddingDate - Date.now());
}, update);
return {
timeToWedding,
timeAsDays: Math.ceil(timeToWedding / 1000 / 60 / 60 / 24),
};
}
import useWeddingStart from '../lib/useWeddingStart';
export default function WeddingStart() {
const { timeAsDays } = useWeddingStart({

17
lib/useWeddingStart.js Normal file
View file

@ -0,0 +1,17 @@
import { useState } from 'react';
import useInterval from '../utils/useInterval';
export default function useWeddingStart({ update = 60000 }) {
const weddingDate = 1906736400000;
const [timeToWedding, setTime] = useState(
weddingDate - Date.now() <= 0 ? 0 : weddingDate - Date.now()
);
useInterval(() => {
const time = weddingDate - Date.now();
setTime(time <= 0 ? 0 : time);
}, update);
return {
timeToWedding,
timeAsDays: Math.ceil(timeToWedding / 1000 / 60 / 60 / 24),
};
}

29
package-lock.json generated
View file

@ -18,6 +18,7 @@
"cloudinary-build-url": "^0.2.4",
"dotenv": "^16.0.1",
"escape-html": "^1.0.3",
"html-escaper": "^3.0.3",
"iron-session": "^6.1.3",
"jsonwebtoken": "^8.5.1",
"mongodb": "^4.7.0",
@ -6885,10 +6886,9 @@
}
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
"integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="
},
"node_modules/htmlparser2": {
"version": "7.2.0",
@ -7496,6 +7496,12 @@
"node": ">=8"
}
},
"node_modules/istanbul-reports/node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
"node_modules/jest": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
@ -17485,10 +17491,9 @@
}
},
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
"integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="
},
"htmlparser2": {
"version": "7.2.0",
@ -17906,6 +17911,14 @@
"requires": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
},
"dependencies": {
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
}
}
},
"jest": {

View file

@ -20,6 +20,7 @@
"cloudinary-build-url": "^0.2.4",
"dotenv": "^16.0.1",
"escape-html": "^1.0.3",
"html-escaper": "^3.0.3",
"iron-session": "^6.1.3",
"jsonwebtoken": "^8.5.1",
"mongodb": "^4.7.0",
@ -142,4 +143,4 @@
}
}
}
}
}

View file

@ -50,6 +50,7 @@ export default withSession(async (req, res) => {
}
response.guests = guestList;
response.note = group?.note || '';
response.statusUpdatable = group?.statusUpdatable || false;
// console.log('response', response);
res.status(200).json(JSON.stringify(response));
} catch (error) {

View file

@ -1,6 +1,7 @@
import Head from 'next/head';
import { useState } from 'react';
import styled, { keyframes } from 'styled-components';
import { unescape } from 'html-escaper';
import GuestRSVP from '../../components/GuestRSVP';
import Layout from '../../components/Layout';
import useForm from '../../lib/useForm';
@ -139,7 +140,7 @@ const ModalContentStyles = styled.div`
`;
export default function SingleGroupPage({ group }) {
const { guests, note } = group;
const { guests, note, statusUpdatable } = group;
const { user } = useUser({ redirectTo: '/login' });
const [errorMsg, setErrorMsg] = useState('');
const [errorCount, setErrorCount] = useState(0);
@ -274,8 +275,22 @@ export default function SingleGroupPage({ group }) {
</a>
</ErrorContactStyles>
)}
<fieldset aria-busy={loading} disabled={loading}>
<fieldset aria-busy={loading} disabled={loading || !statusUpdatable}>
<legend>RSVP Invitation</legend>
<p>Make sure to click the "Submit RSVP" button at the bottom!</p>
{statusUpdatable && (
<p>
Please accept or decline for each person in your party. You can
always update your response until the RSVP deadline.
</p>
)}
{!statusUpdatable && (
<p>
This section is no longer updatable. If you need to make changes
please contact us at{' '}
<a href="mailto:name@example.com">name@example.com</a>
</p>
)}
{group.guests.map((guest) => (
<GuestRSVP
key={guest.id}
@ -433,6 +448,7 @@ export async function getServerSideProps({ params }) {
},
];
group.note = '';
group.statusUpdatable = true;
return { props: { group } };
}
@ -448,8 +464,12 @@ export async function getServerSideProps({ params }) {
firstName: guestData.firstName,
lastName: guestData.lastName,
rsvpStatus: guestData.rsvpStatus || '',
dietaryNotes: guestData.dietaryNotes || '',
songRequests: guestData.songRequests || '',
dietaryNotes: guestData.dietaryNotes
? unescape(guestData.dietaryNotes)
: '',
songRequests: guestData.songRequests
? unescape(guestData.songRequests)
: '',
hasPlusOne: guestData.hasPlusOne || false,
plusOne: guestData.plusOne || false,
plusOneFirstName: guestData.plusOneFirstName || '',
@ -458,7 +478,7 @@ export async function getServerSideProps({ params }) {
guestList.push(guest);
}
group.guests = guestList;
group.note = groupData.note || '';
group.note = groupData.note ? unescape(groupData.note) : '';
return { props: { group } };
} catch (error) {