Skip to content

Commit

Permalink
[404; Landing; Loading] Replace tractor image with people images (#3064)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored May 2, 2024
1 parent 5b6ba18 commit 7dbca7d
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 67 deletions.
2 changes: 1 addition & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"generic": {
"404Title": "404: Page not found",
"404Text": "Click on the combine to go back home.",
"404Text": "Click on the people to go back home.",
"loadingTitle": "Loading...",
"loadingText": "Please wait while The Combine processes your data."
},
Expand Down
81 changes: 81 additions & 0 deletions src/components/HarvestThreshWinnow/ImageAttributions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Dialog, IconButton, Typography } from "@mui/material";
import { type ReactElement, useState } from "react";

import ccIcon from "resources/cc-by-sa.png";

export interface ImageMetadata {
name: string;
nameHref?: string;
by: string;
byHref?: string;
license: string;
licenseHref?: string;
cropped?: boolean;
}

interface ImageAttributionsButtonProps {
images: ImageMetadata[];
width?: number;
}

/** Icon button for image attributions (assumes CC BY-SA) */
export default function ImageAttributionsButton(
props: ImageAttributionsButtonProps
): ReactElement {
const [open, setOpen] = useState(false);
return (
<>
<IconButton
aria-label="show image attribution"
onClick={() => setOpen(true)}
>
<img
alt="CreativeCommons-Attribution-ShareAlike"
src={ccIcon}
style={{ width: props.width || 60 }}
/>
</IconButton>
<Dialog open={open} onClose={() => setOpen(false)}>
{props.images.map((image, index) => (
<ImageAttribution key={index} {...image} />
))}
</Dialog>
</>
);
}

/** Typography with attribution info and links for an image */
function ImageAttribution(props: ImageMetadata): ReactElement {
const nameLink = props.nameHref ? (
<a href={props.nameHref} rel="noreferrer" target="_blank">
{props.name}
</a>
) : (
props.name
);
const byLink = props.byHref ? (
<a href={props.byHref} rel="noreferrer" target="_blank">
{props.by}
</a>
) : (
props.by
);
const licenseLink = props.licenseHref ? (
<a href={props.licenseHref} rel="noreferrer" target="_blank">
{props.license}
</a>
) : (
props.license
);
return (
<Typography>
{'• "'}
{nameLink}
{'" by '}
{byLink}
{props.cropped ? ", cropped" : ""}
{", "}
{licenseLink}
</Typography>
);
}
108 changes: 108 additions & 0 deletions src/components/HarvestThreshWinnow/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { type AnimationOptionsWithOverrides, animate } from "motion";
import { type CSSProperties, type ReactElement, useEffect } from "react";

import ImageAttributions, {
ImageMetadata,
} from "components/HarvestThreshWinnow/ImageAttributions";
import imageLicenses from "resources/HTW-licenses.json";
import harvest from "resources/HTW1-harvest-Ethiopia.jpg";
import thresh from "resources/HTW2-thresh-Bangladesh.jpg";
import winnow from "resources/HTW3-winnow-India.jpg";

enum ImageAlt {
License = "CC BY-SA 4.0 license",
Harvest = "Harvesting in Ethiopia",
Thresh = "Threshing in Bangladesh",
Winnow = "Winnowing in India",
}

enum ImageId {
License = "image-license",
Harvest = "harvest-image",
Thresh = "thresh-image",
Winnow = "winnow-image",
}

const imageMetadata: ImageMetadata[] = [
imageLicenses.harvest,
imageLicenses.thresh,
imageLicenses.winnow,
];

interface HarvestThreshWinnowProps {
loading?: boolean;
maxSize?: number;
}

// Opacity of the 3 images, each fading in then fading out while the next fades in.
const opacityKeyframes1 = [0, 0.5, 1, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0];
const opacityKeyframes2 = [0, 0, 0, 0, 0.5, 1, 1, 0.5, 0, 0, 0, 0, 0];
const opacityKeyframes3 = [0, 0, 0, 0, 0, 0, 0, 0.5, 1, 1, 0.5, 0, 0];

/** A custom harvest-thresh-winnow image */
export default function HarvestThreshWinnow(
props: HarvestThreshWinnowProps
): ReactElement {
useEffect(() => {
if (props.loading) {
const options: AnimationOptionsWithOverrides = {
duration: 7,
easing: "linear",
repeat: Infinity,
};
animate(`#${ImageId.License}`, { opacity: opacityKeyframes1 }, options);
animate(`#${ImageId.Harvest}`, { opacity: opacityKeyframes1 }, options);
animate(`#${ImageId.Thresh}`, { opacity: opacityKeyframes2 }, options);
animate(`#${ImageId.Winnow}`, { opacity: opacityKeyframes3 }, options);
}
}, [props.loading]);

const size = Math.min(
0.75 * window.innerHeight,
0.25 * window.innerWidth,
props.maxSize || 1000
);

const imageStyle: CSSProperties = {
border: "1px solid black",
borderRadius: size,
position: "relative",
width: size,
};

const overlap = 0.23;

return (
<div style={{ height: size, position: "relative", margin: 10 }}>
<img
alt={ImageAlt.Harvest}
id={ImageId.Harvest}
src={harvest}
style={{ ...imageStyle, left: overlap * size }}
/>
<img
alt={ImageAlt.Thresh}
id={ImageId.Thresh}
src={thresh}
style={{ ...imageStyle }}
/>
<img
alt={ImageAlt.Winnow}
id={ImageId.Winnow}
src={winnow}
style={{ ...imageStyle, right: overlap * size }}
/>
<div
id={ImageId.License}
style={{
// Use -10 to offset the button padding
bottom: -10,
left: 0.2 * size - 10,
position: "absolute",
}}
>
<ImageAttributions images={imageMetadata} width={0.15 * size} />
</div>
</div>
);
}
2 changes: 1 addition & 1 deletion src/components/LandingPage/LandingButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const horizontalButtonsHeight =
const horizontalButtonsWidth = 3 * buttonWidth + parseInt(theme.spacing(7));

