1
1
import { conform , useForm } from "@conform-to/react" ;
2
2
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" ;
11
4
import { Form , useActionData , useLocation , useNavigation } from "@remix-run/react" ;
12
- import { DiscordIcon } from "@trigger.dev/companyicons" ;
13
- import { ActivityIcon } from "lucide-react" ;
14
5
import { type ReactNode , useState } from "react" ;
15
6
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" ;
19
9
import { Fieldset } from "./primitives/Fieldset" ;
20
10
import { FormButtons } from "./primitives/FormButtons" ;
21
11
import { FormError } from "./primitives/FormError" ;
22
- import { Header1 } from "./primitives/Headers" ;
12
+ import { Icon } from "./primitives/Icon" ;
13
+ import { InfoPanel } from "./primitives/InfoPanel" ;
23
14
import { InputGroup } from "./primitives/InputGroup" ;
24
15
import { Label } from "./primitives/Label" ;
25
16
import { Paragraph } from "./primitives/Paragraph" ;
26
17
import { Select , SelectItem } from "./primitives/Select" ;
27
- import { Sheet , SheetBody , SheetContent , SheetTrigger } from "./primitives/Sheet" ;
28
18
import { TextArea } from "./primitives/TextArea" ;
29
19
30
20
type FeedbackProps = {
@@ -37,6 +27,7 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
37
27
const location = useLocation ( ) ;
38
28
const lastSubmission = useActionData ( ) ;
39
29
const navigation = useNavigation ( ) ;
30
+ const [ type , setType ] = useState < FeedbackType > ( defaultValue ) ;
40
31
41
32
const [ form , { path, feedbackType, message } ] = useForm ( {
42
33
id : "accept-invite" ,
@@ -57,141 +48,84 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
57
48
}
58
49
59
50
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.
95
60
</ 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"
129
74
>
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 >
190
127
</ 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 >
196
130
) ;
197
131
}
0 commit comments