Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create email invite confirmation screen #215

Merged
merged 11 commits into from
Oct 19, 2023
Binary file removed public/bitsOfGood.png
Binary file not shown.
12 changes: 12 additions & 0 deletions public/bitsOfGood.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 66 additions & 4 deletions src/components/InviteBackLink/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import axios from 'axios';

import { CLOUD_FUNCTION_BASE_URL } from '../../constants';
import Spinner from '../Spinner';

import './stylesheet.scss';

// eslint-disable-next-line no-shadow
enum LoadingState {
LOADING,
SUCCESS,
ERROR,
}

const handleInvite = async (inviteId: string | undefined): Promise<void> =>
// The link should be changed to prod link, or we can choose the link based
Expand All @@ -20,14 +30,66 @@ const handleInvite = async (inviteId: string | undefined): Promise<void> =>
export default function InviteBackLink(): React.ReactElement {
const navigate = useNavigate();
const { id } = useParams();
const [state, setState] = useState(LoadingState.LOADING);

useEffect(() => {
if (id && navigate) {
handleInvite(id)
.then(() => navigate('/'))
.catch(() => navigate('/'));
.then(() => {
setState(LoadingState.SUCCESS);
setTimeout(() => {
navigate('/');
}, 5000);
})
.catch(() => {
setState(LoadingState.ERROR);
setTimeout(() => {
navigate('/');
}, 10000);
});
}
}, [id, navigate]);

return <div />;
if (state === LoadingState.LOADING) {
return (
<div className="Loading">
<Spinner size="normal" style={{ opacity: 0.6 }} />
<h4>Loading</h4>
<div>friend schedule invite</div>
</div>
);
}

return (
<div className="EmailInviteConfirmation">
{state === LoadingState.SUCCESS ? (
<h1>Congratulations on Adding a New Schedule to your View!</h1>
) : (
<h1>We&apos;ve Encountered an Error, Please Try Again</h1>
)}
<p>You are being redirected to our main site, please wait...</p>
<p>
If you have not been redirected in 30 seconds, please click the button
below
</p>
<button
type="button"
className="continue-button"
onClick={(): void => {
navigate('/');
}}
>
Continue
</button>

<a className="footer" href="https://bitsofgood.org/">
<img
alt="Bits of Good Logo"
height={44}
width={243}
src="/bitsOfGood.svg"
/>
</a>
</div>
);
}
79 changes: 79 additions & 0 deletions src/components/InviteBackLink/stylesheet.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@import '../../variables';

body {
background-color: $theme-dark-background;
color: $theme-dark-foreground;
}

.Loading {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;

h4 {
font-size: 1.4rem;
margin-top: 12px;
margin-bottom: 8px;
}
}

.EmailInviteConfirmation {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 20vh;
padding-left: 32px;
padding-right: 32px;
font-size: 24px;
height: 100%;
text-align: center;

@media (max-width: 720px) {
padding-top: 60px;
}

@media (max-width: 450px) {
padding-top: 60px;
font-size: 18px;
}

@media (max-width: 300px) {
font-size: 16px;
}

@media (max-height: 600px) {
padding-top: 60px;
}

h1 {
font-size: 36px;
font-weight: 600;

@media (max-width: 450px) {
font-size: 30px;
}

@media (max-width: 300px) {
font-size: 24px;
}
}

.footer {
position: absolute;
bottom: 38px;
}

.continue-button {
background-color: #fe7c53;
color: white;
margin-top: 96px;
padding: 8px 24px;
border: none;
border-radius: 16px;
cursor: pointer;
font-size: 24px;
font-weight: 600;
}
}