const verticalButtonsHeight = 3 * buttonHeight + parseInt(theme.spacing(7));
const verticalButtonsWidth = buttonWidth + parseInt(theme.spacing(2));
export const verticalButtonsWidth = buttonWidth + parseInt(theme.spacing(2));

interface LandingButtonsProps {
top?: boolean;
Expand Down
36 changes: 17 additions & 19 deletions src/components/LandingPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { ReactElement, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";

import HarvestThreshWinnow from "components/HarvestThreshWinnow";
import BottomBar, { bottomBarHeight } from "components/LandingPage/BottomBar";
import LandingButtons, {
horizontalButtonsHeight,
SignUpButton,
verticalButtonsWidth,
} from "components/LandingPage/LandingButtons";
import TopBar, { topBarHeight } from "components/LandingPage/TopBar";
import tractor from "resources/tractor.png";
import { Path } from "types/path";
import theme from "types/theme";

Expand Down Expand Up @@ -37,7 +38,7 @@ export default function LandingPage(): ReactElement {
<Body />
</Box>
</Grid>
<Grid item sm={3} md={2} xl={1}>
<Grid item width={verticalButtonsWidth}>
<LandingButtons />
</Grid>
</Hidden>
Expand Down Expand Up @@ -66,8 +67,15 @@ function Body(): ReactElement {
const { t } = useTranslation();

return (
<>
<div style={{ padding: theme.spacing(3) }}>
<Box
alignItems="center"
display="flex"
flexDirection="column"
justifyContent="center"
rowGap={theme.spacing(4)}
style={{ padding: theme.spacing(3) }}
>
<div>
<Typography variant="body2" align="justify">
{t("landingPage.descriptionP1")}
{<br />}
Expand All @@ -81,25 +89,15 @@ function Body(): ReactElement {
<Typography
variant="h6"
align="justify"
style={{
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(1),
}}
style={{ paddingTop: theme.spacing(2) }}
>
{t("landingPage.descriptionP4")}
</Typography>
<SignUpButton buttonIdPrefix="landing-body" />
</div>
<img
src={tractor}
alt="Tractor"
style={{
width: "70%",
maxWidth: 700,
margin: "0% 15%",
marginTop: theme.spacing(4),
}}
<SignUpButton buttonIdPrefix="landing-body" />
<HarvestThreshWinnow
maxSize={Math.min(400, (window.innerWidth - verticalButtonsWidth) / 5)}
/>
</>
</Box>
);
}
33 changes: 15 additions & 18 deletions src/components/PageNotFound/component.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Typography } from "@mui/material";
import { Box, Typography } from "@mui/material";
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";

import tractor from "resources/tractor.png";
import HarvestThreshWinnow from "components/HarvestThreshWinnow";
import { Path } from "types/path";

/**
Expand All @@ -15,21 +15,18 @@ export default function PageNotFound(): ReactElement {
const navigate = useNavigate();

return (
<>
<Typography variant="h4" style={{ textAlign: "center" }}>
{t("generic.404Title")}
</Typography>
<img
src={tractor}
alt="Tractor"
style={{ width: "50%", margin: "0% 25%" }}
onClick={() => {
navigate(Path.ProjScreen);
}}
/>
<Typography variant="h5" style={{ textAlign: "center" }}>
{t("generic.404Text")}
</Typography>
</>
<Box
alignItems="center"
display="flex"
flexDirection="column"
justifyContent="center"
rowGap={3}
>
<Typography variant="h4">{t("generic.404Title")}</Typography>
<div onClick={() => navigate(Path.ProjScreen)}>
<HarvestThreshWinnow />
</div>
<Typography variant="h5">{t("generic.404Text")}</Typography>
</Box>
);
}
42 changes: 14 additions & 28 deletions src/goals/DefaultGoal/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,23 @@
import { Typography } from "@mui/material";
import { animate } from "motion";
import { ReactElement, useEffect } from "react";
import { Box, Typography } from "@mui/material";
import { type ReactElement } from "react";
import { useTranslation } from "react-i18next";

import tractor from "resources/tractor.png";
import HarvestThreshWinnow from "components/HarvestThreshWinnow";

/** A custom loading page */
export default function Loading(): ReactElement {
const { t } = useTranslation();

useEffect(() => {
const half = window.innerWidth * 0.75;
animate(
"#loading-tractor",
{ transform: [`translateX(${half}px)`, `translateX(-${half}px)`] },
{ duration: 10, repeat: Infinity, easing: "linear" }
);
}, []);

return (
<>
<Typography variant="h4" style={{ textAlign: "center" }}>
{t("generic.loadingTitle")}
</Typography>
<img
src={tractor}
alt="Tractor"
id="loading-tractor"
style={{ width: "50%", margin: "0% 25%" }}
/>
<Typography variant="h5" style={{ textAlign: "center" }}>
{t("generic.loadingText")}
</Typography>
</>
<Box
alignItems="center"
display="flex"
flexDirection="column"
justifyContent="center"
rowGap={3}
>
<Typography variant="h4">{t("generic.loadingTitle")}</Typography>
<HarvestThreshWinnow loading />
<Typography variant="h5">{t("generic.loadingText")}</Typography>
</Box>
);
}
Loading

0 comments on commit 7dbca7d

Please sign in to comment.