import { useState, type FC } from 'react'; import { Box, Button, Checkbox, Dialog, styled, Typography, TextField, } from '@mui/material'; import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import { OrderEnvironmentsDialogPricing } from './OrderEnvironmentsDialogPricing/OrderEnvironmentsDialogPricing'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import type { IFormErrors } from 'hooks/useFormErrors'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import type { OrderEnvironmentsSchemaEnvironmentsItem } from 'openapi'; type OrderEnvironmentsDialogProps = { open: boolean; onClose: () => void; onSubmit: (environments: OrderEnvironmentsSchemaEnvironmentsItem[]) => void; errors?: IFormErrors; }; const StyledDialog = styled(Dialog)(({ theme }) => ({ maxWidth: '940px', margin: 'auto', '& .MuiDialog-paper': { borderRadius: theme.shape.borderRadiusExtraLarge, maxWidth: theme.spacing(170), width: '100%', backgroundColor: 'transparent', }, padding: 0, '& .MuiPaper-root > section': { overflowX: 'hidden', }, })); const StyledTitle = styled('div')(({ theme }) => ({ marginBottom: theme.spacing(3), })); const StyledFooter = styled('div')(({ theme }) => ({ display: 'flex', justifyContent: 'flex-end', gap: theme.spacing(2), })); const StyledGeneralSelect = styled(GeneralSelect)(({ theme }) => ({ margin: theme.spacing(1, 0), })); const StyledTypeSelect = styled(GeneralSelect)(({ theme }) => ({ minWidth: '166px', })); const StyledEnvironmentInputs = styled(Box)(({ theme }) => ({ display: 'flex', gap: theme.spacing(2), marginBottom: theme.spacing(2), })); const StyledFields = styled(Box)(({ theme }) => ({ display: 'flex', flexDirection: 'column', gap: theme.spacing(2), paddingTop: theme.spacing(3), })); const StyledEnvironmentNameInputs = styled('fieldset')(({ theme }) => ({ display: 'flex', flexDirection: 'column', border: 'none', padding: 0, margin: 0, gap: theme.spacing(1.5), })); const StyledCheckbox = styled(Checkbox)(({ theme }) => ({ marginBottom: theme.spacing(0.4), })); const PRICE = 10; const OPTIONS = [1, 2, 3]; const ENVIRONMENT_TYPES = [ 'development', 'testing', 'pre-production', 'production', ]; export const OrderEnvironmentsDialog: FC = ({ open, onClose, onSubmit, errors, }) => { const { trackEvent } = usePlausibleTracker(); const [selectedOption, setSelectedOption] = useState(OPTIONS[0]); const [costCheckboxChecked, setCostCheckboxChecked] = useState(false); const [environments, setEnvironments] = useState< { name: string; type: string }[] >([{ name: '', type: ENVIRONMENT_TYPES[0] }]); const trackEnvironmentSelect = () => { trackEvent('order-environments', { props: { eventType: 'selected environment count', }, }); }; const onTypeChange = (index: number, type: string) => { setEnvironments( environments.map((env, i) => i === index ? { ...env, type } : { ...env }, ), ); }; const onNameChange = (index: number, name: string) => { setEnvironments( environments.map((env, i) => i === index ? { ...env, name } : { ...env }, ), ); }; return ( ({ environments: option, price: option * PRICE, }))} /> } footer={ } > Order additional environments With our PRO plan, you have the flexibility to expand your workspace by adding environments at ${PRICE} per user per month. Select the number of additional environments ({ key: `${option}`, label: `${option} environment${option > 1 ? 's' : ''}`, }))} onChange={(option) => { const value = Number.parseInt(option, 10); setSelectedOption(value); setEnvironments((envs) => [ ...envs, ...Array(value).fill({ name: '', type: ENVIRONMENT_TYPES[0], }), ].slice(0, value), ); trackEnvironmentSelect(); }} /> How would you like the environment {selectedOption > 1 ? 's' : ''} to be named? {[...Array(selectedOption)].map((_, i) => { const error = errors?.getFormError( `environment-${i}`, ); return ( ({ key: type, label: type, }), )} onChange={(type) => { onTypeChange(i, type); }} /> { onNameChange(i, e.target.value); }} error={!!error} helperText={error} /> ); })} setCostCheckboxChecked((state) => !state) } /> I understand adding environments leads to extra costs ); };