| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  | import { HashtagIcon, InformationCircleIcon, LinkIcon, PhotographIcon } from "@heroicons/react/solid"; | 
					
						
							|  |  |  | import React, { useRef, useState } from "react"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 23:36:43 +00:00
										 |  |  | import showToast from "@calcom/lib/notification"; | 
					
						
							|  |  |  | import { Alert } from "@calcom/ui/Alert"; | 
					
						
							|  |  |  | import Button from "@calcom/ui/Button"; | 
					
						
							|  |  |  | import { TextField } from "@calcom/ui/form/fields"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  | import { useLocale } from "@lib/hooks/useLocale"; | 
					
						
							|  |  |  | import { TeamWithMembers } from "@lib/queries/teams"; | 
					
						
							|  |  |  | import { trpc } from "@lib/trpc"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ImageUploader from "@components/ImageUploader"; | 
					
						
							|  |  |  | import SettingInputContainer from "@components/ui/SettingInputContainer"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface Props { | 
					
						
							|  |  |  |   team: TeamWithMembers | null | undefined; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default function TeamSettings(props: Props) { | 
					
						
							|  |  |  |   const { t } = useLocale(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const [hasErrors, setHasErrors] = useState(false); | 
					
						
							|  |  |  |   const [errorMessage, setErrorMessage] = useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const team = props.team; | 
					
						
							|  |  |  |   const hasLogo = !!team?.logo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const utils = trpc.useContext(); | 
					
						
							|  |  |  |   const mutation = trpc.useMutation("viewer.teams.update", { | 
					
						
							|  |  |  |     onError: (err) => { | 
					
						
							|  |  |  |       setHasErrors(true); | 
					
						
							|  |  |  |       setErrorMessage(err.message); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     async onSuccess() { | 
					
						
							|  |  |  |       await utils.invalidateQueries(["viewer.teams.get"]); | 
					
						
							|  |  |  |       showToast(t("your_team_updated_successfully"), "success"); | 
					
						
							|  |  |  |       setHasErrors(false); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const nameRef = useRef<HTMLInputElement>() as React.MutableRefObject<HTMLInputElement>; | 
					
						
							|  |  |  |   const teamUrlRef = useRef<HTMLInputElement>() as React.MutableRefObject<HTMLInputElement>; | 
					
						
							|  |  |  |   const descriptionRef = useRef<HTMLTextAreaElement>() as React.MutableRefObject<HTMLTextAreaElement>; | 
					
						
							|  |  |  |   const hideBrandingRef = useRef<HTMLInputElement>() as React.MutableRefObject<HTMLInputElement>; | 
					
						
							|  |  |  |   const logoRef = useRef<HTMLInputElement>() as React.MutableRefObject<HTMLInputElement>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function updateTeamData() { | 
					
						
							|  |  |  |     if (!team) return; | 
					
						
							|  |  |  |     const variables = { | 
					
						
							|  |  |  |       name: nameRef.current?.value, | 
					
						
							|  |  |  |       slug: teamUrlRef.current?.value, | 
					
						
							|  |  |  |       bio: descriptionRef.current?.value, | 
					
						
							|  |  |  |       hideBranding: hideBrandingRef.current?.checked, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     // remove unchanged variables
 | 
					
						
							|  |  |  |     for (const key in variables) { | 
					
						
							|  |  |  |       if (variables[key] === team?.[key]) delete variables[key]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mutation.mutate({ id: team.id, ...variables }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function updateLogo(newLogo: string) { | 
					
						
							|  |  |  |     if (!team) return; | 
					
						
							|  |  |  |     logoRef.current.value = newLogo; | 
					
						
							|  |  |  |     mutation.mutate({ id: team.id, logo: newLogo }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const removeLogo = () => updateLogo(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <div className="divide-y divide-gray-200 lg:col-span-9"> | 
					
						
							|  |  |  |       <div className=""> | 
					
						
							|  |  |  |         {hasErrors && <Alert severity="error" title={errorMessage} />} | 
					
						
							|  |  |  |         <form | 
					
						
							|  |  |  |           className="divide-y divide-gray-200 lg:col-span-9" | 
					
						
							|  |  |  |           onSubmit={(e) => { | 
					
						
							|  |  |  |             e.preventDefault(); | 
					
						
							|  |  |  |             updateTeamData(); | 
					
						
							|  |  |  |           }}> | 
					
						
							|  |  |  |           <div className="py-6"> | 
					
						
							|  |  |  |             <div className="flex flex-col lg:flex-row"> | 
					
						
							|  |  |  |               <div className="flex-grow space-y-6"> | 
					
						
							|  |  |  |                 <SettingInputContainer | 
					
						
							|  |  |  |                   Icon={LinkIcon} | 
					
						
							|  |  |  |                   label="Team URL" | 
					
						
							|  |  |  |                   htmlFor="team-url" | 
					
						
							|  |  |  |                   Input={ | 
					
						
							|  |  |  |                     <TextField | 
					
						
							| 
									
										
										
										
											2021-12-17 00:16:59 +00:00
										 |  |  |                       name="" // typescript requires name but we don't want component to render name label
 | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                       id="team-url" | 
					
						
							|  |  |  |                       addOnLeading={ | 
					
						
							| 
									
										
										
										
											2022-03-09 22:17:46 +00:00
										 |  |  |                         <span className="inline-flex items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-sm text-gray-500"> | 
					
						
							| 
									
										
										
										
											2022-03-26 00:39:38 +00:00
										 |  |  |                           {process.env.NEXT_PUBLIC_WEBSITE_URL}/{"team/"} | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                         </span> | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                       ref={teamUrlRef} | 
					
						
							|  |  |  |                       defaultValue={team?.slug as string} | 
					
						
							|  |  |  |                     /> | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 /> | 
					
						
							|  |  |  |                 <SettingInputContainer | 
					
						
							|  |  |  |                   Icon={HashtagIcon} | 
					
						
							|  |  |  |                   label="Team Name" | 
					
						
							|  |  |  |                   htmlFor="name" | 
					
						
							|  |  |  |                   Input={ | 
					
						
							|  |  |  |                     <input | 
					
						
							|  |  |  |                       ref={nameRef} | 
					
						
							|  |  |  |                       type="text" | 
					
						
							|  |  |  |                       name="name" | 
					
						
							|  |  |  |                       id="name" | 
					
						
							|  |  |  |                       placeholder={t("your_team_name")} | 
					
						
							|  |  |  |                       required | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                       className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-neutral-800 sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                       defaultValue={team?.name as string} | 
					
						
							|  |  |  |                     /> | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 /> | 
					
						
							|  |  |  |                 <hr /> | 
					
						
							|  |  |  |                 <div> | 
					
						
							|  |  |  |                   <SettingInputContainer | 
					
						
							|  |  |  |                     Icon={InformationCircleIcon} | 
					
						
							|  |  |  |                     label={t("about")} | 
					
						
							|  |  |  |                     htmlFor="about" | 
					
						
							|  |  |  |                     Input={ | 
					
						
							|  |  |  |                       <> | 
					
						
							|  |  |  |                         <textarea | 
					
						
							|  |  |  |                           ref={descriptionRef} | 
					
						
							|  |  |  |                           id="about" | 
					
						
							|  |  |  |                           name="about" | 
					
						
							|  |  |  |                           rows={3} | 
					
						
							|  |  |  |                           defaultValue={team?.bio as string} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                           className="mt-1 block w-full rounded-sm border-gray-300 shadow-sm focus:border-neutral-800 focus:ring-neutral-800 sm:text-sm"></textarea> | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                         <p className="mt-2 text-sm text-gray-500">{t("team_description")}</p> | 
					
						
							|  |  |  |                       </> | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   /> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |                 <div> | 
					
						
							|  |  |  |                   <SettingInputContainer | 
					
						
							|  |  |  |                     Icon={PhotographIcon} | 
					
						
							|  |  |  |                     label={"Logo"} | 
					
						
							|  |  |  |                     htmlFor="avatar" | 
					
						
							|  |  |  |                     Input={ | 
					
						
							|  |  |  |                       <> | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                         <div className="mt-1 flex"> | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                           <input | 
					
						
							|  |  |  |                             ref={logoRef} | 
					
						
							|  |  |  |                             type="hidden" | 
					
						
							|  |  |  |                             name="avatar" | 
					
						
							|  |  |  |                             id="avatar" | 
					
						
							|  |  |  |                             placeholder="URL" | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                             className="mt-1 block w-full rounded-sm border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-800 focus:outline-none focus:ring-neutral-800 sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                             defaultValue={team?.logo ?? undefined} | 
					
						
							|  |  |  |                           /> | 
					
						
							|  |  |  |                           <ImageUploader | 
					
						
							|  |  |  |                             target="logo" | 
					
						
							|  |  |  |                             id="logo-upload" | 
					
						
							|  |  |  |                             buttonMsg={hasLogo ? t("edit_logo") : t("upload_a_logo")} | 
					
						
							|  |  |  |                             handleAvatarChange={updateLogo} | 
					
						
							|  |  |  |                             imageSrc={team?.logo ?? undefined} | 
					
						
							|  |  |  |                           /> | 
					
						
							|  |  |  |                           {hasLogo && ( | 
					
						
							|  |  |  |                             <Button | 
					
						
							|  |  |  |                               onClick={removeLogo} | 
					
						
							|  |  |  |                               color="secondary" | 
					
						
							|  |  |  |                               type="button" | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                               className="ml-1 py-1 text-xs"> | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                               {t("remove_logo")} | 
					
						
							|  |  |  |                             </Button> | 
					
						
							|  |  |  |                           )} | 
					
						
							|  |  |  |                         </div> | 
					
						
							|  |  |  |                       </> | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   /> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   <hr className="mt-6" /> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 <div className="relative flex items-start"> | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   <div className="flex h-5 items-center"> | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                     <input | 
					
						
							|  |  |  |                       id="hide-branding" | 
					
						
							|  |  |  |                       name="hide-branding" | 
					
						
							|  |  |  |                       type="checkbox" | 
					
						
							|  |  |  |                       ref={hideBrandingRef} | 
					
						
							|  |  |  |                       defaultChecked={team?.hideBranding} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                       className="h-4 w-4 rounded-sm border-gray-300 text-neutral-900 focus:ring-neutral-500" | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                     /> | 
					
						
							|  |  |  |                   </div> | 
					
						
							| 
									
										
										
										
											2022-02-01 22:17:37 +00:00
										 |  |  |                   <div className="text-sm ltr:ml-3 rtl:mr-3"> | 
					
						
							| 
									
										
										
										
											2021-12-09 23:51:30 +00:00
										 |  |  |                     <label htmlFor="hide-branding" className="font-medium text-gray-700"> | 
					
						
							|  |  |  |                       {t("disable_cal_branding")} | 
					
						
							|  |  |  |                     </label> | 
					
						
							|  |  |  |                     <p className="text-gray-500">{t("disable_cal_branding_description")}</p> | 
					
						
							|  |  |  |                   </div> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |           <div className="flex justify-end py-4"> | 
					
						
							|  |  |  |             <Button type="submit" color="primary"> | 
					
						
							|  |  |  |               {t("save")} | 
					
						
							|  |  |  |             </Button> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </form> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } |