Feedback form sends req to stubbed API endpoint
Okay, now the UI can handle the loading/success/error status! Next we need to actually send :3
This commit is contained in:
parent
b713aeea96
commit
87d6cbf72a
2 changed files with 71 additions and 11 deletions
16
api/sendFeedback.js
Normal file
16
api/sendFeedback.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
const beeline = require("honeycomb-beeline")({
|
||||||
|
writeKey: process.env["HONEYCOMB_WRITE_KEY"],
|
||||||
|
dataset:
|
||||||
|
process.env["NODE_ENV"] === "production"
|
||||||
|
? "Dress to Impress (2020)"
|
||||||
|
: "Dress to Impress (2020, dev)",
|
||||||
|
serviceName: "impress-2020-gql-server",
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handle(req, res) {
|
||||||
|
res.status(500).send("TODO! This is a fake error case.");
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
beeline.withTrace({ name: "uploadLayerImage" }, () => handle(req, res));
|
||||||
|
};
|
|
@ -16,7 +16,7 @@ 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";
|
||||||
|
|
||||||
import { Heading1, usePageTitle } from "./util";
|
import { Heading1, useLocalStorage, usePageTitle } from "./util";
|
||||||
import OutfitPreview from "./components/OutfitPreview";
|
import OutfitPreview from "./components/OutfitPreview";
|
||||||
import SpeciesColorPicker from "./components/SpeciesColorPicker";
|
import SpeciesColorPicker from "./components/SpeciesColorPicker";
|
||||||
|
|
||||||
|
@ -390,8 +390,58 @@ function FeedbackFormPitch({ isDisabled, onClick, openButtonRef }) {
|
||||||
|
|
||||||
function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
|
function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
|
||||||
const [content, setContent] = React.useState("");
|
const [content, setContent] = React.useState("");
|
||||||
|
const [email, setEmail] = useLocalStorage("DTIFeedbackFormEmail", "");
|
||||||
|
const [isSending, setIsSending] = React.useState(false);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
const onSubmit = React.useCallback(
|
||||||
|
(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.set("content", content);
|
||||||
|
formData.set("email", email);
|
||||||
|
|
||||||
|
fetch("/api/sendFeedback", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error(`/api/sendFeedback returned status ${res.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsSending(false);
|
||||||
|
setContent("");
|
||||||
|
onClose();
|
||||||
|
toast({
|
||||||
|
status: "success",
|
||||||
|
title: "Got it! We'll take a look soon.",
|
||||||
|
description:
|
||||||
|
"Thanks for helping us get better! Best wishes to you and your " +
|
||||||
|
"pets!!",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
setIsSending(false);
|
||||||
|
console.error(e);
|
||||||
|
toast({
|
||||||
|
status: "warning",
|
||||||
|
title: "Oops, we had an error sending this, sorry!",
|
||||||
|
description:
|
||||||
|
"We'd still love to hear from you! Please reach out to " +
|
||||||
|
"matchu@openneo.net with whatever's on your mind. Thanks and " +
|
||||||
|
"enjoy the site!",
|
||||||
|
duration: null,
|
||||||
|
isClosable: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsSending(true);
|
||||||
|
},
|
||||||
|
[content]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
as="form"
|
as="form"
|
||||||
|
@ -401,16 +451,7 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
|
||||||
gridTemplateAreas={`"email send" "content content"`}
|
gridTemplateAreas={`"email send" "content content"`}
|
||||||
gridTemplateColumns="1fr auto"
|
gridTemplateColumns="1fr auto"
|
||||||
gridGap="2"
|
gridGap="2"
|
||||||
onSubmit={(e) => {
|
onSubmit={onSubmit}
|
||||||
e.preventDefault();
|
|
||||||
toast({
|
|
||||||
title: "Ah, well, this form isn't hooked up yet!",
|
|
||||||
description:
|
|
||||||
"That's coming soon! 😅 For now, please send an email to matchu@openneo.net. Sorry and thanks!",
|
|
||||||
duration: null,
|
|
||||||
isClosable: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
onClose();
|
onClose();
|
||||||
|
@ -423,6 +464,8 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
|
||||||
placeholder="Email address (optional)"
|
placeholder="Email address (optional)"
|
||||||
size="sm"
|
size="sm"
|
||||||
gridArea="email"
|
gridArea="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
ref={emailFieldRef}
|
ref={emailFieldRef}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
/>
|
/>
|
||||||
|
@ -440,6 +483,7 @@ function FeedbackForm({ isDisabled, onClose, emailFieldRef }) {
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
gridArea="send"
|
gridArea="send"
|
||||||
isDisabled={isDisabled || content.trim().length === 0}
|
isDisabled={isDisabled || content.trim().length === 0}
|
||||||
|
isLoading={isSending}
|
||||||
>
|
>
|
||||||
Send
|
Send
|
||||||
</Button>
|
</Button>
|
||||||
|
|
Loading…
Reference in a new issue