session thingy for onboarding checks
This commit is contained in:
parent
7acbca65ce
commit
7d34fcd48f
@ -4,14 +4,14 @@ 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.customer.deleteMany();
|
||||
await db.user.deleteMany();*/
|
||||
|
||||
await db.user.deleteMany();
|
||||
const accountSid = "ACa886d066be0832990d1cf43fb1d53362";
|
||||
const authToken = "8696a59a64b94bb4eba3548ed815953b";
|
||||
/*const ddd = await twilio(accountSid, authToken)
|
||||
@ -37,6 +37,17 @@ export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) {
|
||||
to: "+33757592025",
|
||||
from: "+33757592722",
|
||||
});*/
|
||||
/*const [messagesSent, messagesReceived] = await Promise.all([
|
||||
twilio(accountSid, authToken).messages.list({
|
||||
from: "+33757592025",
|
||||
}),
|
||||
twilio(accountSid, authToken).messages.list({
|
||||
to: "+33757592025",
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log("messagesReceived", messagesReceived.sort((a, b) => a.dateCreated.getTime() - b.dateCreated.getTime()));
|
||||
// console.log("messagesReceived", messagesReceived);*/
|
||||
|
||||
res.status(200).end();
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { useQuery } from "blitz";
|
||||
import { useAuthenticatedSession, useQuery } from "blitz";
|
||||
|
||||
import getCurrentCustomer from "../../customers/queries/get-current-customer";
|
||||
|
||||
export default function useCurrentCustomer() {
|
||||
const session = useAuthenticatedSession();
|
||||
const [customer] = useQuery(getCurrentCustomer, null);
|
||||
return {
|
||||
customer,
|
||||
hasCompletedOnboarding: Boolean(!!customer && customer.accountSid && customer.authToken),
|
||||
hasFilledTwilioCredentials: Boolean(customer && customer.accountSid && customer.authToken),
|
||||
hasCompletedOnboarding: session.hasCompletedOnboarding,
|
||||
};
|
||||
}
|
||||
|
@ -4,12 +4,9 @@ import getCurrentCustomerPhoneNumber from "../../phone-numbers/queries/get-curre
|
||||
import useCurrentCustomer from "./use-current-customer";
|
||||
|
||||
export default function useCustomerPhoneNumber() {
|
||||
const { hasCompletedOnboarding } = useCurrentCustomer();
|
||||
const [customerPhoneNumber] = useQuery(
|
||||
getCurrentCustomerPhoneNumber,
|
||||
{},
|
||||
{ enabled: hasCompletedOnboarding },
|
||||
);
|
||||
const { customer } = useCurrentCustomer();
|
||||
const hasFilledTwilioCredentials = Boolean(customer && customer.accountSid && customer.authToken);
|
||||
const [customerPhoneNumber] = useQuery(getCurrentCustomerPhoneNumber, {}, { enabled: hasFilledTwilioCredentials });
|
||||
|
||||
return customerPhoneNumber;
|
||||
}
|
||||
|
@ -5,10 +5,14 @@ import useCustomerPhoneNumber from "./use-customer-phone-number";
|
||||
|
||||
export default function useRequireOnboarding() {
|
||||
const router = useRouter();
|
||||
const { customer, hasCompletedOnboarding } = useCurrentCustomer();
|
||||
const { hasFilledTwilioCredentials, hasCompletedOnboarding } = useCurrentCustomer();
|
||||
const customerPhoneNumber = useCustomerPhoneNumber();
|
||||
|
||||
if (!hasCompletedOnboarding) {
|
||||
if (hasCompletedOnboarding) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasFilledTwilioCredentials) {
|
||||
throw router.push(Routes.StepTwo());
|
||||
}
|
||||
|
||||
@ -17,7 +21,6 @@ export default function useRequireOnboarding() {
|
||||
return;
|
||||
}*/
|
||||
|
||||
console.log("customerPhoneNumber", customerPhoneNumber);
|
||||
if (!customerPhoneNumber) {
|
||||
throw router.push(Routes.StepThree());
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ const Keypad: BlitzPage = () => {
|
||||
</Row>
|
||||
<Row>
|
||||
<div className="cursor-pointer select-none col-start-2 h-12 w-12 flex justify-center items-center mx-auto bg-green-800 rounded-full">
|
||||
<FontAwesomeIcon icon={faPhone} color="white" size="lg" />
|
||||
<FontAwesomeIcon className="w-6 h-6" icon={faPhone} color="white" size="lg" />
|
||||
</div>
|
||||
<div className="cursor-pointer select-none my-auto" onClick={pressBackspace}>
|
||||
<FontAwesomeIcon icon={faBackspace} size="lg" />
|
||||
<div className="cursor-pointer select-none m-auto" onClick={pressBackspace}>
|
||||
<FontAwesomeIcon className="w-6 h-6" icon={faBackspace} size="lg" />
|
||||
</div>
|
||||
</Row>
|
||||
</section>
|
||||
@ -112,9 +112,7 @@ const Digit: FunctionComponent<{ digit: string }> = ({ children, digit }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DigitLetters: FunctionComponent = ({ children }) => (
|
||||
<div className="text-xs text-gray-600">{children}</div>
|
||||
);
|
||||
const DigitLetters: FunctionComponent = ({ children }) => <div className="text-xs text-gray-600">{children}</div>;
|
||||
|
||||
const phoneNumberAtom = atom("");
|
||||
const pressDigitAtom = atom(null, (get, set, digit: string) => {
|
||||
|
@ -12,14 +12,12 @@ const fetchMessagesQueue = Queue<Payload>("api/queue/fetch-messages", async ({ c
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } });
|
||||
|
||||
const [messagesSent, messagesReceived] = await Promise.all([
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({
|
||||
from: phoneNumber!.phoneNumber,
|
||||
}),
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({
|
||||
to: phoneNumber!.phoneNumber,
|
||||
}),
|
||||
const [sent, received] = await Promise.all([
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({ from: phoneNumber!.phoneNumber }),
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({ to: phoneNumber!.phoneNumber }),
|
||||
]);
|
||||
const messagesSent = sent.filter((message) => message.direction.startsWith("outbound"));
|
||||
const messagesReceived = received.filter((message) => message.direction === "inbound");
|
||||
const messages = [...messagesSent, ...messagesReceived].sort(
|
||||
(a, b) => a.dateCreated.getTime() - b.dateCreated.getTime(),
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Suspense, useState } from "react";
|
||||
import { Suspense } from "react";
|
||||
import type { BlitzPage } from "blitz";
|
||||
import { Routes } from "blitz";
|
||||
import { useAtom } from "jotai";
|
||||
|
@ -1,9 +1,7 @@
|
||||
import type { FunctionComponent } from "react";
|
||||
import { Link } from "blitz";
|
||||
import { CheckIcon } from "@heroicons/react/solid";
|
||||
import clsx from "clsx";
|
||||
import { Link, Routes, useRouter } from "blitz";
|
||||
|
||||
import useCustomerPhoneNumber from "../../core/hooks/use-customer-phone-number";
|
||||
|
||||
type StepLink = {
|
||||
href: string;
|
||||
@ -19,13 +17,6 @@ type Props = {
|
||||
const steps = ["Welcome", "Twilio Credentials", "Pick a plan"] as const;
|
||||
|
||||
const OnboardingLayout: FunctionComponent<Props> = ({ children, currentStep, previous, next }) => {
|
||||
const router = useRouter();
|
||||
const customerPhoneNumber = useCustomerPhoneNumber();
|
||||
|
||||
if (customerPhoneNumber) {
|
||||
throw router.push(Routes.Messages());
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-gray-800 fixed z-10 inset-0 overflow-y-auto">
|
||||
<div className="min-h-screen text-center block p-0">
|
||||
|
@ -12,29 +12,23 @@ const Body = z.object({
|
||||
phoneNumberSid: z.string(),
|
||||
});
|
||||
|
||||
export default resolver.pipe(
|
||||
resolver.zod(Body),
|
||||
resolver.authorize(),
|
||||
async ({ phoneNumberSid }, context) => {
|
||||
const customer = await getCurrentCustomer(null, context);
|
||||
const customerId = customer!.id;
|
||||
const phoneNumbers = await twilio(
|
||||
customer!.accountSid!,
|
||||
customer!.authToken!,
|
||||
).incomingPhoneNumbers.list();
|
||||
const phoneNumber = phoneNumbers.find((phoneNumber) => phoneNumber.sid === phoneNumberSid)!;
|
||||
await db.phoneNumber.create({
|
||||
data: {
|
||||
customerId,
|
||||
phoneNumberSid,
|
||||
phoneNumber: phoneNumber.phoneNumber,
|
||||
},
|
||||
});
|
||||
export default resolver.pipe(resolver.zod(Body), resolver.authorize(), async ({ phoneNumberSid }, context) => {
|
||||
const customer = await getCurrentCustomer(null, context);
|
||||
const customerId = customer!.id;
|
||||
const phoneNumbers = await twilio(customer!.accountSid!, customer!.authToken!).incomingPhoneNumbers.list();
|
||||
const phoneNumber = phoneNumbers.find((phoneNumber) => phoneNumber.sid === phoneNumberSid)!;
|
||||
await db.phoneNumber.create({
|
||||
data: {
|
||||
customerId,
|
||||
phoneNumberSid,
|
||||
phoneNumber: phoneNumber.phoneNumber,
|
||||
},
|
||||
});
|
||||
context.session.$setPrivateData({ hasCompletedOnboarding: true });
|
||||
|
||||
await Promise.all([
|
||||
fetchMessagesQueue.enqueue({ customerId }, { id: `fetch-messages-${customerId}` }),
|
||||
fetchCallsQueue.enqueue({ customerId }, { id: `fetch-messages-${customerId}` }),
|
||||
setTwilioWebhooks.enqueue({ customerId }, { id: `set-twilio-webhooks-${customerId}` }),
|
||||
]);
|
||||
},
|
||||
);
|
||||
await Promise.all([
|
||||
fetchMessagesQueue.enqueue({ customerId }, { id: `fetch-messages-${customerId}` }),
|
||||
fetchCallsQueue.enqueue({ customerId }, { id: `fetch-messages-${customerId}` }),
|
||||
setTwilioWebhooks.enqueue({ customerId }, { id: `set-twilio-webhooks-${customerId}` }),
|
||||
]);
|
||||
});
|
||||
|
@ -16,10 +16,7 @@ const StepOne: BlitzPage = () => {
|
||||
};
|
||||
|
||||
StepOne.getLayout = (page) => (
|
||||
<OnboardingLayout
|
||||
currentStep={1}
|
||||
next={{ href: Routes.StepTwo().pathname, label: "Set up your phone number" }}
|
||||
>
|
||||
<OnboardingLayout currentStep={1} next={{ href: Routes.StepTwo().pathname, label: "Set up your phone number" }}>
|
||||
{page}
|
||||
</OnboardingLayout>
|
||||
);
|
||||
@ -39,16 +36,17 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
}
|
||||
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId: session.userId } });
|
||||
if (!phoneNumber) {
|
||||
return { props: {} };
|
||||
if (phoneNumber) {
|
||||
await session.$setPublicData({ hasCompletedOnboarding: true });
|
||||
return {
|
||||
redirect: {
|
||||
destination: Routes.Messages().pathname,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
redirect: {
|
||||
destination: Routes.Messages().pathname,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
return { props: {} };
|
||||
};
|
||||
|
||||
export default StepOne;
|
||||
|
@ -102,6 +102,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, res }
|
||||
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId: session.userId } });
|
||||
if (phoneNumber) {
|
||||
await session.$setPublicData({ hasCompletedOnboarding: true });
|
||||
return {
|
||||
redirect: {
|
||||
destination: Routes.Messages().pathname,
|
||||
@ -129,10 +130,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, res }
|
||||
};
|
||||
}
|
||||
|
||||
const incomingPhoneNumbers = await twilio(
|
||||
customer.accountSid,
|
||||
customer.authToken,
|
||||
).incomingPhoneNumbers.list();
|
||||
const incomingPhoneNumbers = await twilio(customer.accountSid, customer.authToken).incomingPhoneNumbers.list();
|
||||
const phoneNumbers = incomingPhoneNumbers.map(({ phoneNumber, sid }) => ({ phoneNumber, sid }));
|
||||
|
||||
return {
|
||||
|
@ -48,10 +48,7 @@ const StepTwo: BlitzPage = () => {
|
||||
<div className="flex flex-col space-y-4 items-center">
|
||||
<form onSubmit={onSubmit} className="flex flex-col gap-6">
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="twilioAccountSid"
|
||||
className="block text-sm font-medium text-gray-700"
|
||||
>
|
||||
<label htmlFor="twilioAccountSid" className="block text-sm font-medium text-gray-700">
|
||||
Twilio Account SID
|
||||
</label>
|
||||
<input
|
||||
@ -62,10 +59,7 @@ const StepTwo: BlitzPage = () => {
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="twilioAuthToken"
|
||||
className="block text-sm font-medium text-gray-700"
|
||||
>
|
||||
<label htmlFor="twilioAuthToken" className="block text-sm font-medium text-gray-700">
|
||||
Twilio Auth Token
|
||||
</label>
|
||||
<input
|
||||
@ -108,11 +102,7 @@ const StepTwoLayout: FunctionComponent = ({ children }) => {
|
||||
return (
|
||||
<OnboardingLayout
|
||||
currentStep={2}
|
||||
next={
|
||||
hasTwilioCredentials
|
||||
? { href: Routes.StepThree().pathname, label: "Next" }
|
||||
: undefined
|
||||
}
|
||||
next={hasTwilioCredentials ? { href: Routes.StepThree().pathname, label: "Next" } : undefined}
|
||||
previous={{ href: Routes.StepOne().pathname, label: "Back" }}
|
||||
>
|
||||
{children}
|
||||
@ -135,16 +125,17 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
}
|
||||
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId: session.userId } });
|
||||
if (!phoneNumber) {
|
||||
return { props: {} };
|
||||
if (phoneNumber) {
|
||||
await session.$setPublicData({ hasCompletedOnboarding: true });
|
||||
return {
|
||||
redirect: {
|
||||
destination: Routes.Messages().pathname,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
redirect: {
|
||||
destination: Routes.Messages().pathname,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
return { props: {} };
|
||||
};
|
||||
|
||||
export default StepTwo;
|
||||
|
@ -22,7 +22,8 @@ test.skip("renders blitz documentation link", () => {
|
||||
paddleSubscriptionId: null,
|
||||
user: {} as any,
|
||||
},
|
||||
hasCompletedOnboarding: false,
|
||||
hasFilledTwilioCredentials: false,
|
||||
hasCompletedOnboarding: undefined,
|
||||
});
|
||||
|
||||
const { getByText } = render(<Home />);
|
||||
|
@ -21,7 +21,7 @@
|
||||
"semi": true,
|
||||
"useTabs": true,
|
||||
"tabWidth": 4,
|
||||
"printWidth": 100,
|
||||
"printWidth": 120,
|
||||
"trailingComma": "all",
|
||||
"jsxBracketSameLine": false,
|
||||
"quoteProps": "as-needed",
|
||||
|
Loading…
Reference in New Issue
Block a user