@@ -4,6 +4,7 @@ import { RadioGroup } from "@radix-ui/react-radio-group";
44import type { ActionFunction , LoaderFunctionArgs } from "@remix-run/node" ;
55import { json , redirect } from "@remix-run/node" ;
66import { Form , useActionData , useNavigation } from "@remix-run/react" ;
7+ import { uiComponent } from "@team-plain/typescript-sdk" ;
78import { typedjson , useTypedLoaderData } from "remix-typedjson" ;
89import { z } from "zod" ;
910import { MainCenteredContainer } from "~/components/layout/AppLayout" ;
@@ -17,30 +18,33 @@ import { Input } from "~/components/primitives/Input";
1718import { InputGroup } from "~/components/primitives/InputGroup" ;
1819import { Label } from "~/components/primitives/Label" ;
1920import { RadioGroupItem } from "~/components/primitives/RadioButton" ;
21+ import { TextArea } from "~/components/primitives/TextArea" ;
2022import { useFeatures } from "~/hooks/useFeatures" ;
2123import { createOrganization } from "~/models/organization.server" ;
2224import { NewOrganizationPresenter } from "~/presenters/NewOrganizationPresenter.server" ;
23- import { requireUserId } from "~/services/session.server" ;
25+ import { logger } from "~/services/logger.server" ;
26+ import { requireUser , requireUserId } from "~/services/session.server" ;
2427import { organizationPath , rootPath } from "~/utils/pathBuilder" ;
28+ import { sendToPlain } from "~/utils/plain.server" ;
2529
2630const schema = z . object ( {
2731 orgName : z . string ( ) . min ( 3 ) . max ( 50 ) ,
2832 companySize : z . string ( ) . optional ( ) ,
33+ whyUseUs : z . string ( ) . optional ( ) ,
2934} ) ;
3035
3136export const loader = async ( { request } : LoaderFunctionArgs ) => {
3237 const userId = await requireUserId ( request ) ;
3338 const presenter = new NewOrganizationPresenter ( ) ;
34- const { hasOrganizations } = await presenter . call ( { userId } ) ;
39+ const { hasOrganizations } = await presenter . call ( { userId : userId } ) ;
3540
3641 return typedjson ( {
3742 hasOrganizations,
3843 } ) ;
3944} ;
4045
4146export const action : ActionFunction = async ( { request } ) => {
42- const userId = await requireUserId ( request ) ;
43-
47+ const user = await requireUser ( request ) ;
4448 const formData = await request . formData ( ) ;
4549 const submission = parse ( formData , { schema } ) ;
4650
@@ -51,10 +55,41 @@ export const action: ActionFunction = async ({ request }) => {
5155 try {
5256 const organization = await createOrganization ( {
5357 title : submission . value . orgName ,
54- userId,
58+ userId : user . id ,
5559 companySize : submission . value . companySize ?? null ,
5660 } ) ;
5761
62+ const whyUseUs = formData . get ( "whyUseUs" ) ;
63+
64+ if ( whyUseUs ) {
65+ try {
66+ await sendToPlain ( {
67+ userId : user . id ,
68+ email : user . email ,
69+ name : user . name ?? user . displayName ?? user . email ,
70+ title : "New org feedback" ,
71+ components : [
72+ uiComponent . text ( {
73+ text : `${ submission . value . orgName } just created a new organization.` ,
74+ } ) ,
75+ uiComponent . divider ( { spacingSize : "M" } ) ,
76+ uiComponent . text ( {
77+ size : "L" ,
78+ color : "NORMAL" ,
79+ text : "What problem are you trying to solve?" ,
80+ } ) ,
81+ uiComponent . text ( {
82+ size : "L" ,
83+ color : "NORMAL" ,
84+ text : whyUseUs . toString ( ) ,
85+ } ) ,
86+ ] ,
87+ } ) ;
88+ } catch ( error ) {
89+ logger . error ( "Error sending data to Plain when creating an org:" , { error } ) ;
90+ }
91+ }
92+
5893 return redirect ( organizationPath ( organization ) ) ;
5994 } catch ( error : any ) {
6095 return json ( { errors : { body : error . message } } , { status : 400 } ) ;
@@ -97,39 +132,48 @@ export default function NewOrganizationPage() {
97132 < FormError id = { orgName . errorId } > { orgName . error } </ FormError >
98133 </ InputGroup >
99134 { isManagedCloud && (
100- < InputGroup >
101- < Label htmlFor = { "companySize" } > Number of employees</ Label >
102- < RadioGroup name = "companySize" className = "flex items-center justify-between gap-2" >
103- < RadioGroupItem
104- id = "employees-1-5"
105- label = "1-5"
106- value = { "1-5" }
107- variant = "button/small"
108- className = "grow"
109- />
110- < RadioGroupItem
111- id = "employees-6-49"
112- label = "6-49"
113- value = { "6-49" }
114- variant = "button/small"
115- className = "grow"
116- />
117- < RadioGroupItem
118- id = "employees-50-99"
119- label = "50-99"
120- value = { "50-99" }
121- variant = "button/small"
122- className = "grow"
123- />
124- < RadioGroupItem
125- id = "employees-100+"
126- label = "100+"
127- value = { "100+" }
128- variant = "button/small"
129- className = "grow"
130- />
131- </ RadioGroup >
132- </ InputGroup >
135+ < >
136+ < InputGroup >
137+ < Label htmlFor = { "companySize" } > Number of employees</ Label >
138+ < RadioGroup name = "companySize" className = "flex items-center justify-between gap-2" >
139+ < RadioGroupItem
140+ id = "employees-1-5"
141+ label = "1-5"
142+ value = { "1-5" }
143+ variant = "button/small"
144+ className = "grow"
145+ />
146+ < RadioGroupItem
147+ id = "employees-6-49"
148+ label = "6-49"
149+ value = { "6-49" }
150+ variant = "button/small"
151+ className = "grow"
152+ />
153+ < RadioGroupItem
154+ id = "employees-50-99"
155+ label = "50-99"
156+ value = { "50-99" }
157+ variant = "button/small"
158+ className = "grow"
159+ />
160+ < RadioGroupItem
161+ id = "employees-100+"
162+ label = "100+"
163+ value = { "100+" }
164+ variant = "button/small"
165+ className = "grow"
166+ />
167+ </ RadioGroup >
168+ </ InputGroup >
169+ < InputGroup >
170+ < Label htmlFor = { "whyUseUs" } > What problem are you trying to solve?</ Label >
171+ < TextArea name = "whyUseUs" rows = { 4 } spellCheck = { false } />
172+ < Hint >
173+ Your answer will help us understand your use case and provide better support.
174+ </ Hint >
175+ </ InputGroup >
176+ </ >
133177 ) }
134178
135179 < FormButtons
0 commit comments