Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apis/api-users/src/schema/user/findOrFetchUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ export async function findOrFetchUser(
if (user == null) {
try {
user = await prisma.user.create({
data
})
data
})
userCreated = true
} catch {
user = await prisma.user.findUnique({
Expand Down
6 changes: 0 additions & 6 deletions apps/journeys-admin/__generated__/GetAdminJourneys.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/journeys-admin/__generated__/JourneyDuplicate.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useRouter } from 'next/router'
import { useUser } from 'next-firebase-auth'
import { useTranslation } from 'next-i18next'
import { useSnackbar } from 'notistack'
import { ReactElement, useEffect, useState } from 'react'
import { ReactElement, useState } from 'react'
import { object } from 'yup'

import { useJourney } from '@core/journeys/ui/JourneyProvider'
Expand All @@ -19,27 +19,14 @@ import { useJourneyDuplicateMutation } from '@core/journeys/ui/useJourneyDuplica
import { LanguageAutocomplete } from '@core/shared/ui/LanguageAutocomplete'

import { JourneyProfileCreate } from '../../../../../../__generated__/JourneyProfileCreate'
import { JourneyStatus } from '../../../../../../__generated__/globalTypes'
import { useCurrentUserLazyQuery } from '../../../../../libs/useCurrentUserLazyQuery'
import { useGetChildTemplateJourneyLanguages } from '../../../../../libs/useGetChildTemplateJourneyLanguages'
import { useGetParentTemplateJourneyLanguages } from '../../../../../libs/useGetParentTemplateJourneyLanguages'
import {
useTeamCreateMutation,
useTeamCreateMutationGuest
} from '../../../../../libs/useTeamCreateMutation'
import { useTeamCreateMutation } from '../../../../../libs/useTeamCreateMutation'
import { CustomizationScreen } from '../../../utils/getCustomizeFlowConfig'
import { CustomizeFlowNextButton } from '../../CustomizeFlowNextButton'


// const JOURNEY_PROFILE_CREATE = gql`
// mutation JourneyProfileCreate {
// journeyProfileCreate {
// id
// userId
// acceptedTermsAt
// }
// }
// `

interface LanguageScreenProps {
handleNext: () => void
handleScreenNavigation: (screen: CustomizationScreen) => void
Expand All @@ -60,14 +47,6 @@ export function LanguageScreen({
const isSignedIn = user?.email != null && user?.id != null
const { query } = useTeam()

useEffect(() => {
//TODO: delete this effect
const firebaseUserId = user?.id ?? null
const isAnonymous = user?.firebaseUser?.isAnonymous ?? false
console.log('[LanguageScreen] Firebase user id:', firebaseUserId)
console.log('[LanguageScreen] Is anonymous user:', isAnonymous)
}, [user?.id, user?.firebaseUser?.isAnonymous])

const isParentTemplate = journey?.fromTemplateId == null

const {
Expand Down Expand Up @@ -131,121 +110,45 @@ export function LanguageScreen({

const [journeyDuplicate] = useJourneyDuplicateMutation()
const { loadUser } = useCurrentUserLazyQuery()
// const [journeyProfileCreate] = useMutation<JourneyProfileCreate>(
// JOURNEY_PROFILE_CREATE
// )
const [teamCreate] = useTeamCreateMutation()
const [teamCreateGuest] = useTeamCreateMutationGuest()

const FORM_SM_BREAKPOINT_WIDTH = '390px'

async function createGuestUser(): Promise<{ teamId: string } | null> {
try {
console.log('[createGuestUser] 1. start', {
isAnonymous: user?.firebaseUser?.isAnonymous ?? false
})
const isAnonymous = user?.firebaseUser?.isAnonymous ?? false
if (!isAnonymous) {
console.log('[createGuestUser] 2. calling signInAnonymously')
await signInAnonymously(getAuth(getApp()))
console.log('[createGuestUser] 3. signInAnonymously done')
} else {
console.log('[createGuestUser] 2. already anonymous, skip signInAnonymously')
}

const teamName = t('My Team')

let meResult: Awaited<ReturnType<typeof loadUser>> | null = null
try {
console.log('[createGuestUser] 4. calling loadUser')
meResult = await loadUser()
console.log('[createGuestUser] 5. loadUser done', {
hasMe: meResult?.data?.me != null,
__typename: meResult?.data?.me?.__typename
})
} catch (e) {
console.error('[createGuestUser] loadUser failed:', e)
async function createGuestUser(): Promise<{ teamId: string }> {
const teamName = t('My Team')
const isAnonymous = user?.firebaseUser?.isAnonymous ?? false
if (!isAnonymous) {
await signInAnonymously(getAuth(getApp()))
}

// let profileResult: Awaited<ReturnType<typeof journeyProfileCreate>> | null =
// null
// try {
// profileResult = await journeyProfileCreate()
// } catch (e) {
// console.error('[createGuestUser] journeyProfileCreate failed:', e)
// }

let teamResult: Awaited<ReturnType<typeof teamCreate>> | null = null
try {
console.log('[createGuestUser] 6. calling teamCreate', { teamName })
teamResult = await teamCreateGuest({
const [, teamResult] = await Promise.all([
loadUser().catch(() => null),
teamCreate({
variables: {
input: { title: teamName, publicTitle: teamName }
}
})
console.log('[createGuestUser] 7. teamCreate done', {
teamId: teamResult?.data?.teamCreate?.id
})
} catch (e) {
const err = e as {
graphQLErrors?: Array<{ message: string; extensions?: unknown }>
networkError?: unknown
message?: string
cause?: unknown
}
console.error('[createGuestUser] teamCreate failed:', err?.message ?? e)
if (err?.graphQLErrors?.length) {
err.graphQLErrors.forEach((g, i) => {
console.error(
`[createGuestUser] graphQLErrors[${i}]:`,
g.message,
g.extensions
)
})
}
if (err?.networkError) {
console.error('[createGuestUser] networkError:', err.networkError)
}
if (err?.cause != null) {
console.error('[createGuestUser] cause:', err.cause)
}
return null
}
])

if (teamResult?.data?.teamCreate == null) {
console.log('[createGuestUser] 8. returning null (team missing)', {
hasMe: meResult?.data?.me != null,
hasTeam: false
})
return null
throw new Error('Guest team creation returned no team')
}

// Refetch me after teamCreate (user was created in resolveReference); optional for guest flow
if (meResult?.data?.me == null) {
try {
await loadUser()
} catch {
// ignore
}
}

// Guest flow success: we have a team (user exists in api-users via resolveReference)
console.log('[createGuestUser] 9. success', {
teamId: teamResult.data.teamCreate.id
})
return { teamId: teamResult.data.teamCreate.id }
} catch (e) {
console.error('[createGuestUser] unexpected error:', e)
return null
}
return { teamId: teamResult.data.teamCreate.id }
}

async function duplicateJourneyAndRedirect(
journeyId: string,
teamId: string
teamId: string,
duplicateAsDraft?: boolean
): Promise<boolean> {
const { data } = await journeyDuplicate({
variables: { id: journeyId, teamId, forceNonTemplate: true }
variables: {
id: journeyId,
teamId,
forceNonTemplate: true,
duplicateAsDraft
}
})
if (data?.journeyDuplicate == null) return false

Expand Down Expand Up @@ -276,16 +179,14 @@ export function LanguageScreen({
}

if (isSignedIn) {
// Duplicates journey for a signed in user
const teams = query?.data?.teams ?? []
const teamId =
query?.data?.getJourneyProfile?.lastActiveTeamId ?? teams[0]?.id
if (teamId == null) {
enqueueSnackbar(
t(
'No team available. Please create a team first.'
),
{ variant: 'error' }
)
enqueueSnackbar(t('No team available. Please create a team first.'), {
variant: 'error'
})
setLoading(false)
return
}
Expand All @@ -303,43 +204,25 @@ export function LanguageScreen({
setLoading(false)
return
} else {
// Creates a guest user and duplicates the journey for them
try {
const guestResult = await createGuestUser()
if (guestResult == null) {
enqueueSnackbar(
t('Unable to continue as guest. Please try again or sign in.'),
{ variant: 'error' }
)
setLoading(false)
return
}

try {
const success = await duplicateJourneyAndRedirect(
journeyId,
guestResult.teamId
)
if (!success) {
enqueueSnackbar(
t(
'Failed to duplicate journey to team, please refresh the page and try again'
),
{ variant: 'error' }
)
} else {
handleNext()
}
} catch (e) {
console.error('[LanguageScreen] duplicateJourneyAndRedirect error:', e)
const journeyDuplicateSuccess = await duplicateJourneyAndRedirect(
journeyId,
guestResult.teamId,
true
)
if (!journeyDuplicateSuccess) {
enqueueSnackbar(
t(
'Failed to duplicate journey to team, please refresh the page and try again'
),
{ variant: 'error' }
)
} else {
handleNext()
}
} catch (e) {
console.error('[LanguageScreen] createGuestUser error:', e)
} catch {
enqueueSnackbar(
t('Unable to continue as guest. Please try again or sign in.'),
{ variant: 'error' }
Expand Down
5 changes: 1 addition & 4 deletions apps/journeys-admin/src/libs/useTeamCreateMutation/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
export {
useTeamCreateMutation,
useTeamCreateMutationGuest
} from './useTeamCreateMutation'
export { useTeamCreateMutation } from './useTeamCreateMutation'
Original file line number Diff line number Diff line change
Expand Up @@ -42,33 +42,6 @@ export const TEAM_CREATE = gql`
}
`

/** Minimal selection for guest flow: only user.id to avoid User entity field resolution errors in federation. */
export const TEAM_CREATE_GUEST = gql`
mutation TeamCreateGuest($input: TeamCreateInput!) {
teamCreate(input: $input) {
id
title
publicTitle
userTeams {
id
user {
... on AuthenticatedUser {
id
}
... on AnonymousUser {
id
}
}
role
}
customDomains {
id
name
}
}
}
`

export function useTeamCreateMutation(
options?: MutationHookOptions<TeamCreate, TeamCreateVariables>
): MutationTuple<TeamCreate, TeamCreateVariables> {
Expand Down Expand Up @@ -103,37 +76,3 @@ export function useTeamCreateMutation(

return mutation
}

/** Use for guest flow: only requests user.id to avoid federation User field resolution errors. */
export function useTeamCreateMutationGuest(
options?: MutationHookOptions<TeamCreate, TeamCreateVariables>
): MutationTuple<TeamCreate, TeamCreateVariables> {
const { setActiveTeam } = useTeam()
return useMutation<TeamCreate>(TEAM_CREATE_GUEST, {
update(cache, { data }) {
if (data?.teamCreate != null) {
cache.modify({
fields: {
teams(existingTeams = []) {
const newTeamRef = cache.writeFragment({
data: data.teamCreate,
fragment: gql`
fragment NewTeam on Team {
id
}
`
})
return [...existingTeams, newTeamRef]
}
}
})
}
},
onCompleted(data) {
if (data?.teamCreate != null) {
setActiveTeam(data.teamCreate)
}
},
...options
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ export function UseThisTemplateButton({

const handleCheckSignIn = async (): Promise<void> => {
// For menu-item variant, assume user is signed in
// if (variant === 'menu-item' || signedIn) {
setLoading(true)
await handleCustomizeNavigation()
// } else {
// setOpenAccountDialog(true)
// }
if (variant === 'menu-item' || signedIn) {
setLoading(true)
await handleCustomizeNavigation()
} else {
setOpenAccountDialog(true)
}
}

const handleSignIn = (login: boolean): void => {
Expand Down
Loading
Loading