@@ -24,12 +24,13 @@ import { Textarea } from "@podkit/forms/TextArea";
2424import Modal , { ModalFooter , ModalBody , ModalHeader } from "../components/Modal" ;
2525import { Button } from "@podkit/buttons/Button" ;
2626import { SwitchInputField } from "@podkit/switch/Switch" ;
27- import { Select , SelectContent , SelectGroup , SelectItem , SelectTrigger , SelectValue } from "@podkit/select/Select " ;
27+ import { DropdownMenu , DropdownMenuContent , DropdownMenuItem , DropdownMenuTrigger } from "@podkit/dropdown/DropDown " ;
2828
2929const sampleMarkdown = `“With Gitpod, you'll boost your productivity and streamline your workflow, giving you the freedom to work how you want while helping our team meet its efficiency goals.”
3030
3131**Hannah Cole** - CTO Acme, Inc.
3232` ;
33+ const gitpodWelcomeSubheading = `Gitpod’s sandboxed, ephemeral development environments enable you to use your existing tools without worrying about vulnerabilities impacting their local machines.` ;
3334
3435export default function TeamOnboardingPage ( ) {
3536 useDocumentTitle ( "Organization Settings - Onboarding" ) ;
@@ -121,41 +122,43 @@ export default function TeamOnboardingPage() {
121122 members once they sign up and join your organization.
122123 </ Subheading >
123124
125+ < InputField
126+ label = "Enabled"
127+ hint = { < > Enable showing the message to new organization members.</ > }
128+ id = "show-welcome-message"
129+ >
130+ < SwitchInputField
131+ id = "show-welcome-message"
132+ checked = { showWelcomeMessage }
133+ disabled = { ! isOwner || updateTeamSettings . isLoading }
134+ onCheckedChange = { setShowWelcomeMessage }
135+ label = ""
136+ />
137+ </ InputField >
138+
124139 < span className = "text-pk-content-secondary text-sm" >
125140 Here's a preview of the welcome message that will be shown to your organization members:
126141 </ span >
127142 < WelcomeMessagePreview
128143 welcomeMessage = { welcomeMessage }
129144 setWelcomeMessageEditorOpen = { setWelcomeMessageEditorOpen }
130145 avatarURL = { avatarURL }
146+ disabled = { ! showWelcomeMessage }
131147 />
132148
133- < Modal onClose = { ( ) => setWelcomeMessageEditorOpen ( false ) } visible = { welcomeMessageEditorOpen } >
149+ < Modal
150+ onClose = { ( ) => setWelcomeMessageEditorOpen ( false ) }
151+ visible = { welcomeMessageEditorOpen }
152+ containerClassName = "min-[576px]:max-w-[650px]"
153+ >
134154 < ModalHeader > Edit welcome message</ ModalHeader >
135155 < ModalBody >
136- < InputField
137- label = "Enabled"
138- hint = { < > Enable showing the message to new organization members.</ > }
139- id = "show-welcome-message"
140- >
141- < SwitchInputField
142- id = "show-welcome-message"
143- checked = { showWelcomeMessage }
144- disabled = { ! isOwner || updateTeamSettings . isLoading }
145- onCheckedChange = { setShowWelcomeMessage }
146- label = ""
147- />
148- </ InputField >
149-
150- < OrgMemberSelect
151- avatarURL = { avatarURL }
152- setAvatarURL = { setAvatarURL }
153- disabled = { ! showWelcomeMessage }
154- />
155156 < WelcomeMessageEditor
156157 welcomeMessage = { welcomeMessage }
157158 setWelcomeMessage = { setWelcomeMessage }
158159 disabled = { ! showWelcomeMessage }
160+ avatarURL = { avatarURL }
161+ setAvatarURL = { setAvatarURL }
159162 />
160163 </ ModalBody >
161164 < ModalFooter >
@@ -176,28 +179,27 @@ export default function TeamOnboardingPage() {
176179type WelcomeMessagePreviewProps = {
177180 welcomeMessage : string ;
178181 avatarURL : string | undefined ;
182+ disabled ?: boolean ;
179183 setWelcomeMessageEditorOpen : ( open : boolean ) => void ;
180184} ;
181185const WelcomeMessagePreview = ( {
182186 welcomeMessage,
183187 avatarURL,
188+ disabled,
184189 setWelcomeMessageEditorOpen,
185190} : WelcomeMessagePreviewProps ) => {
186191 return (
187192 < div className = "max-w-2xl mx-auto" >
188193 < div className = "flex justify-between gap-2 items-center" >
189194 < Heading2 className = "py-6" > Welcome to Gitpod</ Heading2 >
190- < Button variant = "secondary" onClick = { ( ) => setWelcomeMessageEditorOpen ( true ) } >
195+ < Button variant = "secondary" onClick = { ( ) => setWelcomeMessageEditorOpen ( true ) } disabled = { disabled } >
191196 Edit
192197 </ Button >
193198 </ div >
194- < Subheading >
195- Gitpod’s sandboxed, ephemeral development environments enable you to use your existing tools without
196- worrying about vulnerabilities impacting their local machines.
197- </ Subheading >
199+ < Subheading > { gitpodWelcomeSubheading } </ Subheading >
198200 { /* todo: sanitize md */ }
199201 < div className = "p-8 my-4 bg-pk-surface-secondary text-pk-content-primary rounded-xl flex flex-col gap-5 items-center justify-center" >
200- < img src = { avatarURL } alt = "" className = "w-12 h-12 rounded-full" />
202+ { avatarURL && < img src = { avatarURL } alt = "" className = "w-12 h-12 rounded-full" /> }
201203 < MDEditor . Markdown
202204 source = { welcomeMessage }
203205 className = "md-preview space-y-4 text-center bg-pk-surface-secondary"
@@ -211,18 +213,33 @@ type WelcomeMessageEditorProps = {
211213 welcomeMessage : string ;
212214 setWelcomeMessage : ( welcomeMessage : string ) => void ;
213215 disabled ?: boolean ;
216+ avatarURL : string | undefined ;
217+ setAvatarURL : ( avatarURL : string | undefined ) => void ;
214218} ;
215- const WelcomeMessageEditor = ( { welcomeMessage, setWelcomeMessage, disabled } : WelcomeMessageEditorProps ) => {
219+ const WelcomeMessageEditor = ( {
220+ welcomeMessage,
221+ setWelcomeMessage,
222+ disabled,
223+ avatarURL,
224+ setAvatarURL,
225+ } : WelcomeMessageEditorProps ) => {
216226 return (
217- < InputField label = "Welcome message" error = { undefined } className = "mb-4" >
218- < Textarea
219- className = "bg-pk-surface-secondary text-pk-content-primary w-full p-4 rounded-xl min-h-[400px]"
220- value = { welcomeMessage }
221- placeholder = "Write a welcome message to your organization members. Markdown formatting is supported."
222- onChange = { ( e ) => setWelcomeMessage ( e . target . value ) }
223- disabled = { disabled }
224- />
225- </ InputField >
227+ < div className = "space-y-4" >
228+ < TextInput readOnly value = "Welcome to Gitpod" className = "cursor-default" > </ TextInput >
229+ < Textarea value = { gitpodWelcomeSubheading } readOnly className = "cursor-default resize-none" />
230+ < div className = "w-full flex justify-center" >
231+ < OrgMemberInput avatarURL = { avatarURL } setAvatarURL = { setAvatarURL } disabled = { disabled } />
232+ </ div >
233+ < InputField label = "Welcome message" error = { undefined } className = "mb-4" labelHidden >
234+ < Textarea
235+ className = "bg-pk-surface-secondary text-pk-content-primary w-full p-4 rounded-xl min-h-[150px]"
236+ value = { welcomeMessage }
237+ placeholder = "Write a welcome message to your organization members. Markdown formatting is supported."
238+ onChange = { ( e ) => setWelcomeMessage ( e . target . value ) }
239+ disabled = { disabled }
240+ />
241+ </ InputField >
242+ </ div >
226243 ) ;
227244} ;
228245
@@ -231,35 +248,39 @@ type OrgMemberSelectProps = {
231248 setAvatarURL : ( avatarURL : string | undefined ) => void ;
232249 disabled ?: boolean ;
233250} ;
234- const OrgMemberSelect = ( { avatarURL, setAvatarURL, disabled } : OrgMemberSelectProps ) => {
251+ const OrgMemberInput = ( { avatarURL, setAvatarURL, disabled } : OrgMemberSelectProps ) => {
235252 const { data : members } = useListOrganizationMembers ( ) ;
236253
237254 return (
238- < InputField label = "Show an avatar on the welcome message" error = { undefined } className = "mb-4" >
239- < Select value = { avatarURL } onValueChange = { setAvatarURL } disabled = { disabled } >
240- < SelectTrigger >
241- < SelectValue placeholder = "No member" />
242- </ SelectTrigger >
243- < SelectContent >
244- < SelectGroup >
245- < SelectItem value = "disabled" > No member</ SelectItem >
246- </ SelectGroup >
247- < SelectGroup >
248- { members ?. map ( ( member ) => (
249- < SelectItem key = { member . userId } value = { member . avatarUrl || member . userId } >
250- < div className = "flex items-center gap-2" >
251- < img
252- src = { member . avatarUrl }
253- className = "w-4 h-4 rounded-full"
254- alt = { member . fullName }
255- />
256- { member . fullName }
257- </ div >
258- </ SelectItem >
259- ) ) }
260- </ SelectGroup >
261- </ SelectContent >
262- </ Select >
263- </ InputField >
255+ < DropdownMenu >
256+ < DropdownMenuTrigger >
257+ < div className = "flex flex-col justify-center items-center gap-2" >
258+ { avatarURL ? (
259+ < img src = { avatarURL } alt = "" className = "w-16 h-16 rounded-full" />
260+ ) : (
261+ < div className = "w-16 h-16 rounded-full bg-[#EA71DE]" />
262+ ) }
263+ < Button variant = "secondary" size = "sm" >
264+ Change Photo
265+ </ Button >
266+ </ div >
267+ </ DropdownMenuTrigger >
268+ < DropdownMenuContent >
269+ < DropdownMenuItem key = "disabled" onClick = { ( ) => setAvatarURL ( undefined ) } >
270+ < div className = "flex items-center gap-2" >
271+ < div className = "w-4 h-4 rounded-full bg-pk-surface-tertiary" />
272+ Disable image
273+ </ div >
274+ </ DropdownMenuItem >
275+ { members ?. map ( ( member ) => (
276+ < DropdownMenuItem key = { member . userId } onClick = { ( ) => setAvatarURL ( member . avatarUrl ) } >
277+ < div className = "flex items-center gap-2" >
278+ < img src = { member . avatarUrl } alt = { member . fullName } className = "w-4 h-4 rounded-full" />
279+ { member . fullName }
280+ </ div >
281+ </ DropdownMenuItem >
282+ ) ) }
283+ </ DropdownMenuContent >
284+ </ DropdownMenu >
264285 ) ;
265286} ;
0 commit comments