do pet loading on homepage, scrap reset modal

This commit is contained in:
Matt Dunn-Rankin 2020-05-10 00:54:23 -07:00
parent 385360ef10
commit dcd8cc7a4a
3 changed files with 117 additions and 171 deletions

View file

@ -1,6 +1,17 @@
import React from "react";
import { Box, Flex, Button, Tooltip } from "@chakra-ui/core";
import { css } from "emotion";
import gql from "graphql-tag";
import {
Box,
Button,
Flex,
Input,
Tooltip,
useTheme,
useToast,
} from "@chakra-ui/core";
import { useHistory } from "react-router-dom";
import { useLazyQuery } from "@apollo/react-hooks";
import { Heading1 } from "./util";
@ -29,6 +40,12 @@ function HomePage() {
<Heading1>Dress to Impress</Heading1>
<Box height="8" />
<StartOutfitForm />
<Box height="4" />
<Box fontStyle="italic" fontSize="sm">
or
</Box>
<Box height="4" />
<SubmitPetForm />
</Flex>
);
}
@ -40,7 +57,9 @@ function StartOutfitForm() {
const [colorId, setColorId] = React.useState("8");
const [isValid, setIsValid] = React.useState(true);
const onSubmit = () => {
const onSubmit = (e) => {
e.preventDefault();
if (!isValid) {
return;
}
@ -84,4 +103,92 @@ function StartOutfitForm() {
);
}
function SubmitPetForm() {
const history = useHistory();
const theme = useTheme();
const toast = useToast();
const [petName, setPetName] = React.useState("");
const [loadPet, { loading }] = useLazyQuery(
gql`
query($petName: String!) {
petOnNeopetsDotCom(petName: $petName) {
color {
id
}
species {
id
}
items {
id
}
}
}
`,
{
fetchPolicy: "network-only",
onCompleted: (data) => {
if (!data) return;
const { species, color, items } = data.petOnNeopetsDotCom;
const params = new URLSearchParams({
name: petName,
species: species.id,
color: color.id,
emotion: "HAPPY", // TODO: Ask PetService
genderPresentation: "FEMININE", // TODO: Ask PetService
});
for (const item of items) {
params.append("objects[]", item.id);
}
history.push(`/outfits/new?${params}`);
},
onError: () => {
toast({
title: "We couldn't load that pet, sorry 😓",
description: "Is it spelled correctly?",
status: "error",
});
},
}
);
const onSubmit = (e) => {
e.preventDefault();
loadPet({ variables: { petName } });
};
return (
<form onSubmit={onSubmit}>
<Flex>
<Input
value={petName}
onChange={(e) => setPetName(e.target.value)}
isDisabled={loading}
placeholder="Enter a pet's name"
borderColor="green.600"
_hover={{ borderColor: "green.400" }}
boxShadow="md"
width="14em"
className={css`
&::placeholder {
color: ${theme.colors.gray["500"]};
}
`}
/>
<Box width="4" />
<Button
type="submit"
variantColor="green"
isDisabled={!petName}
isLoading={loading}
>
Start
</Button>
</Flex>
</form>
);
}
export default HomePage;

View file

@ -11,10 +11,10 @@ import {
useToast,
} from "@chakra-ui/core";
import OutfitResetModal from "./OutfitResetModal";
import PosePicker from "./PosePicker";
import SpeciesColorPicker from "./SpeciesColorPicker";
import useOutfitAppearance from "./useOutfitAppearance";
import { Link } from "react-router-dom";
/**
* OutfitControls is the set of controls layered over the outfit preview, to
@ -54,7 +54,13 @@ function OutfitControls({ outfitState, dispatchToOutfit }) {
)}
>
<Box gridArea="back">
<BackButton dispatchToOutfit={dispatchToOutfit} />
<ControlButton
as={Link}
to="/"
icon="arrow-back"
aria-label="Leave this outfit"
d="inline-flex" // Not sure why <a> requires this to style right! ^^`
/>
</Box>
<Stack
gridArea="sharing"
@ -158,29 +164,6 @@ function CopyLinkButton({ outfitState }) {
);
}
/**
* BackButton opens a reset modal to let you clear the outfit or enter a new
* pet's name to start from!
*/
function BackButton({ dispatchToOutfit }) {
const [showResetModal, setShowResetModal] = React.useState(false);
return (
<>
<ControlButton
icon="arrow-back"
aria-label="Leave this outfit"
onClick={() => setShowResetModal(true)}
/>
<OutfitResetModal
isOpen={showResetModal}
onClose={() => setShowResetModal(false)}
dispatchToOutfit={dispatchToOutfit}
/>
</>
);
}
/**
* ControlButton is a UI helper to render the cute round buttons we use in
* OutfitControls!

View file

@ -1,144 +0,0 @@
import React from "react";
import gql from "graphql-tag";
import { useQuery } from "@apollo/react-hooks";
import {
Text,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
Input,
Button,
ModalFooter,
FormErrorMessage,
FormControl,
Box,
} from "@chakra-ui/core";
/**
* OutfitResetModal gives the user the ability to reset their outfit, by either
* clearing out most of the data, or letting them type in a pet name to load
* from Neopets.com!
*/
function OutfitResetModal({ isOpen, onClose, dispatchToOutfit }) {
const [petName, setPetName] = React.useState("");
const [submittedPetName, submitPetName] = React.useState("");
const { loading, error } = useQuery(
gql`
query($petName: String!) {
petOnNeopetsDotCom(petName: $petName) {
color {
id
}
species {
id
}
items {
id
}
}
}
`,
{
variables: { petName: submittedPetName },
skip: !submittedPetName,
fetchPolicy: "network-only",
onCompleted: (data) => {
if (!data) return;
const { species, color, items } = data.petOnNeopetsDotCom;
dispatchToOutfit({
type: "reset",
name: petName,
speciesId: species.id,
colorId: color.id,
emotion: "HAPPY", // TODO: Ask PetService
genderPresentation: "FEMININE", // TODO: Ask PetService
wornItemIds: items.map((i) => i.id),
closetedItemIds: [],
});
onClose();
setPetName("");
submitPetName("");
},
}
);
const clearOutfit = () => {
dispatchToOutfit({
type: "reset",
name: "",
wornItemIds: [],
closetedItemIds: [],
});
onClose();
setPetName("");
submitPetName("");
};
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<form
onSubmit={(e) => {
e.preventDefault();
submitPetName(petName);
}}
>
<ModalHeader>
<Text fontFamily="Delicious">
Want to try your own pet?{" "}
<span role="img" aria-label="(surprise emoji)">
😮
</span>
</Text>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>
Choose a pet from Neopets.com, and we'll pull their outfit data
into here for you to play with!
</Text>
<Box height="4" />
<FormControl isInvalid={error}>
<Input
placeholder="Enter a pet's name…"
value={petName}
onChange={(e) => setPetName(e.target.value)}
autoFocus
/>
{error && (
<FormErrorMessage>
We had trouble loading that pet, sorry{" "}
<span role="img" aria-label="(confounded emoji)">
😖
</span>
</FormErrorMessage>
)}
</FormControl>
</ModalBody>
<ModalFooter>
<Button
leftIcon="delete"
variant="outline"
variantColor="red"
onClick={clearOutfit}
>
Reset outfit
</Button>
<Box flex="1"></Box>
<Button type="submit" variantColor="green" isLoading={loading}>
Show me!
</Button>
</ModalFooter>
</form>
</ModalContent>
</Modal>
);
}
export default OutfitResetModal;