From 56e88807153b641dad2b2c2259fa7ad2f869c9f6 Mon Sep 17 00:00:00 2001 From: m5r Date: Sun, 1 Aug 2021 15:40:18 +0800 Subject: [PATCH] send message to new recipient --- app/api/ddd.ts | 27 +- app/api/queue/send-message.ts | 27 +- app/messages/components/conversation.tsx | 5 +- app/messages/components/new-message-area.tsx | 19 +- .../components/new-message-bottom-sheet.tsx | 53 ++++ .../components/new-message-button.tsx | 21 ++ app/messages/hooks/use-conversation.ts | 1 + app/messages/hooks/use-known-recipients.ts | 14 + app/messages/mutations/send-message.ts | 13 + app/messages/pages/messages.tsx | 10 +- app/messages/pages/messages/[recipient].tsx | 4 +- app/phone-calls/pages/calls.tsx | 2 +- app/settings/pages/settings.tsx | 37 +-- package-lock.json | 259 ++++++++++++++++++ package.json | 3 + 15 files changed, 456 insertions(+), 39 deletions(-) create mode 100644 app/messages/components/new-message-bottom-sheet.tsx create mode 100644 app/messages/components/new-message-button.tsx create mode 100644 app/messages/hooks/use-known-recipients.ts diff --git a/app/api/ddd.ts b/app/api/ddd.ts index 7e6d86b..d99f2ae 100644 --- a/app/api/ddd.ts +++ b/app/api/ddd.ts @@ -1,16 +1,37 @@ import { BlitzApiRequest, BlitzApiResponse } from "blitz"; import db from "db"; +import twilio from "twilio"; export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) { - await Promise.all([ + /*await Promise.all([ db.message.deleteMany(), db.phoneCall.deleteMany(), db.phoneNumber.deleteMany(), db.customer.deleteMany(), ]); - await db.user.deleteMany(); + await db.user.deleteMany();*/ + const accountSid = "ACa886d066be0832990d1cf43fb1d53362"; + const authToken = "8696a59a64b94bb4eba3548ed815953b"; + /*const ddd = await twilio(accountSid, authToken) + .lookups + .v1 + // .phoneNumbers("+33613370787") + .phoneNumbers("+33476982071") + .fetch();*/ + try { + await twilio(accountSid, authToken).messages.create({ + body: "content", + to: "+213744123789", + from: "+33757592025", + }); + } catch (error) { + console.log(error.code); + console.log(error.moreInfo); + console.log(error.details); + // console.log(JSON.stringify(Object.keys(error))); + } - res.status(200).end(); + res.status(200).send(ddd); } diff --git a/app/api/queue/send-message.ts b/app/api/queue/send-message.ts index d91a76a..4a98e4c 100644 --- a/app/api/queue/send-message.ts +++ b/app/api/queue/send-message.ts @@ -16,15 +16,24 @@ const sendMessageQueue = Queue( const customer = await db.customer.findFirst({ where: { id: customerId } }); const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } }); - const message = await twilio(customer!.accountSid!, customer!.authToken!).messages.create({ - body: content, - to, - from: phoneNumber!.phoneNumber, - }); - await db.message.update({ - where: { id }, - data: { twilioSid: message.sid }, - }); + try { + const message = await twilio( + customer!.accountSid!, + customer!.authToken! + ).messages.create({ + body: content, + to, + from: phoneNumber!.phoneNumber, + }); + await db.message.update({ + where: { id }, + data: { twilioSid: message.sid }, + }); + } catch (error) { + // TODO: handle twilio error + console.log(error.code); // 21211 + console.log(error.moreInfo); // https://www.twilio.com/docs/errors/21211 + } }, { retry: ["1min"], diff --git a/app/messages/components/conversation.tsx b/app/messages/components/conversation.tsx index 8f56035..53fcd40 100644 --- a/app/messages/components/conversation.tsx +++ b/app/messages/components/conversation.tsx @@ -8,7 +8,8 @@ import NewMessageArea from "./new-message-area"; export default function Conversation() { const router = useRouter(); - const conversation = useConversation(router.params.recipient)[0]; + const recipient = decodeURIComponent(router.params.recipient); + const conversation = useConversation(recipient)[0]; const messagesListRef = useRef(null); useEffect(() => { @@ -75,7 +76,7 @@ export default function Conversation() { - + ); diff --git a/app/messages/components/new-message-area.tsx b/app/messages/components/new-message-area.tsx index e2c69d6..887abf4 100644 --- a/app/messages/components/new-message-area.tsx +++ b/app/messages/components/new-message-area.tsx @@ -8,14 +8,18 @@ import { Direction, Message, MessageStatus } from "../../../db"; import getConversationsQuery from "../queries/get-conversations"; import useCurrentCustomer from "../../core/hooks/use-current-customer"; import useCustomerPhoneNumber from "../../core/hooks/use-customer-phone-number"; +import { FunctionComponent } from "react"; type Form = { content: string; }; -export default function NewMessageArea() { - const router = useRouter(); - const recipient = router.params.recipient; +type Props = { + recipient: string; + onSend?: () => void; +}; + +const NewMessageArea: FunctionComponent = ({ recipient, onSend }) => { const { customer } = useCurrentCustomer(); const phoneNumber = useCustomerPhoneNumber(); const sendMessageMutation = useMutation(sendMessage)[0]; @@ -30,6 +34,10 @@ export default function NewMessageArea() { formState: { isSubmitting }, } = useForm
(); const onSubmit = handleSubmit(async ({ content }) => { + if (!recipient) { + return; + } + if (isSubmitting) { return; } @@ -60,6 +68,7 @@ export default function NewMessageArea() { { refetch: false } ); setValue("content", ""); + onSend?.(); await sendMessageMutation({ to: recipient, content }); await refetchConversations({ cancelRefetch: true }); }); @@ -83,7 +92,9 @@ export default function NewMessageArea() {
); -} +}; + +export default NewMessageArea; function uuidv4() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { diff --git a/app/messages/components/new-message-bottom-sheet.tsx b/app/messages/components/new-message-bottom-sheet.tsx new file mode 100644 index 0000000..a48147e --- /dev/null +++ b/app/messages/components/new-message-bottom-sheet.tsx @@ -0,0 +1,53 @@ +import { Suspense, useState } from "react"; +import { BottomSheet } from "react-spring-bottom-sheet"; +import { atom, useAtom } from "jotai"; +import { useRouter, Routes } from "blitz"; + +import "react-spring-bottom-sheet/dist/style.css"; + +import NewMessageArea from "./new-message-area"; + +export const bottomSheetOpenAtom = atom(false); + +export default function NewMessageBottomSheet() { + const router = useRouter(); + const [isOpen, setIsOpen] = useAtom(bottomSheetOpenAtom); + const [recipient, setRecipient] = useState(""); + + return ( + setIsOpen(false)} + snapPoints={({ maxHeight }) => maxHeight / 2} + header={ +
+ New Message + + +
+ } + > +
+
+ To: + setRecipient(event.target.value)} + className="bg-none border-none outline-none flex-1 text-black" + /> +
+ + { + router + .push(Routes.ConversationPage({ recipient })) + .then(() => setIsOpen(false)); + }} + /> + +
+
+ ); +} diff --git a/app/messages/components/new-message-button.tsx b/app/messages/components/new-message-button.tsx new file mode 100644 index 0000000..1c53cce --- /dev/null +++ b/app/messages/components/new-message-button.tsx @@ -0,0 +1,21 @@ +import type { FunctionComponent, MouseEventHandler } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faEdit } from "@fortawesome/pro-regular-svg-icons"; + +type Props = { + onClick: MouseEventHandler; +}; + +const NewMessageButton: FunctionComponent = ({ onClick }) => { + return ( + + ); +}; + +export default NewMessageButton; diff --git a/app/messages/hooks/use-conversation.ts b/app/messages/hooks/use-conversation.ts index fc5ac60..03b0403 100644 --- a/app/messages/hooks/use-conversation.ts +++ b/app/messages/hooks/use-conversation.ts @@ -14,6 +14,7 @@ export default function useConversation(recipient: string) { return conversations[recipient]!; }, + keepPreviousData: true, } ); } diff --git a/app/messages/hooks/use-known-recipients.ts b/app/messages/hooks/use-known-recipients.ts new file mode 100644 index 0000000..633fb24 --- /dev/null +++ b/app/messages/hooks/use-known-recipients.ts @@ -0,0 +1,14 @@ +import { useQuery } from "blitz"; +import getConversationsQuery from "../queries/get-conversations"; + +export default function useKnownRecipients() { + return useQuery( + getConversationsQuery, + {}, + { + select(conversations) { + return Object.keys(conversations); + }, + } + ); +} diff --git a/app/messages/mutations/send-message.ts b/app/messages/mutations/send-message.ts index c59c711..71820c4 100644 --- a/app/messages/mutations/send-message.ts +++ b/app/messages/mutations/send-message.ts @@ -1,11 +1,15 @@ import { resolver } from "blitz"; import { z } from "zod"; +import twilio from "twilio"; import db, { Direction, MessageStatus } from "../../../db"; import getCurrentCustomer from "../../customers/queries/get-current-customer"; import getCustomerPhoneNumber from "../../phone-numbers/queries/get-customer-phone-number"; import { encrypt } from "../../../db/_encryption"; import sendMessageQueue from "../../api/queue/send-message"; +import appLogger from "../../../integrations/logger"; + +const logger = appLogger.child({ mutation: "send-message" }); const Body = z.object({ content: z.string(), @@ -17,6 +21,15 @@ export default resolver.pipe( resolver.authorize(), async ({ content, to }, context) => { const customer = await getCurrentCustomer(null, context); + try { + await twilio(customer!.accountSid!, customer!.authToken!) + .lookups.v1.phoneNumbers(to) + .fetch(); + } catch (error) { + logger.error(error); + return; + } + const customerId = customer!.id; const customerPhoneNumber = await getCustomerPhoneNumber({ customerId }, context); diff --git a/app/messages/pages/messages.tsx b/app/messages/pages/messages.tsx index 534a0a6..1e1fbcc 100644 --- a/app/messages/pages/messages.tsx +++ b/app/messages/pages/messages.tsx @@ -1,22 +1,28 @@ -import { Suspense } from "react"; +import { Suspense, useState } from "react"; import type { BlitzPage } from "blitz"; import { Routes } from "blitz"; +import { useAtom } from "jotai"; import Layout from "../../core/layouts/layout"; import ConversationsList from "../components/conversations-list"; +import NewMessageButton from "../components/new-message-button"; +import NewMessageBottomSheet, { bottomSheetOpenAtom } from "../components/new-message-bottom-sheet"; import useRequireOnboarding from "../../core/hooks/use-require-onboarding"; const Messages: BlitzPage = () => { useRequireOnboarding(); + const setIsOpen = useAtom(bottomSheetOpenAtom)[1]; return ( <>
-

Messages page

+

Messages

+ setIsOpen(true)} /> + ); }; diff --git a/app/messages/pages/messages/[recipient].tsx b/app/messages/pages/messages/[recipient].tsx index 94753cc..5de12f2 100644 --- a/app/messages/pages/messages/[recipient].tsx +++ b/app/messages/pages/messages/[recipient].tsx @@ -16,7 +16,7 @@ const ConversationPage: BlitzPage = () => { useRequireOnboarding(); const router = useRouter(); - const recipient = router.params.recipient; + const recipient = decodeURIComponent(router.params.recipient); return ( <> @@ -39,7 +39,7 @@ const ConversationPage: BlitzPage = () => { ConversationPage.getLayout = function ConversationLayout(page) { const router = useRouter(); - const recipient = router.params.recipient; + const recipient = decodeURIComponent(router.params.recipient); const pageTitle = `Messages with ${recipient}`; return ( diff --git a/app/phone-calls/pages/calls.tsx b/app/phone-calls/pages/calls.tsx index 3bbe356..a40161f 100644 --- a/app/phone-calls/pages/calls.tsx +++ b/app/phone-calls/pages/calls.tsx @@ -12,7 +12,7 @@ const PhoneCalls: BlitzPage = () => { return ( <>
-

Calls page

+

Calls

diff --git a/app/settings/pages/settings.tsx b/app/settings/pages/settings.tsx index 8ac04ab..d445f71 100644 --- a/app/settings/pages/settings.tsx +++ b/app/settings/pages/settings.tsx @@ -33,22 +33,27 @@ const Settings: BlitzPage = () => { useRequireOnboarding(); return ( -
- -
+ <> +
+

Settings

+
+
+ +
+ ); }; diff --git a/package-lock.json b/package-lock.json index 2890ca9..418310b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1329,6 +1329,11 @@ "chalk": "^4.0.0" } }, + "@juggle/resize-observer": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz", + "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==" + }, "@mrleebo/prisma-ast": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@mrleebo/prisma-ast/-/prisma-ast-0.2.5.tgz", @@ -2212,6 +2217,161 @@ "pino": "^6.11.3" } }, + "@reach/portal": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@reach/portal/-/portal-0.13.2.tgz", + "integrity": "sha512-g74BnCdtuTGthzzHn2cWW+bcyIYb0iIE/yRsm89i8oNzNgpopbkh9UY8TPbhNlys52h7U60s4kpRTmcq+JqsTA==", + "requires": { + "@reach/utils": "0.13.2", + "tslib": "^2.1.0" + } + }, + "@reach/utils": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.13.2.tgz", + "integrity": "sha512-3ir6cN60zvUrwjOJu7C6jec/samqAeyAB12ZADK+qjnmQPdzSYldrFWwDVV5H0WkhbYXR3uh+eImu13hCetNPQ==", + "requires": { + "@types/warning": "^3.0.0", + "tslib": "^2.1.0", + "warning": "^4.0.3" + } + }, + "@react-aria/interactions": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.5.0.tgz", + "integrity": "sha512-EL5GWpzM9UHU17LztwgL/tF3H2tLG375CD64kieCgSfsRcCSlC3pavnPy9jbS8levdBQ2qo9e2xfoX5VtfJisw==", + "requires": { + "@babel/runtime": "^7.6.2", + "@react-aria/utils": "^3.8.1", + "@react-types/shared": "^3.7.0" + } + }, + "@react-aria/ssr": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.0.2.tgz", + "integrity": "sha512-+M0wrUlc2eTuMiwTfd0iFZJGu2hvMeYBLE8gRdbPJCDjLhrNWOQLKR/y6ntxQ9u8zjrNl/YPOdRtcqkA2EBnAQ==", + "requires": { + "@babel/runtime": "^7.6.2" + } + }, + "@react-aria/utils": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.8.1.tgz", + "integrity": "sha512-SvFf1T2HHAId6LS4+gbJNLQU9wr5GHuR5wA+HOtfVkZ82v3xhOnzfjR5qgjSLYGsPfqNgci5cpKYlHf4YqMf5w==", + "requires": { + "@babel/runtime": "^7.6.2", + "@react-aria/ssr": "^3.0.2", + "@react-stately/utils": "^3.2.1", + "@react-types/shared": "^3.7.0", + "clsx": "^1.1.1" + } + }, + "@react-spring/animated": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.2.4.tgz", + "integrity": "sha512-AfV6ZM8pCCAT29GY5C8/1bOPjZrv/7kD0vedjiE/tEYvNDwg9GlscrvsTViWR2XykJoYrDfdkYArrldWpsCJ5g==", + "requires": { + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/core": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.2.4.tgz", + "integrity": "sha512-R+PwyfsjiuYCWqaTTfCpYpRmsP0h87RNm7uxC1Uxy7QAHUfHEm2sAHn+AdHPwq/MbVwDssVT8C5yf2WGcqiXGg==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/konva": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/konva/-/konva-9.2.4.tgz", + "integrity": "sha512-19anDOIkfjcydDTfGgVIuZ3lruZxKubYGs9oHCswaP8SRLj7c1kkopJHUr/S4LXGxiIdqdF0XucWm0iTEPEq4w==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/native": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/native/-/native-9.2.4.tgz", + "integrity": "sha512-xKJWKh5qOhSclpL3iuGwJRLoZzTNvlBEnIrMs8yh8xvX6z9Lmnu4uGu5DpfrnM1GzBvRoktoCoLEx/VcEYFSng==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/rafz": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.2.4.tgz", + "integrity": "sha512-SOKf9eue+vAX+DGo7kWYNl9i9J3gPUlQjifIcV9Bzw9h3i30wPOOP0TjS7iMG/kLp2cdHQYDNFte6nt23VAZkQ==" + }, + "@react-spring/shared": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.2.4.tgz", + "integrity": "sha512-ZEr4l2BxmyFRUvRA2VCkPfCJii4E7cGkwbjmTBx1EmcGrOnde/V2eF5dxqCTY3k35QuCegkrWe0coRJVkh8q2Q==", + "requires": { + "@react-spring/rafz": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/three": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.2.4.tgz", + "integrity": "sha512-ljFig7XW099VWwRPKPUf+4yYLivp/sSWXN3oO5SJOF/9BSoV1quS/9chZ5Myl5J14od3CsHf89Tv4FdlX5kHlA==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/types": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.2.4.tgz", + "integrity": "sha512-zHUXrWO8nweUN/ISjrjqU7GgXXvoEbFca1CgiE0TY0H/dqJb3l+Rhx8ecPVNYimzFg3ZZ1/T0egpLop8SOv4aA==" + }, + "@react-spring/web": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.2.4.tgz", + "integrity": "sha512-vtPvOalLFvuju/MDBtoSnCyt0xXSL6Amyv82fljOuWPl1yGd4M1WteijnYL9Zlriljl0a3oXcPunAVYTD9dbDQ==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/zdog": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.2.4.tgz", + "integrity": "sha512-rv7ptedS37SHr6yuCbRkUErAzAhebdgt8f4KUtZWzseC+7qLNkaZWf+uujgsb881qAuX9b9yz8rre9UKeYepgw==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-stately/utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.2.1.tgz", + "integrity": "sha512-H79CYKPiQZrO1/dMSwjRJxsRlYg7y8PbTwnZOQ1h3DI5W6tD8CCLSlU1A5/Fp1GfcGNnK8gHqsJ9oJSRAwFS1g==", + "requires": { + "@babel/runtime": "^7.6.2" + } + }, + "@react-types/shared": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.7.1.tgz", + "integrity": "sha512-VNKlqh37UjB3Hd7gb5Hgsum/2x5mhd7vuBBGPEFevhkOMBW8KlqrU75yaKUe3rEFbky7H6+A8Dzoj4r68OS14w==" + }, "@rushstack/eslint-patch": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz", @@ -2786,6 +2946,11 @@ "@types/jest": "*" } }, + "@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" + }, "@types/yargs": { "version": "15.0.14", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", @@ -2935,6 +3100,15 @@ "eslint-visitor-keys": "^2.0.0" } }, + "@xstate/react": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@xstate/react/-/react-1.5.1.tgz", + "integrity": "sha512-DJHDqDlZHus08X98uMJw4KR17FRWBXLHMQ02YRxx0DMm5VLn75VwGyt4tXdlNZHQWjyk++C5c9Ichq3PdmM3og==", + "requires": { + "use-isomorphic-layout-effect": "^1.0.0", + "use-subscription": "^1.3.0" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -3800,6 +3974,11 @@ } } }, + "body-scroll-lock": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==" + }, "boolean": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz", @@ -6973,6 +7152,14 @@ "readable-stream": "^3.1.1" } }, + "focus-trap": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.6.0.tgz", + "integrity": "sha512-2hWVR3XbBejn5v8wDW9DFzLWXcxMNaSJ/CtE3E+FJjjBCLwIYbZJwjUi2RDBfQPM58gHEt5hck0jrJgHR9/s+A==", + "requires": { + "tabbable": "^5.2.0" + } + }, "follow-redirects": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", @@ -12382,6 +12569,50 @@ "react-is": "^16.12.0 || ^17.0.0" } }, + "react-spring": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.2.4.tgz", + "integrity": "sha512-bMjbyTW0ZGd+/h9cjtohLqCwOGqX2OuaTvalOVfLCGmhzEg/u3GgopI3LAm4UD2Br3MNdVdGgNVoESg4MGqKFQ==", + "requires": { + "@react-spring/core": "~9.2.0", + "@react-spring/konva": "~9.2.0", + "@react-spring/native": "~9.2.0", + "@react-spring/three": "~9.2.0", + "@react-spring/web": "~9.2.0", + "@react-spring/zdog": "~9.2.0" + } + }, + "react-spring-bottom-sheet": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/react-spring-bottom-sheet/-/react-spring-bottom-sheet-3.4.0.tgz", + "integrity": "sha512-zKwTymxrTRMHPjfBiMw8reQlWoVqlCGMTefmMYkAlBvR7n3hBe5sntuQJAEjmrAnA+cLSGp44mtmgBtT2ksL5Q==", + "requires": { + "@juggle/resize-observer": "^3.2.0", + "@reach/portal": "^0.13.0", + "@xstate/react": "^1.2.0", + "body-scroll-lock": "^3.1.5", + "focus-trap": "^6.2.2", + "react-spring": "^8.0.27", + "react-use-gesture": "^8.0.1", + "xstate": "^4.15.1" + }, + "dependencies": { + "react-spring": { + "version": "8.0.27", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz", + "integrity": "sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==", + "requires": { + "@babel/runtime": "^7.3.1", + "prop-types": "^15.5.8" + } + }, + "react-use-gesture": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-8.0.1.tgz", + "integrity": "sha512-CXzUNkulUdgouaAlvAsC5ZVo0fi9KGSBSk81WrE4kOIcJccpANe9zZkAYr5YZZhqpicIFxitsrGVS4wmoMun9A==" + } + } + }, "react-test-renderer": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.1.tgz", @@ -12400,6 +12631,11 @@ } } }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==" + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -13962,6 +14198,11 @@ "rename-overwrite": "^3.0.0" } }, + "tabbable": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.2.0.tgz", + "integrity": "sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg==" + }, "table": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", @@ -14821,6 +15062,11 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==" + }, "use-subscription": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", @@ -15144,6 +15390,14 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", @@ -15352,6 +15606,11 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xstate": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.23.1.tgz", + "integrity": "sha512-8ZoCe8d6wDSPfkep+GBgi+fKAdMyXcaizoNf5FKceEhlso4+9n1TeK6oviaDsXZ3Z5O8xKkJOxXPNuD4cA9LCw==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 86b0ca8..69a1e04 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,9 @@ "react": "18.0.0-alpha-6f3fcbd6f-20210730", "react-dom": "18.0.0-alpha-6f3fcbd6f-20210730", "react-hook-form": "7.12.2", + "react-spring": "9.2.4", + "react-spring-bottom-sheet": "3.4.0", + "react-use-gesture": "9.1.3", "tailwindcss": "2.2.7", "twilio": "3.66.1", "zod": "3.5.1"