From 3cf0039c58c8a2d7226ec41c984171a395d3d067 Mon Sep 17 00:00:00 2001 From: MananTank Date: Wed, 23 Oct 2024 20:01:35 +0000 Subject: [PATCH] Move support ticket creation to /support/create-ticket page (#5144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem solved Short description of the bug fixed or feature added --- ## PR-Codex overview This PR focuses on restructuring the support ticket creation process in the dashboard application. It removes the old `CreateTicket` component and replaces it with a new implementation, enhancing user navigation and support form functionality. ### Detailed summary - Deleted `create-ticket.client.tsx`. - Updated `SupportPage` to replace `` with a button linking to `/support/create-ticket`. - Created a new `Page` component for the support ticket creation, including authentication check and breadcrumb navigation. - Introduced a new `CreateTicket` component with dynamic support form imports and form handling. - Added form reset and submission handling in `CreateTicket`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- apps/dashboard/src/@/constants/auth.ts | 1 - .../components/create-ticket.client.tsx | 187 ------------------ .../components/create-ticket.action.ts | 0 .../components/create-ticket.client.tsx | 152 ++++++++++++++ .../support/create-ticket/page.tsx | 43 ++++ .../src/app/(dashboard)/support/page.tsx | 5 +- 6 files changed, 198 insertions(+), 190 deletions(-) delete mode 100644 apps/dashboard/src/app/(dashboard)/support/components/create-ticket.client.tsx rename apps/dashboard/src/app/(dashboard)/support/{ => create-ticket}/components/create-ticket.action.ts (100%) create mode 100644 apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.client.tsx create mode 100644 apps/dashboard/src/app/(dashboard)/support/create-ticket/page.tsx diff --git a/apps/dashboard/src/@/constants/auth.ts b/apps/dashboard/src/@/constants/auth.ts index 73e67e3974f..fa16695bf8c 100644 --- a/apps/dashboard/src/@/constants/auth.ts +++ b/apps/dashboard/src/@/constants/auth.ts @@ -5,7 +5,6 @@ const LOGGED_IN_ONLY_PATHS = [ "/team", // anything that _starts_ with /cli is logged in only "/cli", - "/support", // publish page "/contracts/publish", ]; diff --git a/apps/dashboard/src/app/(dashboard)/support/components/create-ticket.client.tsx b/apps/dashboard/src/app/(dashboard)/support/components/create-ticket.client.tsx deleted file mode 100644 index 33c665c95b7..00000000000 --- a/apps/dashboard/src/app/(dashboard)/support/components/create-ticket.client.tsx +++ /dev/null @@ -1,187 +0,0 @@ -"use client"; - -import { Spinner } from "@/components/ui/Spinner/Spinner"; -import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser"; -import { SupportForm_SelectInput } from "components/help/contact-forms/shared/SupportForm_SelectInput"; -import dynamic from "next/dynamic"; -import Link from "next/link"; -import { type ReactElement, useEffect, useRef, useState } from "react"; -import { useFormState, useFormStatus } from "react-dom"; -import { toast } from "sonner"; -import { createTicketAction } from "./create-ticket.action"; - -const ConnectSupportForm = dynamic( - () => import("../../../../components/help/contact-forms/connect"), - { - ssr: false, - }, -); -const EngineSupportForm = dynamic( - () => import("../../../../components/help/contact-forms/engine"), - { - ssr: false, - }, -); -const ContractSupportForm = dynamic( - () => import("../../../../components/help/contact-forms/contracts"), - { - ssr: false, - }, -); -const AccountSupportForm = dynamic( - () => import("../../../../components/help/contact-forms/account"), - { - ssr: false, - }, -); -const OtherSupportForm = dynamic( - () => import("../../../../components/help/contact-forms/other"), - { - ssr: false, - }, -); - -const productOptions: { label: string; component: ReactElement }[] = [ - { - label: "Connect", - component: , - }, - { - label: "Engine", - component: , - }, - { - label: "Contracts", - component: , - }, - { - label: "Account", - component: , - }, - { - label: "Other", - component: , - }, -]; - -export function CreateTicket() { - const formRef = useRef(null); - const [productLabel, setProductLabel] = useState(""); - const [isOpen, setIsOpen] = useState(false); - - const [state, formAction] = useFormState(createTicketAction, { - message: "", - success: false, - }); - const { user } = useLoggedInUser(); - // needed here - // eslint-disable-next-line no-restricted-syntax - useEffect(() => { - if (!state.message) { - return; - } - if (state.success) { - toast.success(state.message); - setIsOpen(false); - } else { - toast.error(state.message); - } - }, [state.success, state.message]); - - return ( - { - setIsOpen(open); - if (!open) { - formRef.current?.reset(); - setProductLabel(""); - } - }} - > - - - - - {/* Check this */} - -
- - Get in touch - - We are here to help. Ask product questions, report problems, or - leave feedback. - - - - {/* render the form */} - {user?.jwt ? ( - <> -
- o.label)} - promptText="Select a product" - onValueChange={setProductLabel} - value={productLabel} - required={true} - /> - { - productOptions.find((o) => o.label === productLabel) - ?.component - } -
- - - - - - - ) : ( -
- -

- Please sign in to create a ticket -

-
- )} -
-
-
- ); -} - -function SubmitButton() { - const { pending } = useFormStatus(); - return ( - - ); -} diff --git a/apps/dashboard/src/app/(dashboard)/support/components/create-ticket.action.ts b/apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.action.ts similarity index 100% rename from apps/dashboard/src/app/(dashboard)/support/components/create-ticket.action.ts rename to apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.action.ts diff --git a/apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.client.tsx b/apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.client.tsx new file mode 100644 index 00000000000..c54c3411f84 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/support/create-ticket/components/create-ticket.client.tsx @@ -0,0 +1,152 @@ +"use client"; + +import { Spinner } from "@/components/ui/Spinner/Spinner"; +import { Button } from "@/components/ui/button"; +import { Skeleton } from "@/components/ui/skeleton"; +import { SupportForm_SelectInput } from "components/help/contact-forms/shared/SupportForm_SelectInput"; +import dynamic from "next/dynamic"; +import { type ReactElement, useEffect, useRef, useState } from "react"; +import { useFormState, useFormStatus } from "react-dom"; +import { toast } from "sonner"; +import { createTicketAction } from "./create-ticket.action"; + +const ConnectSupportForm = dynamic( + () => import("../../../../../components/help/contact-forms/connect"), + { + ssr: false, + loading: () => , + }, +); +const EngineSupportForm = dynamic( + () => import("../../../../../components/help/contact-forms/engine"), + { + ssr: false, + loading: () => , + }, +); +const ContractSupportForm = dynamic( + () => import("../../../../../components/help/contact-forms/contracts"), + { + ssr: false, + loading: () => , + }, +); +const AccountSupportForm = dynamic( + () => import("../../../../../components/help/contact-forms/account"), + { + ssr: false, + loading: () => , + }, +); +const OtherSupportForm = dynamic( + () => import("../../../../../components/help/contact-forms/other"), + { + ssr: false, + loading: () => , + }, +); + +const productOptions: { label: string; component: ReactElement }[] = [ + { + label: "Connect", + component: , + }, + { + label: "Engine", + component: , + }, + { + label: "Contracts", + component: , + }, + { + label: "Account", + component: , + }, + { + label: "Other", + component: , + }, +]; + +export function CreateTicket() { + const formRef = useRef(null); + const [productLabel, setProductLabel] = useState(""); + + const [state, formAction] = useFormState(createTicketAction, { + message: "", + success: false, + }); + // needed here + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if (!state.message) { + return; + } + if (state.success) { + toast.success(state.message); + } else { + toast.error(state.message); + } + }, [state.success, state.message]); + + return ( +
+
+

Get Support

+

+ We are here to help. Ask product questions, report problems, or leave + feedback. +

+ +
+ +
+ o.label)} + promptText="Select a product" + onValueChange={setProductLabel} + value={productLabel} + required={true} + /> + {productOptions.find((o) => o.label === productLabel)?.component} +
+
+ +
+ +
+ + +
+ + ); +} + +function SubmitButton() { + const { pending } = useFormStatus(); + return ( + + ); +} diff --git a/apps/dashboard/src/app/(dashboard)/support/create-ticket/page.tsx b/apps/dashboard/src/app/(dashboard)/support/create-ticket/page.tsx new file mode 100644 index 00000000000..332331a7e1b --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/support/create-ticket/page.tsx @@ -0,0 +1,43 @@ +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { getAuthToken } from "../../../api/lib/getAuthToken"; +import { CreateTicket } from "./components/create-ticket.client"; + +export default function Page() { + const authToken = getAuthToken(); + + if (!authToken) { + return redirect( + `/login?next=${encodeURIComponent("/support/create-ticket")}`, + ); + } + + return ( +
+ + + + + Support + + + + + Get Support + + + +
+ +
+
+ ); +} diff --git a/apps/dashboard/src/app/(dashboard)/support/page.tsx b/apps/dashboard/src/app/(dashboard)/support/page.tsx index bb63a44746e..f70e090c7ac 100644 --- a/apps/dashboard/src/app/(dashboard)/support/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/support/page.tsx @@ -17,7 +17,6 @@ import discordIllustration from "../../../../public/assets/support/discord-illus import engineIcon from "../../../../public/assets/support/engine.png"; import miscIcon from "../../../../public/assets/support/misc.svg"; import connectIcon from "../../../../public/assets/support/wallets.png"; -import { CreateTicket } from "./components/create-ticket.client"; export const metadata: Metadata = { title: "thirdweb Support", @@ -139,7 +138,9 @@ export default function SupportPage() { Our dedicated support team is here to help you with any questions or issues you may have. Contact us today and let us assist you.

- +