Skip to content

Commit 244988e

Browse files
authored
New Help & Feedback menu and tab-selected styles (#1374)
* Added a new dropdown help and feedback menu to the side menu * Added a shortcut to the popover menu * Removed dev cli connected button for now * Contact us form uses original Feedback component to prevent broken links * Improved the messaging when selecting different options in the email form * buttons style tweak * SideMenuItem supports the trailingIconClassName * Adding a consistent focus-visible states * Removing tooltips for now * Squashed commit of the following: commit 7d11123 Author: Eric Goldman <eric@sequin.io> Date: Mon Sep 30 17:54:06 2024 -0700 Add sequin guide (#1368) Co-authored-by: James Ritchie <james@trigger.dev> commit 8da495a Author: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Mon Sep 30 13:42:22 2024 +0100 Improve checkpoint reliability and cleanup of temp files (#1367) * improve cleanup reliability * improve logging * bye-bye execa * fix for trailing newlines * prettier errors * trim args and log output by default * fix archive cleanup * prevent potential memleak * more cleanup debug logs * ignore abort during cleanup * rename checkpoint dir env var and move to helper * add global never throw override * add tmp cleaner * also clean up checkpoint dir by default * split by any whitespace, not just tabs * only create tmp cleaner if paths to clean commit 69ec68e Author: Eric Allam <eallam@icloud.com> Date: Sun Sep 29 19:18:39 2024 -0700 Release 3.0.9 commit a6ea844 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun Sep 29 19:17:26 2024 -0700 chore: Update version for release (#1366) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> commit 4c1ee3d Author: Eric Allam <eallam@icloud.com> Date: Sun Sep 29 19:09:38 2024 -0700 fix: run metadata not working when using npx/pnpm dlx * More support for custom-focus * More custom focus styles added * Support for focus-visible style for the Segmented control * Fixed table triple dot menu z-index issue * Improved help menu wording * When you submit the help form, close the modal * focus-visible style for radio buttons * button prop is now optional in the SideMenu component * focus styling for a text link * Deleted unused sequin files
1 parent b1319fb commit 244988e

File tree

30 files changed

+451
-383
lines changed

30 files changed

+451
-383
lines changed
Lines changed: 100 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
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";
14-
import { type ReactNode, useState } from "react";
5+
import { type ReactNode, useState, useEffect } 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";
19+
import { InformationCircleIcon } from "@heroicons/react/20/solid";
20+
import { TextLink } from "./primitives/TextLink";
2921

3022
type FeedbackProps = {
3123
button: ReactNode;
@@ -37,161 +29,111 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
3729
const location = useLocation();
3830
const lastSubmission = useActionData();
3931
const navigation = useNavigation();
32+
const [type, setType] = useState<FeedbackType>(defaultValue);
4033

4134
const [form, { path, feedbackType, message }] = useForm({
4235
id: "accept-invite",
43-
// TODO: type this
4436
lastSubmission: lastSubmission as any,
4537
onValidate({ formData }) {
4638
return parse(formData, { schema });
4739
},
40+
shouldRevalidate: "onInput",
4841
});
4942

50-
if (
51-
open &&
52-
navigation.formAction === "/resources/feedback" &&
53-
form.error === undefined &&
54-
form.errors.length === 0
55-
) {
56-
setOpen(false);
57-
}
43+
useEffect(() => {
44+
if (
45+
navigation.formAction === "/resources/feedback" &&
46+
navigation.state === "loading" &&
47+
form.error === undefined &&
48+
form.errors.length === 0
49+
) {
50+
setOpen(false);
51+
}
52+
}, [navigation, form]);
5853

5954
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.
55+
<Dialog open={open} onOpenChange={setOpen}>
56+
<DialogTrigger asChild>{button}</DialogTrigger>
57+
<DialogContent>
58+
<DialogHeader>Contact us</DialogHeader>
59+
<div className="mt-2 flex flex-col gap-4">
60+
<div className="flex items-center gap-4">
61+
<Icon icon={EnvelopeIcon} className="size-10 min-w-[2.5rem] text-blue-500" />
62+
<Paragraph variant="base/bright">
63+
How can we help? We read every message and will respond as quickly as we can.
9564
</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
65+
</div>
66+
<hr className="border-charcoal-800" />
67+
<Form method="post" action="/resources/feedback" {...form.props} className="w-full">
68+
<Fieldset className="max-w-full gap-y-3">
69+
<input value={location.pathname} {...conform.input(path, { type: "hidden" })} />
70+
<InputGroup className="max-w-full">
71+
{type === "feature" && (
72+
<InfoPanel
73+
icon={InformationCircleIcon}
74+
iconClassName="text-blue-500"
75+
panelClassName="w-full mb-2"
12976
>
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}
77+
<Paragraph variant="small">
78+
All our feature requests are public and voted on by the community. The best
79+
way to submit your feature request is to{" "}
80+
<TextLink to="https://feedback.trigger.dev">
81+
post it to our feedback forum
82+
</TextLink>
83+
.
84+
</Paragraph>
85+
</InfoPanel>
86+
)}
87+
{type === "help" && (
88+
<InfoPanel
89+
icon={InformationCircleIcon}
90+
iconClassName="text-blue-500"
91+
panelClassName="w-full mb-2"
92+
>
93+
<Paragraph variant="small">
94+
The quickest way to get answers from the Trigger.dev team and community is to{" "}
95+
<TextLink to="https://trigger.dev/discord">ask in our Discord</TextLink>.
96+
</Paragraph>
97+
</InfoPanel>
98+
)}
99+
<Select
100+
{...conform.select(feedbackType)}
101+
variant="tertiary/medium"
102+
value={type}
103+
defaultValue={type}
104+
setValue={(v) => setType(v as FeedbackType)}
105+
placeholder="Select type"
106+
text={(value) => feedbackTypeLabel[value as FeedbackType]}
107+
dropdownIcon
108+
>
109+
{Object.entries(feedbackTypeLabel).map(([name, title]) => (
110+
<SelectItem key={name} value={name}>
111+
{title}
112+
</SelectItem>
113+
))}
114+
</Select>
115+
<FormError id={feedbackType.errorId}>{feedbackType.error}</FormError>
116+
</InputGroup>
117+
<InputGroup className="max-w-full">
118+
<Label>Message</Label>
119+
<TextArea {...conform.textarea(message)} />
120+
<FormError id={message.errorId}>{message.error}</FormError>
121+
</InputGroup>
122+
<FormError>{form.error}</FormError>
123+
<div className="flex w-full justify-end">
124+
<FormButtons
125+
className="m-0 w-max"
126+
confirmButton={
127+
<Button type="submit" variant="tertiary/medium">
128+
Send message
129+
</Button>
130+
}
131+
/>
132+
</div>
133+
</Fieldset>
134+
</Form>
190135
</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>
136+
</DialogContent>
137+
</Dialog>
196138
);
197139
}

