diff --git a/src/app/boards/[...boardId]/components/NewCardForm.tsx b/src/app/boards/[...boardId]/components/NewCardForm.tsx
index 6a73b6e3..96ffbfd3 100644
--- a/src/app/boards/[...boardId]/components/NewCardForm.tsx
+++ b/src/app/boards/[...boardId]/components/NewCardForm.tsx
@@ -14,6 +14,7 @@ import { useModal } from "~/app/providers/modal";
interface FormData {
title: string;
listPublicId: string;
+ memberPublicIds: string[];
}
interface NewCardFormProps {
@@ -34,9 +35,12 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
defaultValues: {
title: "",
listPublicId,
+ memberPublicIds: [],
},
});
+ const memberPublicIds = watch("memberPublicIds") || [];
+
const refetchBoard = () =>
utils.board.byId.refetch({ id: boardData.publicId });
@@ -64,10 +68,18 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
selected: list.publicId === watch("listPublicId"),
})) ?? [];
+ const formattedMembers =
+ boardData?.workspace?.members?.map((member) => ({
+ key: member.publicId,
+ value: member.user.name,
+ selected: memberPublicIds.includes(member.publicId),
+ })) ?? [];
+
const onSubmit = (data: FormData) => {
createCard.mutate({
title: data.title,
listPublicId: data.listPublicId,
+ memberPublicIds: data.memberPublicIds,
});
reset();
};
@@ -76,6 +88,17 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
setValue("listPublicId", listPublicId);
};
+ const handleSelectMembers = (memberPublicId: string): void => {
+ const currentIndex = memberPublicIds.indexOf(memberPublicId);
+ if (currentIndex === -1) {
+ setValue("memberPublicIds", [...memberPublicIds, memberPublicId]);
+ } else {
+ const newMemberPublicIds = [...memberPublicIds];
+ newMemberPublicIds.splice(currentIndex, 1);
+ setValue("memberPublicIds", newMemberPublicIds);
+ }
+ };
+
const selectedList = formattedLists.find((item) => item.selected);
return (
@@ -105,16 +128,59 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
className="block w-full rounded-md border-0 bg-dark-300 bg-white/5 py-1.5 text-dark-1000 shadow-sm ring-1 ring-inset ring-dark-700 focus:ring-2 focus:ring-inset focus:ring-dark-700 sm:text-sm sm:leading-6"
/>
-
-
handleSelectList(list.key)}
- >
-
- {selectedList?.value}
-
-
+
+
+
+ handleSelectList(list.key)
+ }
+ >
+
+ {selectedList?.value}
+
+
+
+
+
+ handleSelectMembers(list.key)
+ }
+ >
+
+ {!memberPublicIds.length ? (
+ "Members"
+ ) : (
+ <>
+ {memberPublicIds.map((memberPublicId) => {
+ const member = formattedMembers.find(
+ (member) => member.key === memberPublicId,
+ );
+
+ return (
+
+
+ {member?.value
+ .split(" ")
+ .map((namePart) =>
+ namePart.charAt(0).toUpperCase(),
+ )
+ .join("")}
+
+
+ );
+ })}
+ >
+ )}
+
+
+
+
Create more
(undefined);
diff --git a/src/server/api/routers/board.ts b/src/server/api/routers/board.ts
index 849a7a3d..c2d72ab9 100644
--- a/src/server/api/routers/board.ts
+++ b/src/server/api/routers/board.ts
@@ -43,6 +43,25 @@ export const boardRouter = createTRPCRouter({
name: true,
},
with: {
+ workspace: {
+ columns: {
+ publicId: true,
+ },
+ with: {
+ members: {
+ columns: {
+ publicId: true,
+ },
+ with: {
+ user: {
+ columns: {
+ name: true
+ }
+ }
+ }
+ }
+ }
+ },
lists: {
orderBy: [asc(lists.index)],
where: isNull(cards.deletedAt),
diff --git a/src/server/api/routers/card.ts b/src/server/api/routers/card.ts
index 29c148f3..56715a68 100644
--- a/src/server/api/routers/card.ts
+++ b/src/server/api/routers/card.ts
@@ -1,5 +1,5 @@
import { z } from "zod";
-import { and, desc, eq, isNull, sql } from "drizzle-orm";
+import { and, desc, eq, isNull, inArray, sql } from "drizzle-orm";
import { cards, cardsToLabels, cardToWorkspaceMembers, labels, lists, workspaceMembers } from "~/server/db/schema";
import { generateUID } from "~/utils/generateUID";
@@ -15,6 +15,7 @@ export const cardRouter = createTRPCRouter({
z.object({
title: z.string().min(1),
listPublicId: z.string().min(12),
+ memberPublicIds: z.array(z.string().min(12))
}),
)
.mutation(({ ctx, input }) => {
@@ -40,13 +41,27 @@ export const cardRouter = createTRPCRouter({
orderBy: desc(cards.index)
});
- return tx.insert(cards).values({
+ const newCard = await tx.insert(cards).values({
publicId: generateUID(),
title: input.title,
createdBy: userId,
listId: list.id,
index: latestCard ? latestCard.index + 1 : 0
});
+
+ if (newCard.insertId && input.memberPublicIds.length) {
+ const members = await tx.query.workspaceMembers.findMany({
+ where: inArray(workspaceMembers.publicId, input.memberPublicIds),
+ });
+
+ if (!members.length) return;
+
+ const membersInsert = members.map((member) => ({ cardId: Number(newCard.insertId), workspaceMemberId: member.id}))
+
+ await tx.insert(cardToWorkspaceMembers).values(membersInsert);
+ }
+
+ return newCard;
})
}),
addOrRemoveLabel: publicProcedure