extract conversation loader

This commit is contained in:
m5r 2022-05-22 13:04:26 +02:00
parent 3afc1d27cf
commit 331d53a8a8
2 changed files with 57 additions and 49 deletions

View File

@ -0,0 +1,51 @@
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 db from "~/utils/db.server";
import { requireLoggedIn } from "~/utils/auth.server";
type ConversationType = {
recipient: string;
formattedPhoneNumber: string;
messages: Message[];
};
export type ConversationLoaderData = {
conversation: ConversationType;
};
const loader: LoaderFunction = async ({ request, params }) => {
const { organization } = await requireLoggedIn(request);
const recipient = decodeURIComponent(params.recipient ?? "");
const conversation = await getConversation(recipient);
return json<ConversationLoaderData>({ conversation });
async function getConversation(recipient: string): Promise<ConversationType> {
const organizationId = organization.id;
const phoneNumber = await db.phoneNumber.findUnique({
where: { organizationId_isCurrent: { organizationId, isCurrent: true } },
});
if (!phoneNumber || phoneNumber.isFetchingMessages) {
throw new Error("unreachable");
}
const formattedPhoneNumber = parsePhoneNumber(recipient).getNumber("international");
const messages = await db.message.findMany({
where: {
phoneNumberId: phoneNumber.id,
OR: [{ from: recipient }, { to: recipient }],
},
orderBy: { sentAt: Prisma.SortOrder.asc },
});
return {
recipient,
formattedPhoneNumber,
messages,
};
}
};
export default loader;

View File

@ -1,15 +1,12 @@
import type { LoaderFunction, MetaFunction } from "@remix-run/node"; import type { MetaFunction } from "@remix-run/node";
import { Link, useNavigate, useParams } from "@remix-run/react"; import { Link, useNavigate, useParams } from "@remix-run/react";
import { json, useLoaderData } from "superjson-remix"; import { useLoaderData } from "superjson-remix";
import { IoCall, IoChevronBack } from "react-icons/io5"; import { IoCall, IoChevronBack } from "react-icons/io5";
import { parsePhoneNumber } from "awesome-phonenumber";
import { type Message, Prisma } from "@prisma/client";
import Conversation from "~/features/messages/components/conversation"; import Conversation from "~/features/messages/components/conversation";
import { getSeoMeta } from "~/utils/seo"; import { getSeoMeta } from "~/utils/seo";
import db from "~/utils/db.server"; import conversationAction from "~/features/messages/actions/messages.$recipient";
import { requireLoggedIn } from "~/utils/auth.server"; import conversationLoader, { type ConversationLoaderData } from "~/features/messages/loaders/messages.$recipient";
import newMessageAction from "~/features/messages/actions/messages.$recipient";
export const meta: MetaFunction = ({ params }) => { export const meta: MetaFunction = ({ params }) => {
const recipient = decodeURIComponent(params.recipient ?? ""); const recipient = decodeURIComponent(params.recipient ?? "");
@ -21,49 +18,9 @@ export const meta: MetaFunction = ({ params }) => {
}; };
}; };
export const action = newMessageAction; export const action = conversationAction;
type ConversationType = { export const loader = conversationLoader;
recipient: string;
formattedPhoneNumber: string;
messages: Message[];
};
export type ConversationLoaderData = {
conversation: ConversationType;
};
export const loader: LoaderFunction = async ({ request, params }) => {
const { organization } = await requireLoggedIn(request);
const recipient = decodeURIComponent(params.recipient ?? "");
const conversation = await getConversation(recipient);
return json<ConversationLoaderData>({ conversation });
async function getConversation(recipient: string): Promise<ConversationType> {
const organizationId = organization.id;
const phoneNumber = await db.phoneNumber.findUnique({
where: { organizationId_isCurrent: { organizationId, isCurrent: true } },
});
if (!phoneNumber || phoneNumber.isFetchingMessages) {
throw new Error("unreachable");
}
const formattedPhoneNumber = parsePhoneNumber(recipient).getNumber("international");
const messages = await db.message.findMany({
where: {
phoneNumberId: phoneNumber.id,
OR: [{ from: recipient }, { to: recipient }],
},
orderBy: { sentAt: Prisma.SortOrder.asc },
});
return {
recipient,
formattedPhoneNumber,
messages,
};
}
};
export default function ConversationPage() { export default function ConversationPage() {
const navigate = useNavigate(); const navigate = useNavigate();