diff --git a/src/app/boards/[...boardId]/page.tsx b/src/app/boards/[...boardId]/page.tsx
index 0740ba22..f27d7a1a 100644
--- a/src/app/boards/[...boardId]/page.tsx
+++ b/src/app/boards/[...boardId]/page.tsx
@@ -22,6 +22,7 @@ import BoardDropdown from "./components/BoardDropdown";
import { DeleteBoardConfirmation } from "./components/DeleteBoardConfirmation";
import { DeleteListConfirmation } from "./components/DeleteListConfirmation";
import List from "./components/List";
+import { NewWorkspaceForm } from "~/app/components/NewWorkspaceForm";
import { NewCardForm } from "./components/NewCardForm";
import { NewListForm } from "./components/NewListForm";
@@ -304,6 +305,7 @@ export default function BoardPage() {
{modalContentType === "NEW_LIST" && (
)}
+ {modalContentType === "NEW_WORKSPACE" && }
);
diff --git a/src/app/boards/page.tsx b/src/app/boards/page.tsx
index 5469e7d0..0e213796 100644
--- a/src/app/boards/page.tsx
+++ b/src/app/boards/page.tsx
@@ -8,6 +8,7 @@ import Modal from "~/app/components/modal";
import { ImportBoardsForm } from "./components/ImportBoardsForm";
import { NewBoardForm } from "./components/NewBoardForm";
+import { NewWorkspaceForm } from "~/app/components/NewWorkspaceForm";
export default function BoardsPage() {
const { openModal, modalContentType } = useModal();
@@ -48,6 +49,7 @@ export default function BoardsPage() {
{modalContentType === "NEW_BOARD" && }
{modalContentType === "IMPORT_BOARDS" && }
+ {modalContentType === "NEW_WORKSPACE" && }
diff --git a/src/app/cards/[cardId]/page.tsx b/src/app/cards/[cardId]/page.tsx
index 7d0b2205..4ad64b3e 100644
--- a/src/app/cards/[cardId]/page.tsx
+++ b/src/app/cards/[cardId]/page.tsx
@@ -12,6 +12,7 @@ import LabelSelector from "./components/LabelSelector";
import ListSelector from "./components/ListSelector";
import MemberSelector from "./components/MemberSelector";
import { NewLabelForm } from "./components/NewLabelForm";
+import { NewWorkspaceForm } from "~/app/components/NewWorkspaceForm";
import Modal from "~/app/components/modal";
import { useModal } from "~/app/providers/modal";
@@ -162,6 +163,7 @@ export default function CardPage() {
cardPublicId={cardId}
/>
)}
+ {modalContentType === "NEW_WORKSPACE" && }
);
diff --git a/src/app/components/NewWorkspaceForm.tsx b/src/app/components/NewWorkspaceForm.tsx
new file mode 100644
index 00000000..ac30a108
--- /dev/null
+++ b/src/app/components/NewWorkspaceForm.tsx
@@ -0,0 +1,79 @@
+"use client";
+
+import { api } from "~/trpc/react";
+
+import { HiXMark } from "react-icons/hi2";
+
+import { useModal } from "~/app/providers/modal";
+import { useWorkspace } from "~/app/providers/workspace";
+
+import { Formik, Form, Field } from "formik";
+
+interface FormValues {
+ name: string;
+}
+
+export function NewWorkspaceForm() {
+ const { closeModal } = useModal();
+ const { switchWorkspace } = useWorkspace();
+
+ const createWorkspace = api.workspace.create.useMutation({
+ onSuccess: (values) => {
+ try {
+ if (values?.publicId) {
+ switchWorkspace({ publicId: values.publicId, name: values.name });
+ closeModal();
+ }
+ } catch (e) {
+ console.log(e);
+ }
+ },
+ });
+
+ return (
+ <>
+
+
New workspace
+
+
+
+ {
+ createWorkspace.mutate({
+ name: values.name,
+ });
+ }}
+ >
+
+
+ >
+ );
+}
diff --git a/src/app/components/SideNavigation.tsx b/src/app/components/SideNavigation.tsx
index 994d00bf..ed3b77dd 100644
--- a/src/app/components/SideNavigation.tsx
+++ b/src/app/components/SideNavigation.tsx
@@ -33,23 +33,28 @@ export default function SideNavigation({ user }: SideNavigationProps) {
];
return (
-
+ <>
+
+ >
);
}
diff --git a/src/app/components/WorkspaceMenu.tsx b/src/app/components/WorkspaceMenu.tsx
index 64f391a8..23c6f8bc 100644
--- a/src/app/components/WorkspaceMenu.tsx
+++ b/src/app/components/WorkspaceMenu.tsx
@@ -3,10 +3,14 @@
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
+import { useModal } from "~/app/providers/modal";
import { useWorkspace } from "~/app/providers/workspace";
-export default function UserMenu() {
+import { HiCheck } from "react-icons/hi2";
+
+export default function WorkspaceMenu() {
const { workspace, availableWorkspaces, switchWorkspace } = useWorkspace();
+ const { openModal } = useModal();
return (
diff --git a/src/app/members/page.tsx b/src/app/members/page.tsx
index 8d127cd9..e1dc5ab3 100644
--- a/src/app/members/page.tsx
+++ b/src/app/members/page.tsx
@@ -7,6 +7,7 @@ import Modal from "~/app/components/modal";
import { ImportBoardsForm } from "~/app/boards/components/ImportBoardsForm";
import { NewBoardForm } from "~/app/boards/components/NewBoardForm";
+import { NewWorkspaceForm } from "~/app/components/NewWorkspaceForm";
import MemberDropdown from "./components/MemberDropdown";
@@ -85,6 +86,7 @@ export default function MembersPage() {
{modalContentType === "NEW_BOARD" && }
{modalContentType === "IMPORT_BOARDS" && }
+ {modalContentType === "NEW_WORKSPACE" && }
);
diff --git a/src/app/providers/workspace.tsx b/src/app/providers/workspace.tsx
index fe50b5cb..5fc9f1f8 100644
--- a/src/app/providers/workspace.tsx
+++ b/src/app/providers/workspace.tsx
@@ -45,8 +45,6 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
const { data } = api.workspace.all.useQuery();
- console.log({ data });
-
const switchWorkspace = (_workspace: Workspace) => {
localStorage.setItem("workspacePublicId", _workspace.publicId);
diff --git a/src/server/api/routers/board.ts b/src/server/api/routers/board.ts
index 8a1b2a47..849a7a3d 100644
--- a/src/server/api/routers/board.ts
+++ b/src/server/api/routers/board.ts
@@ -122,8 +122,6 @@ export const boardRouter = createTRPCRouter({
where: eq(workspaces.publicId, input.workspacePublicId),
})
- console.log({ workspace })
-
if (!workspace) return;
return ctx.db.insert(boards).values({
diff --git a/src/server/api/routers/card.ts b/src/server/api/routers/card.ts
index 0022d905..29c148f3 100644
--- a/src/server/api/routers/card.ts
+++ b/src/server/api/routers/card.ts
@@ -109,8 +109,6 @@ export const cardRouter = createTRPCRouter({
if (!card || !member) return;
- console.log({ member })
-
const memberExists = await tx.query.cardToWorkspaceMembers.findFirst({
where: and(eq(cardToWorkspaceMembers.cardId, card.id), eq(cardToWorkspaceMembers.workspaceMemberId, member.id)),
});
diff --git a/src/server/api/routers/workspace.ts b/src/server/api/routers/workspace.ts
index 05289730..75b8a84f 100644
--- a/src/server/api/routers/workspace.ts
+++ b/src/server/api/routers/workspace.ts
@@ -3,6 +3,8 @@ import { and, eq, isNull } from "drizzle-orm";
import { workspaces, workspaceMembers } from "~/server/db/schema";
+import { generateUID } from "~/utils/generateUID";
+
import {
createTRPCRouter,
publicProcedure,
@@ -61,4 +63,38 @@ export const workspaceRouter = createTRPCRouter({
}
});
}),
+ create: publicProcedure
+ .input(
+ z.object({
+ name: z.string().min(1),
+ }),
+ )
+ .mutation(async ({ ctx, input }) => {
+ const userId = ctx.session?.user.id;
+
+ if (!userId) return;
+
+ const workspace = await ctx.db.insert(workspaces).values({
+ publicId: generateUID(),
+ name: input.name,
+ slug: input.name.toLowerCase(),
+ createdBy: userId,
+ });
+
+ await ctx.db.insert(workspaceMembers).values({
+ publicId: generateUID(),
+ userId,
+ workspaceId: Number(workspace.insertId),
+ createdBy: userId,
+ role: 'admin'
+ })
+
+ return ctx.db.query.workspaces.findFirst({
+ where: eq(workspaces.id, Number(workspace.insertId)),
+ columns: {
+ publicId: true,
+ name: true,
+ },
+ });
+ }),
});
\ No newline at end of file