diff --git a/app/features/keypad/loaders/keypad.ts b/app/features/keypad/loaders/keypad.ts index 401b93a..549b4e9 100644 --- a/app/features/keypad/loaders/keypad.ts +++ b/app/features/keypad/loaders/keypad.ts @@ -12,7 +12,10 @@ export type KeypadLoaderData = { }; const loader: LoaderFunction = async ({ request }) => { - const { phoneNumber } = await requireLoggedIn(request); + const { twilio } = await requireLoggedIn(request); + const phoneNumber = await db.phoneNumber.findUnique({ + where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } }, + }); const hasOngoingSubscription = true; // TODO const hasPhoneNumber = Boolean(phoneNumber); const lastCall = diff --git a/app/features/messages/actions/messages.$recipient.tsx b/app/features/messages/actions/messages.$recipient.tsx index 1436bb1..c2aa8ca 100644 --- a/app/features/messages/actions/messages.$recipient.tsx +++ b/app/features/messages/actions/messages.$recipient.tsx @@ -8,12 +8,17 @@ import getTwilioClient, { translateMessageDirection, translateMessageStatus } fr export type NewMessageActionData = {}; const action: ActionFunction = async ({ params, request }) => { - const { phoneNumber, twilio } = await requireLoggedIn(request); + const { twilio } = await requireLoggedIn(request); if (!twilio) { throw new Error("unreachable"); } - const twilioAccount = await db.twilioAccount.findUnique({ where: { accountSid: twilio.accountSid } }); - if (!twilioAccount) { + const [phoneNumber, twilioAccount] = await Promise.all([ + db.phoneNumber.findUnique({ + where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio.accountSid ?? "", isCurrent: true } }, + }), + db.twilioAccount.findUnique({ where: { accountSid: twilio.accountSid } }), + ]); + if (!phoneNumber || !twilioAccount) { throw new Error("unreachable"); } @@ -24,11 +29,11 @@ const action: ActionFunction = async ({ params, request }) => { const message = await twilioClient.messages.create({ body: formData.content.toString(), to: recipient, - from: phoneNumber!.number, + from: phoneNumber.number, }); await db.message.create({ data: { - phoneNumberId: phoneNumber!.id, + phoneNumberId: phoneNumber.id, id: message.sid, to: message.to, recipient: message.to, diff --git a/app/features/messages/components/conversation.tsx b/app/features/messages/components/conversation.tsx index 383f0fa..22ae9a5 100644 --- a/app/features/messages/components/conversation.tsx +++ b/app/features/messages/components/conversation.tsx @@ -7,13 +7,11 @@ import { Direction } from "@prisma/client"; import NewMessageArea from "./new-message-area"; import { formatDate, formatTime } from "~/features/core/helpers/date-formatter"; import { type ConversationLoaderData } from "~/features/messages/loaders/messages.$recipient"; -import useSession from "~/features/core/hooks/use-session"; export default function Conversation() { - const { phoneNumber } = useSession(); const params = useParams<{ recipient: string }>(); const recipient = decodeURIComponent(params.recipient ?? ""); - const { conversation } = useLoaderData(); + const { conversation, currentPhoneNumber } = useLoaderData(); const transition = useTransition(); const messagesListRef = useRef(null); @@ -21,8 +19,8 @@ export default function Conversation() { if (transition.submission) { messages.push({ id: "temp", - phoneNumberId: phoneNumber!.id, - from: phoneNumber!.number, + phoneNumberId: currentPhoneNumber!.id, + from: currentPhoneNumber!.number, to: recipient, recipient, sentAt: new Date(), diff --git a/app/features/messages/loaders/messages.$recipient.ts b/app/features/messages/loaders/messages.$recipient.ts index 77cc795..05a5b26 100644 --- a/app/features/messages/loaders/messages.$recipient.ts +++ b/app/features/messages/loaders/messages.$recipient.ts @@ -1,7 +1,7 @@ import type { LoaderFunction } from "@remix-run/node"; import { json } from "superjson-remix"; import { parsePhoneNumber } from "awesome-phonenumber"; -import { type Message, Prisma } from "@prisma/client"; +import { type Message, type PhoneNumber, Prisma } from "@prisma/client"; import db from "~/utils/db.server"; import { requireLoggedIn } from "~/utils/auth.server"; @@ -15,6 +15,7 @@ type ConversationType = { export type ConversationLoaderData = { conversation: ConversationType; + currentPhoneNumber: Pick; }; const loader: LoaderFunction = async ({ request, params }) => { @@ -24,10 +25,26 @@ const loader: LoaderFunction = async ({ request, params }) => { } const twilioAccountSid = twilio.accountSid; + const currentPhoneNumber = await db.phoneNumber.findUnique({ + where: { + twilioAccountSid_isCurrent: { + twilioAccountSid, + isCurrent: true, + }, + }, + select: { + id: true, + number: true, + }, + }); + if (!currentPhoneNumber) { + return redirect("/messages"); + } + const recipient = decodeURIComponent(params.recipient ?? ""); const conversation = await getConversation(recipient); - return json({ conversation }); + return json({ conversation, currentPhoneNumber }); async function getConversation(recipient: string): Promise { const phoneNumber = await db.phoneNumber.findUnique({ diff --git a/app/features/messages/loaders/messages.ts b/app/features/messages/loaders/messages.ts index ced9155..af2787c 100644 --- a/app/features/messages/loaders/messages.ts +++ b/app/features/messages/loaders/messages.ts @@ -19,12 +19,10 @@ type Conversation = { }; const loader: LoaderFunction = async ({ request }) => { - const sessionData = await requireLoggedIn(request); - const phoneNumber = - sessionData.phoneNumber && - (await db.phoneNumber.findUnique({ - where: { id: sessionData.phoneNumber.id }, - })); + const { twilio } = await requireLoggedIn(request); + const phoneNumber = await db.phoneNumber.findUnique({ + where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } }, + }); return json({ hasPhoneNumber: Boolean(phoneNumber), isFetchingMessages: phoneNumber?.isFetchingMessages ?? null, diff --git a/app/features/phone-calls/loaders/calls.ts b/app/features/phone-calls/loaders/calls.ts index 0cf1f6e..3fb4bff 100644 --- a/app/features/phone-calls/loaders/calls.ts +++ b/app/features/phone-calls/loaders/calls.ts @@ -26,20 +26,12 @@ export type PhoneCallsLoaderData = { ); const loader: LoaderFunction = async ({ request }) => { - const sessionData = await requireLoggedIn(request); - const hasOngoingSubscription = true; // TODO - const hasPhoneNumber = Boolean(sessionData.phoneNumber); - if (!sessionData.phoneNumber) { - return json({ - hasOngoingSubscription, - hasPhoneNumber: false, - isFetchingCalls: false, - }); - } - + const { twilio } = await requireLoggedIn(request); const phoneNumber = await db.phoneNumber.findUnique({ - where: { id: sessionData.phoneNumber.id }, + where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } }, }); + const hasPhoneNumber = Boolean(phoneNumber); + const hasOngoingSubscription = true; // TODO if (!phoneNumber || phoneNumber.isFetchingCalls) { return json({ hasOngoingSubscription, diff --git a/app/features/settings/actions/phone.ts b/app/features/settings/actions/phone.ts index e857358..cd7f85c 100644 --- a/app/features/settings/actions/phone.ts +++ b/app/features/settings/actions/phone.ts @@ -75,16 +75,8 @@ async function setPhoneNumber(request: Request, formData: unknown) { phoneNumberId: validation.data.phoneNumberSid, organizationId: organization.id, }); - const { session } = await refreshSessionData(request); - return json( - { setPhoneNumber: { submitted: true } }, - { - headers: { - "Set-Cookie": await commitSession(session), - }, - }, - ); + return json({ setPhoneNumber: { submitted: true } }); } export type SetTwilioCredentialsActionData = FormActionData; diff --git a/app/features/settings/components/phone/phone-number-form.tsx b/app/features/settings/components/phone/phone-number-form.tsx index 12f1c93..a29eaed 100644 --- a/app/features/settings/components/phone/phone-number-form.tsx +++ b/app/features/settings/components/phone/phone-number-form.tsx @@ -10,7 +10,7 @@ import type { SetPhoneNumberActionData } from "~/features/settings/actions/phone import clsx from "clsx"; export default function PhoneNumberForm() { - const { twilio, phoneNumber } = useSession(); + const { twilio } = useSession(); const fetcher = useFetcher(); const transition = useTransition(); const actionData = useActionData()?.setPhoneNumber; diff --git a/app/utils/auth.server.ts b/app/utils/auth.server.ts index 86f6016..eb11533 100644 --- a/app/utils/auth.server.ts +++ b/app/utils/auth.server.ts @@ -1,7 +1,7 @@ import { redirect, type Session } from "@remix-run/node"; import type { FormStrategyVerifyParams } from "remix-auth-form"; import SecurePassword from "secure-password"; -import type { MembershipRole, Organization, PhoneNumber, TwilioAccount, User } from "@prisma/client"; +import type { MembershipRole, Organization, TwilioAccount, User } from "@prisma/client"; import db from "./db.server"; import logger from "./logger.server"; @@ -11,12 +11,10 @@ import { commitSession, destroySession, getSession } from "./session.server"; type SessionTwilioAccount = Pick; type SessionOrganization = Pick & { role: MembershipRole; membershipId: string }; -type SessionPhoneNumber = Pick; export type SessionUser = Pick; export type SessionData = { user: SessionUser; organization: SessionOrganization; - phoneNumber: SessionPhoneNumber | null; twilio: SessionTwilioAccount | null; }; @@ -198,13 +196,9 @@ async function buildSessionData(id: string): Promise { membershipId: membership.id, })); const { twilioAccount, ...organization } = organizations[0]; - const phoneNumber = await db.phoneNumber.findUnique({ - where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilioAccount?.accountSid ?? "", isCurrent: true } }, - }); return { user: rest, organization, - phoneNumber, twilio: twilioAccount, }; }