mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 06:34:35 +03:00
Fix skipping creating a user if we don't change the default name (#11013)
Closes: enso-org/cloud-v2#1473 This PR fixes a bug introduced in #10946
This commit is contained in:
parent
7b4b635fa8
commit
1fdaf37add
@ -9,13 +9,14 @@ import * as portal from '#/components/Portal'
|
||||
import * as suspense from '#/components/Suspense'
|
||||
|
||||
import * as mergeRefs from '#/utilities/mergeRefs'
|
||||
import * as twv from '#/utilities/tailwindVariants'
|
||||
|
||||
import type { VariantProps } from '#/utilities/tailwindVariants'
|
||||
import { tv } from '#/utilities/tailwindVariants'
|
||||
import * as dialogProvider from './DialogProvider'
|
||||
import * as dialogStackProvider from './DialogStackProvider'
|
||||
import type * as types from './types'
|
||||
import * as utlities from './utilities'
|
||||
import * as variants from './variants'
|
||||
import { DIALOG_BACKGROUND } from './variants'
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
@ -25,10 +26,10 @@ import * as variants from './variants'
|
||||
*/
|
||||
export interface DialogProps
|
||||
extends types.DialogProps,
|
||||
Omit<twv.VariantProps<typeof DIALOG_STYLES>, 'scrolledToTop'> {}
|
||||
Omit<VariantProps<typeof DIALOG_STYLES>, 'scrolledToTop'> {}
|
||||
|
||||
const OVERLAY_STYLES = twv.tv({
|
||||
base: 'fixed inset-0 isolate flex items-center justify-center bg-black/[25%]',
|
||||
const OVERLAY_STYLES = tv({
|
||||
base: 'fixed inset-0 isolate flex items-center justify-center bg-primary/20',
|
||||
variants: {
|
||||
isEntering: { true: 'animate-in fade-in duration-200 ease-out' },
|
||||
isExiting: { true: 'animate-out fade-out duration-200 ease-in' },
|
||||
@ -36,17 +37,23 @@ const OVERLAY_STYLES = twv.tv({
|
||||
},
|
||||
})
|
||||
|
||||
const MODAL_STYLES = twv.tv({
|
||||
base: 'fixed inset-0 flex items-center justify-center text-center text-xs text-primary p-4',
|
||||
const MODAL_STYLES = tv({
|
||||
base: 'fixed inset-0 flex items-center justify-center text-xs text-primary',
|
||||
variants: {
|
||||
isEntering: { true: 'animate-in slide-in-from-top-1 ease-out duration-200' },
|
||||
isExiting: { true: 'animate-out slide-out-to-top-1 ease-in duration-200' },
|
||||
isEntering: { true: 'animate-in ease-out duration-200' },
|
||||
isExiting: { true: 'animate-out ease-in duration-200' },
|
||||
type: { modal: '', fullscreen: 'p-3.5' },
|
||||
},
|
||||
compoundVariants: [
|
||||
{ type: 'modal', isEntering: true, class: 'slide-in-from-top-1' },
|
||||
{ type: 'modal', isExiting: true, class: 'slide-out-to-top-1' },
|
||||
{ type: 'fullscreen', isEntering: true, class: 'zoom-in-[1.015]' },
|
||||
{ type: 'fullscreen', isExiting: true, class: 'zoom-out-[1.015]' },
|
||||
],
|
||||
})
|
||||
|
||||
const DIALOG_STYLES = twv.tv({
|
||||
extend: variants.DIALOG_STYLES,
|
||||
base: 'w-full overflow-y-auto',
|
||||
const DIALOG_STYLES = tv({
|
||||
base: DIALOG_BACKGROUND({ className: 'w-full flex flex-col text-left align-middle shadow-xl' }),
|
||||
variants: {
|
||||
type: {
|
||||
modal: {
|
||||
@ -74,6 +81,16 @@ const DIALOG_STYLES = twv.tv({
|
||||
content: 'isolate',
|
||||
},
|
||||
},
|
||||
rounded: {
|
||||
none: { base: '' },
|
||||
small: { base: 'rounded-sm' },
|
||||
medium: { base: 'rounded-md' },
|
||||
large: { base: 'rounded-lg' },
|
||||
xlarge: { base: 'rounded-xl' },
|
||||
xxlarge: { base: 'rounded-2xl', content: 'scroll-offset-edge-2xl' },
|
||||
xxxlarge: { base: 'rounded-3xl', content: 'scroll-offset-edge-4xl' },
|
||||
xxxxlarge: { base: 'rounded-4xl', content: 'scroll-offset-edge-6xl' },
|
||||
},
|
||||
/**
|
||||
* The size of the dialog.
|
||||
* Only applies to the `modal` type.
|
||||
@ -120,6 +137,7 @@ const DIALOG_STYLES = twv.tv({
|
||||
hideCloseButton: false,
|
||||
size: 'medium',
|
||||
padding: 'medium',
|
||||
rounded: 'xxlarge',
|
||||
},
|
||||
})
|
||||
|
||||
@ -146,6 +164,7 @@ export function Dialog(props: DialogProps) {
|
||||
rounded,
|
||||
padding = type === 'modal' ? 'medium' : 'xlarge',
|
||||
fitContent,
|
||||
variants = DIALOG_STYLES,
|
||||
...ariaDialogProps
|
||||
} = props
|
||||
|
||||
@ -155,11 +174,13 @@ export function Dialog(props: DialogProps) {
|
||||
* Handles the scroll event on the dialog content.
|
||||
*/
|
||||
const handleScroll = (scrollTop: number) => {
|
||||
if (scrollTop > 0) {
|
||||
setIsScrolledToTop(false)
|
||||
} else {
|
||||
setIsScrolledToTop(true)
|
||||
}
|
||||
React.startTransition(() => {
|
||||
if (scrollTop > 0) {
|
||||
setIsScrolledToTop(false)
|
||||
} else {
|
||||
setIsScrolledToTop(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const dialogId = aria.useId()
|
||||
@ -169,7 +190,7 @@ export function Dialog(props: DialogProps) {
|
||||
const overlayState = React.useRef<aria.OverlayTriggerState | null>(null)
|
||||
const root = portal.useStrictPortalContext()
|
||||
|
||||
const styles = DIALOG_STYLES({
|
||||
const styles = variants({
|
||||
className,
|
||||
type,
|
||||
rounded,
|
||||
@ -200,11 +221,7 @@ export function Dialog(props: DialogProps) {
|
||||
return (
|
||||
<aria.ModalOverlay
|
||||
className={({ isEntering, isExiting }) =>
|
||||
OVERLAY_STYLES({
|
||||
isEntering,
|
||||
isExiting,
|
||||
blockInteractions: !isDismissable,
|
||||
})
|
||||
OVERLAY_STYLES({ isEntering, isExiting, blockInteractions: !isDismissable })
|
||||
}
|
||||
isDismissable={isDismissable}
|
||||
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
||||
@ -218,7 +235,7 @@ export function Dialog(props: DialogProps) {
|
||||
|
||||
return (
|
||||
<aria.Modal
|
||||
className={MODAL_STYLES}
|
||||
className={({ isEntering, isExiting }) => MODAL_STYLES({ type, isEntering, isExiting })}
|
||||
isDismissable={isDismissable}
|
||||
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
||||
UNSTABLE_portalContainer={root}
|
||||
@ -252,25 +269,23 @@ export function Dialog(props: DialogProps) {
|
||||
{(opts) => {
|
||||
return (
|
||||
<dialogProvider.DialogProvider value={{ close: opts.close, dialogId }}>
|
||||
{((!hideCloseButton && closeButton !== 'floating') || title != null) && (
|
||||
<aria.Header className={styles.header({ scrolledToTop: isScrolledToTop })}>
|
||||
<ariaComponents.CloseButton
|
||||
className={styles.closeButton()}
|
||||
onPress={opts.close}
|
||||
/>
|
||||
<aria.Header className={styles.header({ scrolledToTop: isScrolledToTop })}>
|
||||
<ariaComponents.CloseButton
|
||||
className={styles.closeButton()}
|
||||
onPress={opts.close}
|
||||
/>
|
||||
|
||||
{title != null && (
|
||||
<ariaComponents.Text.Heading
|
||||
id={titleId}
|
||||
level={2}
|
||||
className={styles.heading()}
|
||||
weight="semibold"
|
||||
>
|
||||
{title}
|
||||
</ariaComponents.Text.Heading>
|
||||
)}
|
||||
</aria.Header>
|
||||
)}
|
||||
{title != null && (
|
||||
<ariaComponents.Text.Heading
|
||||
id={titleId}
|
||||
level={2}
|
||||
className={styles.heading()}
|
||||
weight="semibold"
|
||||
>
|
||||
{title}
|
||||
</ariaComponents.Text.Heading>
|
||||
)}
|
||||
</aria.Header>
|
||||
|
||||
<div
|
||||
ref={(ref) => {
|
||||
|
@ -14,19 +14,4 @@ export const DIALOG_BACKGROUND = twv.tv({
|
||||
export const DIALOG_STYLES = twv.tv({
|
||||
extend: DIALOG_BACKGROUND,
|
||||
base: 'flex flex-col text-left align-middle shadow-xl',
|
||||
variants: {
|
||||
rounded: {
|
||||
none: '',
|
||||
small: 'rounded-sm',
|
||||
medium: 'rounded-md',
|
||||
large: 'rounded-lg',
|
||||
xlarge: 'rounded-xl',
|
||||
xxlarge: 'rounded-2xl',
|
||||
xxxlarge: 'rounded-3xl',
|
||||
xxxxlarge: 'rounded-4xl',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
rounded: 'xxlarge',
|
||||
},
|
||||
})
|
||||
|
@ -7,6 +7,8 @@ import { useAuth } from '#/providers/AuthProvider'
|
||||
import { useRemoteBackendStrict } from '#/providers/BackendProvider'
|
||||
import { useText } from '#/providers/TextProvider'
|
||||
import { Plan, PLANS } from '#/services/Backend'
|
||||
import type { VariantProps } from '#/utilities/tailwindVariants'
|
||||
import { tv } from '#/utilities/tailwindVariants'
|
||||
import { Card } from './components'
|
||||
import { getComponentPerPlan } from './getComponentForPlan'
|
||||
|
||||
@ -26,7 +28,7 @@ interface CreateCheckoutSessionMutation {
|
||||
/**
|
||||
* Props for {@link PlanSelector}
|
||||
*/
|
||||
export interface PlanSelectorProps {
|
||||
export interface PlanSelectorProps extends VariantProps<typeof PLAN_SELECTOR_STYLES> {
|
||||
readonly showFreePlan?: boolean
|
||||
readonly hasTrial?: boolean
|
||||
readonly userPlan?: Plan | undefined
|
||||
@ -36,6 +38,26 @@ export interface PlanSelectorProps {
|
||||
readonly onSubscribeError?: (error: Error) => void
|
||||
}
|
||||
|
||||
const PLAN_SELECTOR_STYLES = tv({
|
||||
base: DIALOG_BACKGROUND({
|
||||
className: 'w-full snap-x overflow-auto rounded-4xl scroll-hidden',
|
||||
}),
|
||||
variants: {
|
||||
showFreePlan: {
|
||||
true: {
|
||||
grid: 'grid-cols-1fr md:grid-cols-2 xl:grid-cols-4',
|
||||
},
|
||||
false: {
|
||||
grid: 'grid-cols-1fr md:grid-cols-3 justify-center',
|
||||
},
|
||||
},
|
||||
},
|
||||
slots: {
|
||||
grid: 'inline-grid min-w-full gap-6 p-6',
|
||||
card: 'min-w-64 snap-center',
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Plan selector component.
|
||||
* Shows the available plans and allows the user to subscribe to one.
|
||||
@ -49,6 +71,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
||||
showFreePlan = true,
|
||||
hasTrial = true,
|
||||
isOrganizationAdmin = false,
|
||||
variants = PLAN_SELECTOR_STYLES,
|
||||
} = props
|
||||
|
||||
const { getText } = useText()
|
||||
@ -77,13 +100,11 @@ export function PlanSelector(props: PlanSelectorProps) {
|
||||
onError: (error) => onSubscribeError?.(error),
|
||||
})
|
||||
|
||||
const classes = variants({ showFreePlan })
|
||||
|
||||
return (
|
||||
<div
|
||||
className={DIALOG_BACKGROUND({
|
||||
className: 'w-full snap-x overflow-auto rounded-4xl scroll-hidden',
|
||||
})}
|
||||
>
|
||||
<div className="inline-grid min-w-full grid-cols-1fr gap-6 p-6 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div className={classes.base()}>
|
||||
<div className={classes.grid()}>
|
||||
{PLANS.map((newPlan) => {
|
||||
const paywallLevel = getPaywallLevel(newPlan)
|
||||
const userPaywallLevel = getPaywallLevel(userPlan)
|
||||
@ -96,7 +117,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
||||
return (
|
||||
<Card
|
||||
key={newPlan}
|
||||
className="min-w-64 snap-center"
|
||||
className={classes.card()}
|
||||
features={planProps.features}
|
||||
subtitle={planProps.subtitle}
|
||||
title={planProps.title}
|
||||
@ -112,6 +133,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
||||
})
|
||||
|
||||
const startEpochMs = Number(new Date())
|
||||
|
||||
while (true) {
|
||||
const { data: session } = await refetchSession()
|
||||
if (session && 'user' in session && session.user.plan === newPlan) {
|
||||
|
@ -68,6 +68,7 @@ const BASE_STEPS: Step[] = [
|
||||
const userSession = useUserSession()
|
||||
const { getText } = textProvider.useText()
|
||||
|
||||
const isUserCreated = userSession?.type === UserSessionType.full
|
||||
const defaultName =
|
||||
session && 'user' in session ? session.user.name : userSession?.email ?? ''
|
||||
|
||||
@ -85,7 +86,8 @@ const BASE_STEPS: Step[] = [
|
||||
}
|
||||
defaultValues={{ username: defaultName }}
|
||||
onSubmit={({ username }) => {
|
||||
if (username === defaultName) {
|
||||
// If user is already created we shouldn't call `setUsername` if value wasn't changed
|
||||
if (username === defaultName && isUserCreated) {
|
||||
goToNextStep()
|
||||
return
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user