apps/webapp/app/components/billing/v2/FreePlanUsage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function FreePlanUsage({ to, percentage }: { to: string; percentage: numb
2727
<ArrowUpCircleIcon className="h-5 w-5 text-text-dimmed" />
2828
<Paragraph className="text-2sm text-text-bright">Free Plan</Paragraph>
2929
</div>
30-
<Link to={to} className="text-2sm text-text-link">
30+
<Link to={to} className="text-2sm text-text-link focus-custom">
3131
Upgrade
3232
</Link>
3333
</div>

apps/webapp/app/components/code/CodeBlock.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
241241
onMouseEnter={() => setMouseOver(true)}
242242
onMouseLeave={() => setMouseOver(false)}
243243
className={cn(
244-
"absolute right-3 z-50 transition-colors duration-100 hover:cursor-pointer",
244+
"absolute right-3 z-50 transition-colors duration-100 focus-custom hover:cursor-pointer",
245245
showChrome ? "top-10" : "top-2.5",
246246
copied ? "text-emerald-500" : "text-charcoal-500 hover:text-charcoal-300"
247247
)}

apps/webapp/app/components/navigation/AccountSideMenu.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function AccountSideMenu({ user }: { user: User }) {
3838
<SideMenuItem
3939
name="Your profile"
4040
icon="account"
41-
iconColor="text-indigo-500"
41+
activeIconColor="text-indigo-500"
4242
to={accountPath()}
4343
data-action="account"
4444
/>
@@ -49,7 +49,7 @@ export function AccountSideMenu({ user }: { user: User }) {
4949
<SideMenuItem
5050
name="Personal Access Tokens"
5151
icon={ShieldCheckIcon}
52-
iconColor="text-emerald-500"
52+
activeIconColor="text-emerald-500"
5353
to={personalAccessTokensPath()}
5454
data-action="tokens"
5555
/>

0 commit comments

Comments
 (0)