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

Loading Screen to Welcome Screen #875

Merged
merged 4 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 117 additions & 30 deletions src/components/includes/Wrapped.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CloseIcon from '@material-ui/icons/Close';
import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
import "../../styles/Wrapped.scss";
import "../../styles/WrappedAnimation.scss";
import React, { useEffect, useState } from "react";
import firebase from '../../firebase';
import Couple from "../../media/wrapped/couple.svg"
Expand All @@ -13,6 +14,9 @@ import Bus from "../../media/wrapped/bus.svg"
import ConsistentPersonality from "../../media/wrapped/consistent_personality.svg"
import ResourcefulPersonality from "../../media/wrapped/resourceful_personality.svg"
import IndependentPersonality from "../../media/wrapped/independent_personality.svg"
import arrow from '../../media/wrapped/arrow.svg';
import smallPlus from '../../media/wrapped/plus.svg';
import bigPlus from '../../media/wrapped/plus2.svg';

type Props = {
user: FireUser | undefined;
Expand All @@ -22,12 +26,17 @@ type Props = {
type DotProps = {
active: boolean;
};

type DotIndicatorProps = {
showDots: string
}


const Dot = ({active} : DotProps) => (
<div className={`dot ${active ? 'active' : ''}`} />
);

const Wrapped = (props: Props) => {
const Wrapped= (props: Props): JSX.Element => {
const [loading, setLoading] = useState<boolean>(true);
const [stage, setStage] = useState<number>(0);
const [wrappedData, setWrappedData] = useState({
Expand All @@ -42,7 +51,6 @@ const Wrapped = (props: Props) => {
useEffect(() => {

const wrappedRef = firebase.firestore().collection('wrapped');
// eslint-disable-next-line no-console
const fetchData = async () => {
setLoading(true);
try {
Expand All @@ -62,7 +70,6 @@ const Wrapped = (props: Props) => {
// eslint-disable-next-line no-console
console.error("Error fetching data: ", error);
}
setLoading(false);
};

fetchData();
Expand All @@ -86,39 +93,114 @@ const Wrapped = (props: Props) => {
});
};

const DotsIndicator = () => (
<div className="dotsContainer">
const DotsIndicator = ({showDots} : DotIndicatorProps) => (

<div className={"dotsContainer" + showDots}>
{[...Array(totalStages)].map((_, index) => (
<Dot active={index === stage} />
))}
</div>
);

const WrappedAnimationModal = () =>
(
<div className='qmi-container'>

{/* creates first red svg circle. need linear gradient tags here
since didn't import this svg.
make note that width and height are basically the box containing the circle,
so they need to be double the radius
*/}
<svg className="red-circle" width="300" height="300">
{/* this creates the color gradients on the qmi logo */}
<defs>
<linearGradient
id="red-gradient"
x1="24.4251"
y1="-52.6352"
x2="112.279"
y2="143.659"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#FF9399" />
<stop offset="1" stopColor="#FF5A60" />
</linearGradient>
</defs>

{/* this is the actual circle part.
cx and cy are centers so shld be half of height/width. r is radius */}
<circle cx='150' cy='150' r='115'> </circle>
</svg>
<svg className="blue-circle" width="400" height="400">
<defs>
<linearGradient
id="blue-gradient"
x1="36.7649"
y1="66.8832"
x2="134.326"
y2="192.278"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#B2D9FF" />
<stop offset="1" stopColor="#78B6F4" />
</linearGradient>
</defs>
<circle cx='200' cy='200' r='180'> </circle>
</svg>
{/* imported way of using svgs, so cant adjust stroke colors */}
<img src={arrow} className="arrow-circle" alt="dti arrow" />
{/* made two pluses since color gradient changes and second one needs
to expand outside of the container. */}
<img src={smallPlus} className="first-plus" alt="first plus" />
<img
src={bigPlus}
className="sec-plus"
alt="second plus"
onAnimationEnd={() => {
const timer = setTimeout(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the animation looks good. I'm just curious that since this calls an inline-function inside of onAnimationEnd, wouldn't this create a timer every re-render. Would it be better to make declare the function outside? This might be a bit better performance-wise if the component frequently re-renders or updates.

setLoading(false);
}, 1000);
return () => clearTimeout(timer);
}}
/>

</div>
)


const Welcome = () => (
<div>
<div style={{ display: "flex", flexDirection: "column", width: "400px", justifyContent: "space-between" }}>
<div style={{ alignSelf: "flex-start" }}>
<Typography variant="h2" style={{ fontWeight: "bold" }}> Queue Me In</Typography>
</div>
<div style={{ alignSelf: "flex-end" }}>
<Typography variant="h1" style={{ fontWeight: "bold" }}> Wrapped</Typography>
</div>
<div className="animationContainer">
{showBanner && (
<>
<div className="banner top-right">
loading ? (<> </>) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of conditionally rendering an empty component, this is typically done with && in typescript (see line 418 for an example)

(
<div>
<div style={{ display: "flex", flexDirection: "column",
width: "400px", justifyContent: "space-between"
}}
>
<div style={{ alignSelf: "flex-start" }} className="intro-title">
<Typography variant="h2" style={{ fontWeight: "bold" }}> Queue Me In</Typography>
</div>
<div style={{ alignSelf: "flex-end" }} className="intro-title">
<Typography variant="h1" style={{ fontWeight: "bold" }}> Wrapped</Typography>
</div>
<div className="animationContainer">
{showBanner && (
<>
<div className="banner top-right">
SPRING 2024 SPRING 2024 SPRING 2024
</div>
<div className="banner bottom-left">
</div>
<div className="banner bottom-left">
SPRING 2024 SPRING 2024 SPRING 2024
</div>
</>
)}
</div>
</>
)}
</div>
</div>
</div>
</div>
</div>
)
)



);

const Visits = () => (
<div>
Expand Down Expand Up @@ -333,9 +415,12 @@ const Wrapped = (props: Props) => {
return (
<div className="wrappedBackground">
<div className="wrappedContainer">
{loading && <div>Loading...</div>}
{loading && <WrappedAnimationModal />}
{stage !== 0 &&
<div className="navigateStage prev" onClick={() => navigateStage('prev')}>
<div
className={`navigateStage${loading ? '':'Visible prev'}`}
onClick={() => navigateStage('prev')}
>
<ArrowBackIosIcon />
</div>
}
Expand All @@ -345,9 +430,12 @@ const Wrapped = (props: Props) => {
{stage === 2 && <TimeSpent />}
{stage === 3 && <PersonalityType />}
{stage === 4 && <Conclusion />}
<DotsIndicator />
<DotsIndicator showDots={loading ? "" : "Visible"} />
{stage !== totalStages - 1 &&
<div className="navigateStage next" onClick={() => navigateStage('next')}>
<div
className={`navigateStage${loading ? '':'Visible next'}`}
onClick={() => navigateStage('next')}
>
<ArrowForwardIosIcon />
</div>
}
Expand All @@ -362,5 +450,4 @@ const Wrapped = (props: Props) => {
);
};


export default Wrapped;
11 changes: 11 additions & 0 deletions src/media/wrapped/arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/media/wrapped/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/media/wrapped/plus2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 29 additions & 3 deletions src/styles/Wrapped.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
width: 825px;
height: 475px;
color: #FFFFFF;
background: #80B0DE;
background: linear-gradient(90deg, #80B0DE 3.12%, #93A7E4 97.75%);
align-items: center;
justify-content: center;
box-shadow: 0px 4px 4px 0px #00000040;


}

Expand All @@ -41,7 +43,7 @@
right: "1.8rem";
}

.navigateStage {
.navigateStageVisible {
position: absolute;
top: 50%;
transform: translateY(-50%);
Expand All @@ -52,6 +54,7 @@
align-items: center;
justify-content: center;
background-color: rgba(255, 255, 255, 0);
transition: 0.5s;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
Expand All @@ -72,7 +75,11 @@
padding-right: 10px;
}

.dotsContainer {
.dotsContainer, .navigateStage {
display: none;
}

.dotsContainerVisible {
display: flex;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -118,6 +125,25 @@
}
}

@keyframes fadeIn {
0% {
opacity: 0%
}

100% {
opacity: 100%;
}
}

.intro-title{
animation: fadeIn 1s ease-in both;
}

.intro-title:nth-child(2) {
animation-delay: 0.75s;
animation-duration: 0.5s;
}

.banner {
position: absolute;
background-color: #7a57d1;
Expand Down
Loading
Loading