diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 2cde22f2b3..ab7131a2b9 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -2355,6 +2355,7 @@ type SubdomainAvailabilityDTO { isValid: Boolean! available: Boolean! suggestedSubdomain: String! + suggestedSubdomains: [String!]! } type WorkspaceCreationDefaultsDTO { diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 9885eb70ab..0ecc185e6a 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -2012,6 +2012,7 @@ export interface SubdomainAvailabilityDTO { isValid: Scalars['Boolean'] available: Scalars['Boolean'] suggestedSubdomain: Scalars['String'] + suggestedSubdomains: Scalars['String'][] __typename: 'SubdomainAvailabilityDTO' } @@ -5117,6 +5118,7 @@ export interface SubdomainAvailabilityDTOGenqlSelection{ isValid?: boolean | number available?: boolean | number suggestedSubdomain?: boolean | number + suggestedSubdomains?: boolean | number __typename?: boolean | number __scalar?: boolean | number } diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index 28db6c1c2f..e3cde05778 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -4610,6 +4610,9 @@ export default { "suggestedSubdomain": [ 1 ], + "suggestedSubdomains": [ + 1 + ], "__typename": [ 1 ] diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index f4b80eae8d..56d352c383 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -5091,6 +5091,7 @@ export type SubdomainAvailabilityDto = { available: Scalars['Boolean']['output']; isValid: Scalars['Boolean']['output']; suggestedSubdomain: Scalars['String']['output']; + suggestedSubdomains: Array; }; export type Subscription = { @@ -6819,7 +6820,7 @@ export type CheckWorkspaceSubdomainAvailabilityQueryVariables = Exact<{ }>; -export type CheckWorkspaceSubdomainAvailabilityQuery = { __typename?: 'Query', checkWorkspaceSubdomainAvailability: { __typename?: 'SubdomainAvailabilityDTO', isValid: boolean, available: boolean, suggestedSubdomain: string } }; +export type CheckWorkspaceSubdomainAvailabilityQuery = { __typename?: 'Query', checkWorkspaceSubdomainAvailability: { __typename?: 'SubdomainAvailabilityDTO', isValid: boolean, available: boolean, suggestedSubdomain: string, suggestedSubdomains: Array } }; export type FindApplicationRegistrationByClientIdQueryVariables = Exact<{ clientId: Scalars['String']['input']; @@ -8733,7 +8734,7 @@ export const UploadNewWorkspaceLogoDocument = {"kind":"Document","definitions":[ export const VerifyEmailAndGetLoginTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifyEmailAndGetLoginToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationToken"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"origin"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyEmailAndGetLoginToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"emailVerificationToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationToken"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"captchaToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}}},{"kind":"Argument","name":{"kind":"Name","value":"origin"},"value":{"kind":"Variable","name":{"kind":"Name","value":"origin"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"loginToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AuthTokenFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspaceUrls"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceUrlsFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AuthTokenFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AuthToken"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceUrlsFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceUrls"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subdomainUrl"}},{"kind":"Field","name":{"kind":"Name","value":"customUrl"}}]}}]} as unknown as DocumentNode; export const VerifyEmailAndGetWorkspaceAgnosticTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifyEmailAndGetWorkspaceAgnosticToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationToken"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyEmailAndGetWorkspaceAgnosticToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"emailVerificationToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationToken"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"captchaToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"availableWorkspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspacesFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tokens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AuthTokenPairFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AvailableWorkspaceFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AvailableWorkspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"loginToken"}},{"kind":"Field","name":{"kind":"Name","value":"inviteHash"}},{"kind":"Field","name":{"kind":"Name","value":"personalInviteToken"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceUrls"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subdomainUrl"}},{"kind":"Field","name":{"kind":"Name","value":"customUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"sso"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AuthTokenFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AuthToken"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AvailableWorkspacesFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AvailableWorkspaces"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"availableWorkspacesForSignIn"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspaceFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"availableWorkspacesForSignUp"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspaceFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AuthTokenPairFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AuthTokenPair"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accessOrWorkspaceAgnosticToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AuthTokenFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"refreshToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AuthTokenFragment"}}]}}]}}]} as unknown as DocumentNode; export const CheckUserExistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CheckUserExists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkUserExists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"captchaToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"captchaToken"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"exists"}},{"kind":"Field","name":{"kind":"Name","value":"availableWorkspacesCount"}},{"kind":"Field","name":{"kind":"Name","value":"isEmailVerified"}}]}}]}}]} as unknown as DocumentNode; -export const CheckWorkspaceSubdomainAvailabilityDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CheckWorkspaceSubdomainAvailability"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"subdomain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkWorkspaceSubdomainAvailability"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"subdomain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"subdomain"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isValid"}},{"kind":"Field","name":{"kind":"Name","value":"available"}},{"kind":"Field","name":{"kind":"Name","value":"suggestedSubdomain"}}]}}]}}]} as unknown as DocumentNode; +export const CheckWorkspaceSubdomainAvailabilityDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CheckWorkspaceSubdomainAvailability"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"subdomain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkWorkspaceSubdomainAvailability"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"subdomain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"subdomain"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isValid"}},{"kind":"Field","name":{"kind":"Name","value":"available"}},{"kind":"Field","name":{"kind":"Name","value":"suggestedSubdomain"}},{"kind":"Field","name":{"kind":"Name","value":"suggestedSubdomains"}}]}}]}}]} as unknown as DocumentNode; export const FindApplicationRegistrationByClientIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindApplicationRegistrationByClientId"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"clientId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findApplicationRegistrationByClientId"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"clientId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"clientId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"oAuthScopes"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}}]}}]}}]} as unknown as DocumentNode; export const GetPublicWorkspaceDataByDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPublicWorkspaceDataByDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"origin"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getPublicWorkspaceDataByDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"origin"},"value":{"kind":"Variable","name":{"kind":"Name","value":"origin"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceUrls"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceUrlsFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"authProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sso"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"}}]}},{"kind":"Field","name":{"kind":"Name","value":"google"}},{"kind":"Field","name":{"kind":"Name","value":"magicLink"}},{"kind":"Field","name":{"kind":"Name","value":"password"}},{"kind":"Field","name":{"kind":"Name","value":"microsoft"}}]}},{"kind":"Field","name":{"kind":"Name","value":"authBypassProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"google"}},{"kind":"Field","name":{"kind":"Name","value":"password"}},{"kind":"Field","name":{"kind":"Name","value":"microsoft"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceUrlsFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceUrls"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subdomainUrl"}},{"kind":"Field","name":{"kind":"Name","value":"customUrl"}}]}}]} as unknown as DocumentNode; export const GetWorkspaceCreationDefaultsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceCreationDefaults"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getWorkspaceCreationDefaults"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"subdomain"}}]}}]}}]} as unknown as DocumentNode; diff --git a/packages/twenty-front/src/modules/auth/graphql/queries/checkWorkspaceSubdomainAvailability.ts b/packages/twenty-front/src/modules/auth/graphql/queries/checkWorkspaceSubdomainAvailability.ts index 8d0f17f5ef..cba8b23a24 100644 --- a/packages/twenty-front/src/modules/auth/graphql/queries/checkWorkspaceSubdomainAvailability.ts +++ b/packages/twenty-front/src/modules/auth/graphql/queries/checkWorkspaceSubdomainAvailability.ts @@ -6,6 +6,7 @@ export const CHECK_WORKSPACE_SUBDOMAIN_AVAILABILITY = gql` isValid available suggestedSubdomain + suggestedSubdomains } } `; diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpV2Header.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpV2Header.tsx new file mode 100644 index 0000000000..a3cddfce9e --- /dev/null +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpV2Header.tsx @@ -0,0 +1,70 @@ +import { styled } from '@linaria/react'; +import { useLingui } from '@lingui/react/macro'; +import { IconChevronLeft } from 'twenty-ui/icon'; +import { LightIconButton } from 'twenty-ui/input'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +const HEADER_CENTER_WIDTH = 340; + +const StyledHeader = styled.div` + align-items: center; + box-sizing: border-box; + display: flex; + justify-content: space-between; + padding: ${themeCssVariables.spacing[8]}; + width: 100%; +`; + +const StyledSide = styled.div` + align-items: center; + display: flex; + flex: 1 1 0; + min-width: 0; +`; + +const StyledLeftSide = styled(StyledSide)` + justify-content: flex-end; + padding-right: ${themeCssVariables.spacing[1]}; +`; + +const StyledCenter = styled.div` + align-items: center; + display: flex; + flex: 0 1 ${HEADER_CENTER_WIDTH}px; + justify-content: flex-start; + min-width: 0; +`; + +const StyledLogo = styled.div` + background-image: url('/images/integrations/twenty-logo.svg'); + background-size: cover; + height: ${themeCssVariables.spacing[6]}; + opacity: 0.4; + width: ${themeCssVariables.spacing[6]}; +`; + +type SignInUpV2HeaderProps = { + onBack: () => void; +}; + +export const SignInUpV2Header = ({ onBack }: SignInUpV2HeaderProps) => { + const { t } = useLingui(); + + return ( + + + + + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpWorkspaceCreationFormV2.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpWorkspaceCreationFormV2.tsx new file mode 100644 index 0000000000..b6ac06e439 --- /dev/null +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpWorkspaceCreationFormV2.tsx @@ -0,0 +1,292 @@ +import { StyledOnboardingContentContainer } from '@/auth/components/StyledOnboardingContentContainer'; +import { useSignUpInNewWorkspace } from '@/auth/sign-in-up/hooks/useSignUpInNewWorkspace'; +import { useWorkspaceSubdomainField } from '@/auth/sign-in-up/hooks/useWorkspaceSubdomainField'; +import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; +import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState'; +import { TextInput } from '@/ui/input/components/TextInput'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; +import { useLingui } from '@lingui/react/macro'; +import { styled } from '@linaria/react'; +import { isNonEmptyString } from '@sniptt/guards'; +import { useEffect, useRef, useState } from 'react'; +import { Key } from 'ts-key-enum'; +import { isDefined } from 'twenty-shared/utils'; +import { Avatar } from 'twenty-ui/data-display'; +import { Loader } from 'twenty-ui/feedback'; +import { IconTrash, IconUpload } from 'twenty-ui/icon'; +import { Button, LightIconButton, MainButton } from 'twenty-ui/input'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +const StyledHeading = styled.div` + margin-bottom: ${themeCssVariables.spacing[6]}; +`; + +const StyledTitle = styled.div` + color: ${themeCssVariables.font.color.primary}; + font-size: ${themeCssVariables.font.size.xl}; + font-weight: ${themeCssVariables.font.weight.semiBold}; +`; + +const StyledSubtitle = styled.div` + color: ${themeCssVariables.font.color.secondary}; + font-size: ${themeCssVariables.font.size.sm}; + margin-top: ${themeCssVariables.spacing[1]}; +`; + +const StyledSection = styled.div` + margin-top: ${themeCssVariables.spacing[4]}; + width: 100%; +`; + +const StyledLogoRow = styled.div` + align-items: center; + display: flex; + gap: ${themeCssVariables.spacing[2]}; +`; + +const StyledHiddenFileInput = styled.input` + display: none; +`; + +const StyledButtonContainer = styled.div` + margin-top: ${themeCssVariables.spacing[6]}; + width: 100%; +`; + +const StyledAlternativesBox = styled.div` + border: 1px solid ${themeCssVariables.border.color.medium}; + border-radius: ${themeCssVariables.border.radius.sm}; + display: flex; + flex-direction: column; + gap: ${themeCssVariables.spacing[2]}; + margin-top: ${themeCssVariables.spacing[2]}; + padding: ${themeCssVariables.spacing[3]}; +`; + +const StyledAlternativesLabel = styled.span` + color: ${themeCssVariables.font.color.secondary}; + font-size: ${themeCssVariables.font.size.xs}; +`; + +const StyledAlternativeRow = styled.button` + align-items: center; + background: transparent; + border: none; + color: ${themeCssVariables.color.green}; + cursor: pointer; + display: flex; + font-size: ${themeCssVariables.font.size.sm}; + gap: ${themeCssVariables.spacing[2]}; + padding: 0; + text-align: left; +`; + +const StyledAvailabilityDot = styled.div` + background-color: ${themeCssVariables.color.green}; + border-radius: 50%; + flex-shrink: 0; + height: 6px; + width: 6px; +`; + +export const SignInUpWorkspaceCreationFormV2 = () => { + const { t } = useLingui(); + const { createWorkspace } = useSignUpInNewWorkspace(); + const { frontDomain } = useAtomStateValue(domainConfigurationState); + const isMultiWorkspaceEnabled = useAtomStateValue( + isMultiWorkspaceEnabledState, + ); + + const [isSubmitting, setIsSubmitting] = useState(false); + const [logo, setLogo] = useState(undefined); + const [logoPreviewUrl, setLogoPreviewUrl] = useState( + undefined, + ); + const hiddenFileInputRef = useRef(null); + + const { + workspaceName, + subdomain, + status, + errorMessage, + suggestions, + isAvailable, + handleWorkspaceNameChange, + handleSubdomainChange, + applySuggestionValue, + } = useWorkspaceSubdomainField({ + isSubdomainEnabled: isMultiWorkspaceEnabled, + }); + + const isContinueDisabled = + workspaceName.trim() === '' || + isSubmitting || + (isMultiWorkspaceEnabled && !isAvailable); + + const openFilePicker = () => { + hiddenFileInputRef.current?.click(); + }; + + const handleLogoUpload = (file: File) => { + if (!isDefined(file)) { + return; + } + setLogo(file); + setLogoPreviewUrl(URL.createObjectURL(file)); + }; + + const handleLogoRemove = () => { + setLogo(undefined); + setLogoPreviewUrl(undefined); + }; + + useEffect(() => { + if (!isDefined(logoPreviewUrl)) { + return; + } + + return () => { + URL.revokeObjectURL(logoPreviewUrl); + }; + }, [logoPreviewUrl]); + + const handleSubmit = async () => { + if (isContinueDisabled) { + return; + } + + setIsSubmitting(true); + try { + await createWorkspace({ + displayName: workspaceName.trim(), + ...(isMultiWorkspaceEnabled ? { subdomain } : {}), + logo, + }); + } finally { + setIsSubmitting(false); + } + }; + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.nativeEvent.isComposing || event.keyCode === 229) { + return; + } + if (event.key === Key.Enter) { + event.preventDefault(); + handleSubmit(); + } + }; + + const subdomainError = + status === 'invalid' + ? errorMessage + : status === 'unavailable' + ? t`This address is already taken` + : status === 'error' + ? t`Couldn't check availability. Please try again.` + : undefined; + + return ( + + + {t`Create your workspace`} + + {t`Move work forward across teams and agents`} + + + + + + { + const file = event.target.files?.[0]; + if (isDefined(file)) { + handleLogoUpload(file); + } + event.target.value = ''; + }} + /> +