make the feedback form more visible
This commit is contained in:
parent
d99f5d7ac8
commit
5f3ac956e3
1 changed files with 54 additions and 127 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue