diff --git a/apps/webapp/app/components/Feedback.tsx b/apps/webapp/app/components/Feedback.tsx index a0dcce42e..b42067586 100644 --- a/apps/webapp/app/components/Feedback.tsx +++ b/apps/webapp/app/components/Feedback.tsx @@ -8,7 +8,7 @@ import { useNavigation, } from "@remix-run/react"; import { useState } from "react"; -import { schema } from "~/routes/resources.feedback"; +import { feedbackTypeLabel, schema } from "~/routes/resources.feedback"; import { Button } from "./primitives/Buttons"; import { Fieldset } from "./primitives/Fieldset"; import { FormButtons } from "./primitives/FormButtons"; @@ -67,7 +67,7 @@ export function Feedback() { Send us feedback - + Give us feedback @@ -82,14 +82,16 @@ export function Feedback() { - - Bug report - Feature request - Help me out + {Object.entries(feedbackTypeLabel).map(([key, value]) => ( + + {value} + + ))} @@ -104,6 +106,7 @@ export function Feedback() { {form.error} Send diff --git a/apps/webapp/app/components/primitives/FormButtons.tsx b/apps/webapp/app/components/primitives/FormButtons.tsx index 2745e6395..9175290e4 100644 --- a/apps/webapp/app/components/primitives/FormButtons.tsx +++ b/apps/webapp/app/components/primitives/FormButtons.tsx @@ -1,12 +1,16 @@ +import { cn } from "~/utils/cn"; + export function FormButtons({ cancelButton, confirmButton, + className, }: { cancelButton?: React.ReactNode; confirmButton: React.ReactNode; + className?: string; }) { return ( -
+
{cancelButton ? cancelButton :
} {confirmButton}
); diff --git a/apps/webapp/app/routes/resources.feedback.ts b/apps/webapp/app/routes/resources.feedback.ts index 255b6cf14..7125ac982 100644 --- a/apps/webapp/app/routes/resources.feedback.ts +++ b/apps/webapp/app/routes/resources.feedback.ts @@ -1,8 +1,13 @@ import { parse } from "@conform-to/zod"; import { ActionArgs, json } from "@remix-run/server-runtime"; -import { PlainClient } from "@team-plain/typescript-sdk"; +import { + ComponentDividerSpacingSize, + ComponentSpacerSize, + ComponentTextColor, + ComponentTextSize, + PlainClient, +} from "@team-plain/typescript-sdk"; import { inspect } from "util"; -import { s } from "vitest/dist/index-6e18a03a"; import { z } from "zod"; import { env } from "~/env.server"; import { redirectWithSuccessMessage } from "~/models/message.server"; @@ -10,20 +15,31 @@ import { requireUser } from "~/services/session.server"; let client: PlainClient | undefined; +export const feedbackTypeLabel = { + bug: "Bug report", + feature: "Feature request", + help: "Help me out", + integration: "Request an integration", +}; + +type FeedbackType = keyof typeof feedbackTypeLabel; + +const feedbackTypeLiterals = Object.keys(feedbackTypeLabel).map((key) => + z.literal(key) +); + const feedbackType = z.union( - [z.literal("bug"), z.literal("feature"), z.literal("help")], + [ + feedbackTypeLiterals[0], + feedbackTypeLiterals[1], + ...feedbackTypeLiterals.slice(2), + ], { required_error: "Must be either 'bug' or 'feature'", invalid_type_error: "Must be either 'bug' or 'feature'", } ); -const feedbackTypeLabel = { - bug: "Bug", - feature: "Feature request", - help: "Help", -}; - export const schema = z.object({ path: z.string(), feedbackType, @@ -77,10 +93,46 @@ export async function action({ request }: ActionArgs) { return json(submission); } + const title = + feedbackTypeLabel[submission.value.feedbackType as FeedbackType]; const upsertTimelineEntryRes = await client.upsertCustomTimelineEntry({ customerId: upsertCustomerRes.data.customer.id, - title: feedbackTypeLabel[submission.value.feedbackType], + title, components: [ + { + componentText: { + text: `New ${title} reported by ${user.name} (${user.email})`, + }, + }, + { + componentDivider: { + dividerSpacingSize: ComponentDividerSpacingSize.M, + }, + }, + { + componentText: { + textSize: ComponentTextSize.S, + textColor: ComponentTextColor.Muted, + text: "Page", + }, + }, + { + componentText: { + text: submission.value.path, + }, + }, + { + componentSpacer: { + spacerSize: ComponentSpacerSize.M, + }, + }, + { + componentText: { + textSize: ComponentTextSize.S, + textColor: ComponentTextColor.Muted, + text: "Message", + }, + }, { componentText: { text: submission.value.message, @@ -105,7 +157,7 @@ export async function action({ request }: ActionArgs) { return redirectWithSuccessMessage( submission.value.path, request, - "Feedback submitted" + "Thanks for your feedback! We'll get back to you soon." ); } catch (e) { return json(e, { status: 400 });