11import { conform , useForm } from "@conform-to/react" ;
22import { parse } from "@conform-to/zod" ;
3- import { FolderIcon , CommandLineIcon , PuzzlePieceIcon } from "@heroicons/react/20/solid" ;
3+ import { CommandLineIcon , FolderIcon } from "@heroicons/react/20/solid" ;
44import { json , type ActionFunction , type LoaderFunctionArgs } from "@remix-run/node" ;
55import { Form , useActionData , useNavigation } from "@remix-run/react" ;
6- import { redirect , typedjson , useTypedLoaderData } from "remix-typedjson" ;
76import type { Prisma } from "@trigger.dev/database" ;
7+ import React , { useEffect , useState } from "react" ;
8+ import { redirect , typedjson , useTypedLoaderData } from "remix-typedjson" ;
89import invariant from "tiny-invariant" ;
9- import { useEffect , useState } from "react" ;
1010import { z } from "zod" ;
1111import { BackgroundWrapper } from "~/components/BackgroundWrapper" ;
1212import { Feedback } from "~/components/Feedback" ;
1313import { AppContainer , MainCenteredContainer } from "~/components/layout/AppLayout" ;
14+ import { TechnologyPicker } from "~/components/onboarding/TechnologyPicker" ;
1415import { Button , LinkButton } from "~/components/primitives/Buttons" ;
1516import { Callout } from "~/components/primitives/Callout" ;
1617import { Fieldset } from "~/components/primitives/Fieldset" ;
@@ -22,7 +23,6 @@ import { InputGroup } from "~/components/primitives/InputGroup";
2223import { Label } from "~/components/primitives/Label" ;
2324import { Select , SelectItem } from "~/components/primitives/Select" ;
2425import { ButtonSpinner } from "~/components/primitives/Spinner" ;
25- import { TechnologyPicker } from "~/components/onboarding/TechnologyPicker" ;
2626import { prisma } from "~/db.server" ;
2727import { featuresForRequest } from "~/features.server" ;
2828import { redirectWithErrorMessage , redirectWithSuccessMessage } from "~/models/message.server" ;
@@ -64,6 +64,47 @@ function shuffleArray<T>(arr: T[]): T[] {
6464 return shuffled ;
6565}
6666
67+ function MultiSelectField ( {
68+ value,
69+ setValue,
70+ items,
71+ icon,
72+ } : {
73+ value : string [ ] ;
74+ setValue : ( value : string [ ] ) => void ;
75+ items : string [ ] ;
76+ icon : React . ReactNode ;
77+ } ) {
78+ return (
79+ < Select < string [ ] , string >
80+ value = { value }
81+ setValue = { setValue }
82+ placeholder = "Select options"
83+ variant = "secondary/small"
84+ dropdownIcon
85+ icon = { icon }
86+ items = { items }
87+ className = "h-8 min-w-0 border-0 bg-charcoal-750 pl-2 text-sm text-text-dimmed ring-charcoal-600 transition hover:bg-charcoal-650 hover:text-text-dimmed hover:ring-1"
88+ text = { ( v ) =>
89+ v . length === 0 ? undefined : (
90+ < span className = "flex min-w-0 items-center text-text-bright" >
91+ < span className = "truncate" > { v . slice ( 0 , 2 ) . join ( ", " ) } </ span >
92+ { v . length > 2 && < span className = "ml-1 flex-none" > +{ v . length - 2 } more</ span > }
93+ </ span >
94+ )
95+ }
96+ >
97+ { ( items ) =>
98+ items . map ( ( item ) => (
99+ < SelectItem key = { item } value = { item } checkPosition = "left" >
100+ < span className = "text-text-bright" > { item } </ span >
101+ </ SelectItem >
102+ ) )
103+ }
104+ </ Select >
105+ ) ;
106+ }
107+
67108export async function loader ( { params, request } : LoaderFunctionArgs ) {
68109 const userId = await requireUserId ( request ) ;
69110 const { organizationSlug } = OrganizationParamsSchema . parse ( params ) ;
@@ -320,43 +361,23 @@ export default function Page() {
320361 < InputGroup >
321362 < Label > What are you working on?</ Label >
322363 < input type = "hidden" name = "workingOn" value = { JSON . stringify ( selectedWorkingOn ) } />
323- < Select < string [ ] , string >
364+ < MultiSelectField
324365 value = { selectedWorkingOn }
325366 setValue = { setSelectedWorkingOn }
326- placeholder = "Select options"
327- variant = "secondary/small"
328- dropdownIcon
329- icon = { < CommandLineIcon className = "mr-1 size-4 text-text-dimmed" /> }
330367 items = { shuffledWorkingOn }
331- className = "h-8 border-0 bg-charcoal-750 pl-3 text-sm text-text-dimmed transition ring-charcoal-600 hover:bg-charcoal-650 hover:text-text-dimmed hover:ring-1"
332- text = { ( value ) =>
333- value . length === 0 ? undefined : (
334- < span className = "text-text-bright" >
335- { value . length <= 2
336- ? value . join ( ", " )
337- : `${ value . slice ( 0 , 2 ) . join ( ", " ) } +${ value . length - 2 } more` }
338- </ span >
339- )
340- }
341- >
342- { ( items ) =>
343- items . map ( ( item ) => (
344- < SelectItem key = { item } value = { item } checkPosition = "left" >
345- < span className = "text-text-bright" > { item } </ span >
346- </ SelectItem >
347- ) )
348- }
349- </ Select >
368+ icon = { < CommandLineIcon className = "mr-1 size-4 text-text-dimmed" /> }
369+ />
350370 { showWorkingOnOther && (
351371 < >
352372 < input type = "hidden" name = "workingOnOther" value = { workingOnOther } />
353373 < Input
354374 type = "text"
375+ variant = "small"
355376 value = { workingOnOther }
356377 onChange = { ( e ) => setWorkingOnOther ( e . target . value ) }
357378 placeholder = "Tell us what you're working on"
358379 spellCheck = { false }
359- className = "mt-2 "
380+ containerClassName = "h-8 "
360381 />
361382 </ >
362383 ) }
@@ -385,33 +406,12 @@ export default function Page() {
385406 < InputGroup >
386407 < Label > What are you trying to do with Trigger.dev?</ Label >
387408 < input type = "hidden" name = "goals" value = { JSON . stringify ( selectedGoals ) } />
388- < Select < string [ ] , string >
409+ < MultiSelectField
389410 value = { selectedGoals }
390411 setValue = { setSelectedGoals }
391- placeholder = "Select options"
392- variant = "secondary/small"
393- dropdownIcon
394- icon = { < PuzzlePieceIcon className = "size-4 text-text-dimmed" /> }
395412 items = { [ ...goalOptions ] }
396- className = "h-8 border-0 bg-charcoal-750 pl-3 text-sm text-text-dimmed transition ring-charcoal-600 hover:bg-charcoal-650 hover:text-text-dimmed hover:ring-1"
397- text = { ( value ) =>
398- value . length === 0 ? undefined : (
399- < span className = "text-text-bright" >
400- { value . length <= 2
401- ? value . join ( ", " )
402- : `${ value . slice ( 0 , 2 ) . join ( ", " ) } +${ value . length - 2 } more` }
403- </ span >
404- )
405- }
406- >
407- { ( items ) =>
408- items . map ( ( item ) => (
409- < SelectItem key = { item } value = { item } checkPosition = "left" >
410- < span className = "text-text-bright" > { item } </ span >
411- </ SelectItem >
412- ) )
413- }
414- </ Select >
413+ icon = { < CommandLineIcon className = "mr-1 size-4 text-text-dimmed" /> }
414+ />
415415 </ InputGroup >
416416
417417 < FormButtons
0 commit comments