Skip to content

Commit a0f92db

Browse files
committed
Contact us form uses original Feedback component to prevent broken links
1 parent 7a3f948 commit a0f92db

File tree

2 files changed

+90
-250
lines changed

2 files changed

+90
-250
lines changed
Lines changed: 82 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
import { conform, useForm } from "@conform-to/react";
22
import { parse } from "@conform-to/zod";
3-
import { BookOpenIcon } from "@heroicons/react/20/solid";
4-
import {
5-
CalendarDaysIcon,
6-
ChevronRightIcon,
7-
EnvelopeIcon,
8-
LifebuoyIcon,
9-
LightBulbIcon,
10-
} from "@heroicons/react/24/solid";
3+
import { EnvelopeIcon, LightBulbIcon } from "@heroicons/react/24/solid";
114
import { Form, useActionData, useLocation, useNavigation } from "@remix-run/react";
12-
import { DiscordIcon } from "@trigger.dev/companyicons";
13-
import { ActivityIcon } from "lucide-react";
145
import { type ReactNode, useState } from "react";
156
import { type FeedbackType, feedbackTypeLabel, schema } from "~/routes/resources.feedback";
16-
import { cn } from "~/utils/cn";
17-
import { docsTroubleshootingPath } from "~/utils/pathBuilder";
18-
import { Button, LinkButton } from "./primitives/Buttons";
7+
import { Button } from "./primitives/Buttons";
8+
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from "./primitives/Dialog";
199
import { Fieldset } from "./primitives/Fieldset";
2010
import { FormButtons } from "./primitives/FormButtons";
2111
import { FormError } from "./primitives/FormError";
22-
import { Header1 } from "./primitives/Headers";
12+
import { Icon } from "./primitives/Icon";
13+
import { InfoPanel } from "./primitives/InfoPanel";
2314
import { InputGroup } from "./primitives/InputGroup";
2415
import { Label } from "./primitives/Label";
2516
import { Paragraph } from "./primitives/Paragraph";
2617
import { Select, SelectItem } from "./primitives/Select";
27-
import { Sheet, SheetBody, SheetContent, SheetTrigger } from "./primitives/Sheet";
2818
import { TextArea } from "./primitives/TextArea";
2919

