make the feedback form more visible

This commit is contained in:
Emi Matchu 2020-10-22 16:01:54 -07:00
parent d99f5d7ac8
commit 5f3ac956e3

View file

@ -5,14 +5,13 @@ import {
Box, Box,
Button, Button,
Flex, Flex,
IconButton,
Input, Input,
Textarea, Textarea,
useColorModeValue, useColorModeValue,
useTheme, useTheme,
useToast, useToast,
VStack,
} from "@chakra-ui/core"; } from "@chakra-ui/core";
import { CloseIcon } from "@chakra-ui/icons";
import { useHistory, useLocation } from "react-router-dom"; import { useHistory, useLocation } from "react-router-dom";
import { useLazyQuery } from "@apollo/client"; import { useLazyQuery } from "@apollo/client";
@ -249,42 +248,51 @@ function SubmitPetForm() {
} }
function FeedbackFormSection() { function FeedbackFormSection() {
const [isOpen, setIsOpen] = React.useState(false); const pitchBorderColor = useColorModeValue("gray.300", "green.400");
const borderColor = useColorModeValue("gray.300", "blue.400"); const formBorderColor = useColorModeValue("gray.300", "blue.400");
const openButtonRef = React.useRef(null);
const emailFieldRef = React.useRef(null);
const elementAwaitingFocusRef = React.useRef(null);
const openForm = React.useCallback(() => {
setIsOpen(true);
// Wait for the re-render to enable the field, then focus it.
elementAwaitingFocusRef.current = emailFieldRef.current;
}, [setIsOpen]);
const closeForm = React.useCallback(() => {
setIsOpen(false);
// Wait for the re-render to enable the button, then focus it.
elementAwaitingFocusRef.current = openButtonRef.current;
}, [setIsOpen]);
// This lil layout effect will focus whatever element is awaiting focus, then
// clear it out. We use this to set up focus() calls, but wait until the next
// layout finishes to actually call them.
React.useLayoutEffect(() => {
if (elementAwaitingFocusRef.current) {
elementAwaitingFocusRef.current.focus();
elementAwaitingFocusRef.current = null;
}
});
return ( return (
<Flex <VStack spacing="4" alignItems="stretch">
<FeedbackFormContainer borderColor={pitchBorderColor}>
<Flex position="relative" alignItems="center">
<Box padding="2" borderRadius="lg" overflow="hidden" flex="0 0 auto">
<Box
as="img"
src={FeedbackXweeImg}
srcSet={`${FeedbackXweeImg} 1x, ${FeedbackXweeImg2x} 2x`}
height="90px"
width="90px"
opacity="0.9"
alt=""
/>
</Box>
<FeedbackFormPitch />
</Flex>
</FeedbackFormContainer>
<FeedbackFormContainer
borderColor={formBorderColor}
image={
<Box
as="img"
src={FeedbackXweeImg}
srcSet={`${FeedbackXweeImg} 1x, ${FeedbackXweeImg2x} 2x`}
height="90px"
width="90px"
opacity="0.9"
alt=""
/>
}
>
<FeedbackForm />
</FeedbackFormContainer>
</VStack>
);
}
function FeedbackFormContainer({ borderColor, children }) {
return (
<Box
as="section" as="section"
position="relative"
alignItems="center"
border="1px solid" border="1px solid"
borderColor={borderColor} borderColor={borderColor}
borderRadius="lg" borderRadius="lg"
@ -293,77 +301,13 @@ function FeedbackFormSection() {
paddingLeft="2" paddingLeft="2"
paddingRight="4" paddingRight="4"
paddingY="2" paddingY="2"
cursor={!isOpen && "pointer"}
onClick={!isOpen ? openForm : null}
> >
<Box padding="2" borderRadius="lg" overflow="hidden" flex="0 0 auto"> {children}
<Box </Box>
as="img"
src={FeedbackXweeImg}
srcSet={`${FeedbackXweeImg} 1x, ${FeedbackXweeImg2x} 2x`}
height="90px"
width="90px"
opacity="0.9"
alt=""
/>
</Box>
<Box
display="grid"
gridTemplateAreas="the-single-area"
alignItems="center"
marginLeft="2"
>
<Box
position="absolute"
left="1"
top="1"
aria-hidden={!isOpen}
isDisabled={!isOpen}
opacity={isOpen ? "0.5" : "0"}
pointerEvents={isOpen ? "all" : "none"}
transition="opacity 0.25s"
>
<IconButton
aria-label="Close"
icon={<CloseIcon />}
size="xs"
variant="ghost"
onClick={closeForm}
isDisabled={!isOpen}
/>
</Box>
<Box
gridArea="the-single-area"
aria-hidden={isOpen}
opacity={isOpen ? "0" : "1"}
pointerEvents={isOpen ? "none" : "all"}
transition="opacity 0.25s"
>
<FeedbackFormPitch
isDisabled={isOpen}
onClick={openForm}
openButtonRef={openButtonRef}
/>
</Box>
<Box
gridArea="the-single-area"
aria-hidden={!isOpen}
opacity={isOpen ? "1" : "0"}
pointerEvents={isOpen ? "all" : "none"}
transition="opacity 0.25s"
>
<FeedbackForm
isDisabled={!isOpen}
onClose={closeForm}
emailFieldRef={emailFieldRef}
/>
</Box>
</Box>
</Flex>
); );
} }
function FeedbackFormPitch({ isDisabled, onClick, openButtonRef }) { function FeedbackFormPitch() {
return ( return (
<Flex direction="column" textAlign="left" opacity="0.9"> <Flex direction="column" textAlign="left" opacity="0.9">
<Box as="header">Hi friends! Welcome to the beta!</Box> <Box as="header">Hi friends! Welcome to the beta!</Box>
@ -371,24 +315,17 @@ function FeedbackFormPitch({ isDisabled, onClick, openButtonRef }) {
This is the new Dress to Impress! It's ready for the future, and it even This is the new Dress to Impress! It's ready for the future, and it even
works great on mobile! More coming soon! works great on mobile! More coming soon!
</Box> </Box>
<Box <Box fontSize="sm" marginTop="1">
as="button" Got ideas? Send them to us, please!{" "}
alignSelf="flex-end" <span role="img" aria-label="Sparkle heart emoji">
fontSize="sm" 💖
marginTop="1" </span>
opacity="0.8"
textDecoration="underline"
disabled={isDisabled}
onClick={onClick}
ref={openButtonRef}
>
Got ideas? Send us your feedback
</Box> </Box>
</Flex> </Flex>
); );
} }
function FeedbackForm({ isDisabled, onClose, emailFieldRef }) { function FeedbackForm() {
const [content, setContent] = React.useState(""); const [content, setContent] = React.useState("");
const [email, setEmail] = useLocalStorage("DTIFeedbackFormEmail", ""); const [email, setEmail] = useLocalStorage("DTIFeedbackFormEmail", "");
const [isSending, setIsSending] = React.useState(false); const [isSending, setIsSending] = React.useState(false);
@ -410,7 +347,6 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
setIsSending(false); setIsSending(false);
setContent(""); setContent("");
onClose();
toast({ toast({
status: "success", status: "success",
title: "Got it! We'll take a look soon.", title: "Got it! We'll take a look soon.",
@ -436,7 +372,7 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
setIsSending(true); setIsSending(true);
}, },
[content, email, onClose, toast] [content, email, toast]
); );
return ( return (
@ -449,12 +385,6 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
gridTemplateColumns="1fr auto" gridTemplateColumns="1fr auto"
gridGap="2" gridGap="2"
onSubmit={onSubmit} onSubmit={onSubmit}
onKeyDown={(e) => {
if (e.key === "Escape") {
onClose();
e.stopPropagation();
}
}}
> >
<Input <Input
type="email" type="email"
@ -463,8 +393,6 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
gridArea="email" gridArea="email"
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
ref={emailFieldRef}
isDisabled={isDisabled}
/> />
<Textarea <Textarea
size="sm" size="sm"
@ -472,14 +400,13 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
gridArea="content" gridArea="content"
value={content} value={content}
onChange={(e) => setContent(e.target.value)} onChange={(e) => setContent(e.target.value)}
isDisabled={isDisabled}
/> />
<Button <Button
type="submit" type="submit"
size="sm" size="sm"
colorScheme="blue" colorScheme="blue"
gridArea="send" gridArea="send"
isDisabled={isDisabled || content.trim().length === 0} isDisabled={content.trim().length === 0}
isLoading={isSending} isLoading={isSending}
> >
Send Send