From 5720168adfa80ea166adab6a65be683a03f611f7 Mon Sep 17 00:00:00 2001 From: Lewis Carhart Date: Mon, 31 Mar 2025 19:16:57 -0400 Subject: [PATCH 1/2] Add AssistantButton component and integrate into Header - Introduced the `AssistantButton` component for AI interaction, utilizing responsive design with media queries. - Integrated `AssistantButton` into the `Header` component, enhancing the user interface. - Refactored the `Header` component for improved readability and structure. - Maintained existing functionality while optimizing layout and component usage. --- apps/app/src/components/ai/chat-button.tsx | 32 +++++++++ apps/app/src/components/header.tsx | 82 +++++++++++----------- 2 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 apps/app/src/components/ai/chat-button.tsx diff --git a/apps/app/src/components/ai/chat-button.tsx b/apps/app/src/components/ai/chat-button.tsx new file mode 100644 index 0000000000..6828049e1f --- /dev/null +++ b/apps/app/src/components/ai/chat-button.tsx @@ -0,0 +1,32 @@ +"use client"; + +import { Button } from "@bubba/ui/button"; +import { useMediaQuery } from "@bubba/ui/hooks" +import { useQueryState } from "nuqs"; + + +export function AssistantButton() { + const isDesktop = useMediaQuery("(min-width: 768px)"); + const [, setAssistantOpen] = useQueryState("assistant", { + history: "push", + parse: (value) => value === "true", + serialize: (value) => value.toString(), + }); + + if (!isDesktop) { + return null; + } + + return ( + + ); +} diff --git a/apps/app/src/components/header.tsx b/apps/app/src/components/header.tsx index 58a3c844f6..83536b4694 100644 --- a/apps/app/src/components/header.tsx +++ b/apps/app/src/components/header.tsx @@ -7,53 +7,55 @@ import Link from "next/link"; import { Suspense } from "react"; import { FeedbackForm } from "./feedback-form"; import { MobileMenu } from "./mobile-menu"; -import { NotificationCenter } from "./notification-center"; + import { auth } from "@/auth"; import { redirect } from "next/navigation"; +import { AssistantButton } from "./ai/chat-button"; export async function Header() { - const t = await getI18n(); - const session = await auth(); - const user = session?.user; - const currentOrganizationId = user?.organizationId; - const hasAccess = user?.isAdmin; + const t = await getI18n(); + const session = await auth(); + const user = session?.user; + const currentOrganizationId = user?.organizationId; + const hasAccess = user?.isAdmin; - if (!currentOrganizationId) { - redirect("/"); - } + if (!currentOrganizationId) { + redirect("/"); + } - return ( -
- + return ( +
+ + -
-
- - -
+
+
+ + +
- {/* */} + {/* */} - }> - - -
-
- ); + }> + + + +
+ ); } From c853c12db7d33c4315c80ca32a7acfe36678ae98 Mon Sep 17 00:00:00 2001 From: Lewis Carhart Date: Mon, 31 Mar 2025 19:27:17 -0400 Subject: [PATCH 2/2] Enhance delete organization action and layout adjustments - Added revalidation of the organization path after successful deletion in the `deleteOrganizationAction`. - Updated layout styles in the dashboard for improved spacing and responsiveness. - Refactored `Header` component to maintain structure and readability. - Adjusted `SidebarLogo` component to ensure consistent styling and added width/height attributes for the logo. --- .../delete-organization-action.ts | 79 ++++++++++--------- .../(app)/(dashboard)/[orgId]/layout.tsx | 2 +- apps/app/src/components/header.tsx | 1 + apps/app/src/components/sidebar-logo.tsx | 38 ++++----- 4 files changed, 62 insertions(+), 58 deletions(-) diff --git a/apps/app/src/actions/organization/delete-organization-action.ts b/apps/app/src/actions/organization/delete-organization-action.ts index 57915fd4c2..0ed9659e8d 100644 --- a/apps/app/src/actions/organization/delete-organization-action.ts +++ b/apps/app/src/actions/organization/delete-organization-action.ts @@ -5,46 +5,49 @@ import { db } from "@bubba/db"; import { authActionClient } from "../safe-action"; import { deleteOrganizationSchema } from "../schema"; +import { revalidatePath, revalidateTag } from "next/cache"; type DeleteOrganizationResult = { - success: boolean; - redirect?: string; + success: boolean; + redirect?: string; }; export const deleteOrganizationAction = authActionClient - .schema(deleteOrganizationSchema) - .metadata({ - name: "delete-organization", - track: { - event: "delete-organization", - channel: "server", - }, - }) - .action(async ({ parsedInput, ctx }): Promise => { - const { id } = parsedInput; - const { user } = ctx; - - if (!id) { - throw new Error("Invalid user input"); - } - - if (!user.organizationId) { - throw new Error("Invalid organization input"); - } - - try { - await db.$transaction(async () => { - await db.organization.delete({ - where: { id: user.organizationId }, - }); - }); - - return { - success: true, - }; - } catch (error) { - return { - success: false, - }; - } - }); + .schema(deleteOrganizationSchema) + .metadata({ + name: "delete-organization", + track: { + event: "delete-organization", + channel: "server", + }, + }) + .action(async ({ parsedInput, ctx }): Promise => { + const { id } = parsedInput; + const { user } = ctx; + + if (!id) { + throw new Error("Invalid user input"); + } + + if (!user.organizationId) { + throw new Error("Invalid organization input"); + } + + try { + await db.$transaction(async () => { + await db.organization.delete({ + where: { id: user.organizationId }, + }); + }); + + revalidatePath(`/${user.organizationId}`); + + return { + success: true, + }; + } catch (error) { + return { + success: false, + }; + } + }); diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx index cca311b4f3..5d35fb3b16 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx @@ -40,7 +40,7 @@ export default async function Layout({ } isCollapsed={isCollapsed}> -
+
{children}
diff --git a/apps/app/src/components/header.tsx b/apps/app/src/components/header.tsx index 83536b4694..06f2feb368 100644 --- a/apps/app/src/components/header.tsx +++ b/apps/app/src/components/header.tsx @@ -29,6 +29,7 @@ export async function Header() { organizationId={currentOrganizationId} isAdmin={hasAccess ?? false} /> +
diff --git a/apps/app/src/components/sidebar-logo.tsx b/apps/app/src/components/sidebar-logo.tsx index b33b7f8a51..64ceeedc7d 100644 --- a/apps/app/src/components/sidebar-logo.tsx +++ b/apps/app/src/components/sidebar-logo.tsx @@ -5,26 +5,26 @@ import { cn } from "@bubba/ui/cn"; import Link from "next/link"; interface SidebarLogoProps { - isCollapsed: boolean; - organizationId: string; + isCollapsed: boolean; + organizationId: string; } export function SidebarLogo({ isCollapsed, organizationId }: SidebarLogoProps) { - return ( -
- - - -
- ); + return ( +
+ + + +
+ ); }