3020
type FeedbackProps = {
@@ -37,6 +27,7 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
3727
const location = useLocation();
3828
const lastSubmission = useActionData();
3929
const navigation = useNavigation();
30+
const [type, setType] = useState<FeedbackType>(defaultValue);
4031

4132
const [form, { path, feedbackType, message }] = useForm({
4233
id: "accept-invite",
@@ -57,141 +48,84 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
5748
}
5849

5950
return (
60-
<Sheet open={open} onOpenChange={setOpen}>
61-
<SheetTrigger asChild={true}>{button}</SheetTrigger>
62-
<SheetContent className="@container">
63-
<SheetBody className="flex h-full flex-col justify-between">
64-
<LinkBanner
65-
title="Join our Discord community"
66-
icon={<DiscordIcon className="size-9" />}
67-
to="https://trigger.dev/discord"
68-
className="hover:border-text-link"
69-
>
70-
<Paragraph>The quickest way to get answers from the Trigger.dev community.</Paragraph>
71-
</LinkBanner>
72-
<LinkBanner
73-
title="Book a 15 min chat with the founders"
74-
icon={<CalendarDaysIcon className="size-9 text-green-500" />}
75-
to="https://cal.com/team/triggerdotdev/founders-call"
76-
className="hover:border-green-500"
77-
>
78-
<Paragraph>Have a question or want to chat? Book a time to talk with us.</Paragraph>
79-
</LinkBanner>
80-
<LinkBanner
81-
title="Suggest a feature"
82-
icon={<LightBulbIcon className="size-9 text-sun-500" />}
83-
to="https://feedback.trigger.dev/"
84-
className="hover:border-sun-400"
85-
>
86-
<Paragraph>Have an idea for a new feature or improvement? Let us know!</Paragraph>
87-
</LinkBanner>
88-
<LinkBanner
89-
title="Troubleshooting"
90-
icon={<LifebuoyIcon className="size-9 text-rose-500" />}
91-
>
92-
<Paragraph>
93-
If you're having trouble, check out our troubleshooting guide or the Trigger.dev
94-
Status page.
51+
<Dialog>
52+
<DialogTrigger asChild>{button}</DialogTrigger>
53+
<DialogContent>
54+
<DialogHeader>Contact us</DialogHeader>
55+
<div className="mt-2 flex flex-col gap-4">
56+
<div className="flex items-center gap-4">
57+
<Icon icon={EnvelopeIcon} className="size-10 min-w-[2.5rem] text-blue-500" />
58+
<Paragraph variant="base/bright">
59+
How can we help? We read every message and will respond as quickly as we can.
9560
</Paragraph>
96-
<div className="flex flex-wrap gap-2">
97-
<LinkButton
98-
to={docsTroubleshootingPath("")}
99-
variant="tertiary/medium"
100-
LeadingIcon={BookOpenIcon}
101-
>
102-
Troubleshooting Docs
103-
</LinkButton>
104-
<LinkButton
105-
to={"https://status.trigger.dev/"}
106-
variant="tertiary/medium"
107-
LeadingIcon={ActivityIcon}
108-
>
109-
Trigger.dev Status
110-
</LinkButton>
111-
</div>
112-
</LinkBanner>
113-
<LinkBanner
114-
title="Send us an email"
115-
icon={<EnvelopeIcon className="size-9 text-blue-500" />}
116-
>
117-
<Paragraph>We read every message and respond quickly.</Paragraph>
118-
<Form method="post" action="/resources/feedback" {...form.props} className="w-full">
119-
<Fieldset className="max-w-full gap-y-3">
120-
<input value={location.pathname} {...conform.input(path, { type: "hidden" })} />
121-
<InputGroup className="max-w-full">
122-
<Select
123-
{...conform.select(feedbackType)}
124-
variant="tertiary/medium"
125-
defaultValue={defaultValue}
126-
placeholder="Select type"
127-
text={(value) => feedbackTypeLabel[value]}
128-
dropdownIcon
61+
</div>
62+
<hr className="border-charcoal-800" />
63+
<Form method="post" action="/resources/feedback" {...form.props} className="w-full">
64+
<Fieldset className="max-w-full gap-y-3">
65+
<input value={location.pathname} {...conform.input(path, { type: "hidden" })} />
66+
<InputGroup className="max-w-full">
67+
{type === "feature" && (
68+
<InfoPanel
69+
icon={LightBulbIcon}
70+
title="Did you know?"
71+
panelClassName="w-full inline-flex mb-2"
72+
to="https://feedback.trigger.dev"
73+
buttonLabel="Submit feature request"
12974
>
130-
{Object.entries(feedbackTypeLabel).map(([name, title]) => (
131-
<SelectItem key={name} value={name}>
132-
{title}
133-
</SelectItem>
134-
))}
135-
</Select>
136-
<FormError id={feedbackType.errorId}>{feedbackType.error}</FormError>
137-
</InputGroup>
138-
<InputGroup className="max-w-full">
139-
<Label>Message</Label>
140-
<TextArea {...conform.textarea(message)} />
141-
<FormError id={message.errorId}>{message.error}</FormError>
142-
</InputGroup>
143-
<FormError>{form.error}</FormError>
144-
<div className="flex w-full justify-end">
145-
<FormButtons
146-
className="m-0 w-max"
147-
confirmButton={
148-
<Button type="submit" variant="tertiary/medium">
149-
Send message
150-
</Button>
151-
}
152-
/>
153-
</div>
154-
</Fieldset>
155-
</Form>
156-
</LinkBanner>
157-
</SheetBody>
158-
</SheetContent>
159-
</Sheet>
160-
);
161-
}
162-
163-
function LinkBanner({
164-
className,
165-
icon,
166-
title,
167-
children,
168-
to,
169-
}: {
170-
className?: string;
171-
icon?: ReactNode;
172-
title?: string;
173-
children?: ReactNode;
174-
to?: string;
175-
}) {
176-
return (
177-
<a
178-
href={to}
179-
target="_blank"
180-
className={cn(
181-
"group/banner mb-4 flex w-full items-center justify-between rounded-md border border-grid-bright bg-charcoal-750 p-4 transition",
182-
className
183-
)}
184-
>
185-
<div className="flex w-full items-start gap-4">
186-
<span>{icon}</span>
187-
<div className="flex w-full flex-col gap-2">
188-
<Header1 className="text-2xl font-semibold text-text-bright">{title}</Header1>
189-
{children}
75+
All our feature requests are public and voted on by the community. The best way
76+
to submit your feature request is to post it to our feedback forum.
77+
</InfoPanel>
78+
)}
79+
{type === "help" && (
80+
<InfoPanel
81+
icon={LightBulbIcon}
82+
title="Did you know?"
83+
panelClassName="w-full inline-flex mb-2"
84+
to="https://trigger.dev/discord"
85+
buttonLabel="Join our Discord"
86+
>
87+
Discord is the quickest way to get answers from the Trigger.dev team and
88+
community.
89+
</InfoPanel>
90+
)}
91+
<Select
92+
{...conform.select(feedbackType)}
93+
variant="tertiary/medium"
94+
value={type}
95+
defaultValue={type}
96+
setValue={(v) => setType(v as FeedbackType)}
97+
placeholder="Select type"
98+
text={(value) => feedbackTypeLabel[value as FeedbackType]}
99+
dropdownIcon
100+
>
101+
{Object.entries(feedbackTypeLabel).map(([name, title]) => (
102+
<SelectItem key={name} value={name}>
103+
{title}
104+
</SelectItem>
105+
))}
106+
</Select>
107+
<FormError id={feedbackType.errorId}>{feedbackType.error}</FormError>
108+
</InputGroup>
109+
<InputGroup className="max-w-full">
110+
<Label>Message</Label>
111+
<TextArea {...conform.textarea(message)} />
112+
<FormError id={message.errorId}>{message.error}</FormError>
113+
</InputGroup>
114+
<FormError>{form.error}</FormError>
115+
<div className="flex w-full justify-end">
116+
<FormButtons
117+
className="m-0 w-max"
118+
confirmButton={
119+
<Button type="submit" variant="tertiary/medium">
120+
Send message
121+
</Button>
122+
}
123+
/>
124+
</div>
125+
</Fieldset>
126+
</Form>
190127
</div>
191-
</div>
192-
{to && (
193-
<ChevronRightIcon className="size-5 text-charcoal-500 transition group-hover:translate-x-1 group-hover/banner:text-text-bright" />
194-
)}
195-
</a>
128+
</DialogContent>
129+
</Dialog>
196130
);
197131
}

0 commit comments

Comments
 (0)